11 KiB
Dropshell Template Guide
This guide explains how to create templates for Dropshell - a system management tool for deploying and managing services on remote servers via Docker containers.
Template Structure
Every template must follow this directory structure:
template-name/
├── config/
│ ├── .template_info.env # REQUIRED: Template metadata
│ └── service.env # REQUIRED: Default service configuration
├── install.sh # REQUIRED: Installation script
├── uninstall.sh # REQUIRED: Uninstallation script
├── start.sh # OPTIONAL: Start the service
├── stop.sh # OPTIONAL: Stop the service
├── status.sh # OPTIONAL: Check service status
├── logs.sh # OPTIONAL: View service logs
├── backup.sh # OPTIONAL: Backup service data
├── restore.sh # OPTIONAL: Restore service data
├── destroy.sh # OPTIONAL: Destroy service and data
├── ssh.sh # OPTIONAL: SSH into service container
├── ports.sh # OPTIONAL: List exposed ports
└── README.txt # OPTIONAL: Template documentation
Essential Files
1. config/.template_info.env
Template metadata file that defines the template and its requirements. This file is managed by the template author and should NOT be modified by users:
# Template identifier - MUST match the directory name
TEMPLATE=template-name
# Requirements
REQUIRES_HOST_ROOT=false # Whether root access on host is needed
REQUIRES_DOCKER=true # Whether Docker is required
REQUIRES_DOCKER_ROOT=false # Whether Docker root privileges are needed
# Docker image settings
IMAGE_REGISTRY="docker.io"
IMAGE_REPO="vendor/image"
IMAGE_TAG="latest"
# Volume definitions (if needed)
DATA_VOLUME="${CONTAINER_NAME}_data"
CONFIG_VOLUME="${CONTAINER_NAME}_config"
Important: This file is replaced when the template is updated. Users should never edit this file.
2. config/service.env
Default service configuration that will be modified per installation. When a user creates a service from this template, they edit this file to customize the deployment:
# Service-specific settings
CONTAINER_NAME=service-name
IMAGE_TAG="latest"
# Server settings
SSH_USER="root"
# Service-specific variables
# (Add any configuration specific to your service)
Important: This is the file users edit to customize each service instance. Different deployments of the same template will have different service.env
files.
How Environment Variables Work
When Dropshell runs any template script (install.sh, start.sh, etc.), it:
- First loads all variables from
config/.template_info.env
- Then loads all variables from
config/service.env
(which can override template defaults) - Exports all these variables to the environment
- Executes the requested script with these variables available
This means:
- Scripts can use any variable defined in either file directly (e.g.,
$CONTAINER_NAME
,$IMAGE_TAG
) - Variables in
service.env
override those in.template_info.env
if they have the same name - Users customize deployments by editing
service.env
, never.template_info.env
3. install.sh
Installation script that sets up the service:
#!/bin/bash
source "${AGENT_PATH}/common.sh"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Check required environment variables
_check_required_env_vars "CONTAINER_NAME" "IMAGE_REGISTRY" "IMAGE_REPO" "IMAGE_TAG"
# Check Docker is available
_check_docker_installed || _die "Docker test failed"
# Pull the Docker image
docker pull "$IMAGE_REGISTRY/$IMAGE_REPO:$IMAGE_TAG" || _die "Failed to pull image"
# Stop any existing container
bash ./stop.sh || _die "Failed to stop container"
# Remove old container
_remove_container "$CONTAINER_NAME" || _die "Failed to remove container"
# Start the new container
bash ./start.sh || _die "Failed to start container"
echo "Installation of ${CONTAINER_NAME} complete"
4. uninstall.sh
Uninstallation script to remove the service:
#!/bin/bash
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME"
# Stop the container
bash ./stop.sh || _die "Failed to stop container"
# Remove the container
_remove_container "$CONTAINER_NAME" || _die "Failed to remove container"
# Optionally remove volumes (with confirmation)
# _remove_volume "$DATA_VOLUME"
echo "Uninstallation of ${CONTAINER_NAME} complete"
Optional Command Scripts
start.sh
Starts the Docker container with appropriate configuration:
#!/bin/bash
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME" "IMAGE_REGISTRY" "IMAGE_REPO" "IMAGE_TAG"
docker run -d \
--name "$CONTAINER_NAME" \
--restart unless-stopped \
-v "$DATA_VOLUME:/data" \
"$IMAGE_REGISTRY/$IMAGE_REPO:$IMAGE_TAG"
stop.sh
Stops the running container:
#!/bin/bash
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME"
docker stop "$CONTAINER_NAME" 2>/dev/null || true
status.sh
Reports the service status:
#!/bin/bash
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME"
if docker ps --format "table {{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then
echo "Running"
else
echo "Stopped"
fi
logs.sh
Shows container logs:
#!/bin/bash
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME"
docker logs "$CONTAINER_NAME" "$@"
backup.sh / restore.sh
Handle data backup and restoration for services with persistent data.
Common Functions (from common.sh)
Templates have access to these utility functions:
_check_required_env_vars VAR1 VAR2 ...
- Verify required variables are set_die "message"
- Exit with error message_check_docker_installed
- Verify Docker is available_remove_container NAME
- Safely remove a containercreate_items ITEM1 ITEM2 ...
- Create volumes or networks_remove_volume NAME
- Remove a Docker volume
Environment Variables
Templates receive these variables at runtime:
AGENT_PATH
- Path to the Dropshell agent directoryCONFIG_PATH
- Path to the service configuration directorySCRIPT_DIR
- Directory containing the template scripts- All variables from
.template_info.env
andservice.env
Validation Requirements
Templates must pass these validation checks:
- Required files exist:
config/.template_info.env
,config/service.env
,install.sh
,uninstall.sh
- Scripts are executable: All
.sh
files must have execute permissions - TEMPLATE variable matches: The
TEMPLATE
variable in.template_info.env
must match the directory name - Valid environment files: Both
.env
files must be parseable
Best Practices
- Always use
_check_required_env_vars
at the start of scripts to validate inputs - Handle errors gracefully with
|| _die "Error message"
- Use Docker volumes for persistent data that survives container recreation
- Document configuration in README.txt for users
- Support idempotency - scripts should handle being run multiple times
- Clean up properly in uninstall/destroy scripts
- Use standard naming - volumes as
${CONTAINER_NAME}_data
, configs as${CONTAINER_NAME}_config
- Test thoroughly - use
dropshell test-template <path>
to validate
Examples
Example 1: Basic Web Server (Nginx)
A minimal template for deploying an Nginx web server:
nginx-server/
├── config/
│ ├── .template_info.env
│ └── service.env
├── install.sh
├── uninstall.sh
├── start.sh
├── stop.sh
└── logs.sh
.template_info.env
:
TEMPLATE=nginx-server
REQUIRES_DOCKER=true
REQUIRES_DOCKER_ROOT=false
IMAGE_REGISTRY="docker.io"
IMAGE_REPO="nginx"
CONTENT_VOLUME="${CONTAINER_NAME}_content"
service.env
:
CONTAINER_NAME=nginx-server
IMAGE_TAG="alpine"
HTTP_PORT=8080
start.sh
:
#!/bin/bash
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME" "IMAGE_REGISTRY" "IMAGE_REPO" "IMAGE_TAG" "HTTP_PORT"
docker run -d \
--name "$CONTAINER_NAME" \
--restart unless-stopped \
-p "${HTTP_PORT}:80" \
-v "${CONTENT_VOLUME}:/usr/share/nginx/html:ro" \
"$IMAGE_REGISTRY/$IMAGE_REPO:$IMAGE_TAG"
Example 2: Stateful Application with Persistent Storage
A more complex template for a database or application requiring data persistence, configuration files, and network settings:
postgres-db/
├── config/
│ ├── .template_info.env
│ ├── service.env
│ └── postgres.conf # Additional config files
├── install.sh
├── uninstall.sh
├── start.sh
├── stop.sh
├── status.sh
├── backup.sh # Data backup
├── restore.sh # Data restoration
├── destroy.sh # Complete cleanup including volumes
├── logs.sh
└── README.txt
.template_info.env
:
TEMPLATE=postgres-db
REQUIRES_DOCKER=true
REQUIRES_DOCKER_ROOT=true # Needed for volume management
IMAGE_REGISTRY="docker.io"
IMAGE_REPO="postgres"
# Multiple volumes for different purposes
DATA_VOLUME="${CONTAINER_NAME}_data"
BACKUP_VOLUME="${CONTAINER_NAME}_backup"
CONFIG_VOLUME="${CONTAINER_NAME}_config"
service.env
:
CONTAINER_NAME=postgres-db
IMAGE_TAG="15-alpine"
DB_PORT=5432
POSTGRES_PASSWORD="changeme"
POSTGRES_USER="admin"
POSTGRES_DB="myapp"
backup.sh
:
#!/bin/bash
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME" "BACKUP_VOLUME" "POSTGRES_USER" "POSTGRES_DB"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="backup_${TIMESTAMP}.sql"
echo "Creating backup ${BACKUP_FILE}..."
docker exec "$CONTAINER_NAME" pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > "/tmp/${BACKUP_FILE}"
docker cp "/tmp/${BACKUP_FILE}" "${CONTAINER_NAME}:/${BACKUP_VOLUME}/${BACKUP_FILE}"
rm "/tmp/${BACKUP_FILE}"
echo "Backup completed: ${BACKUP_FILE}"
destroy.sh
:
#!/bin/bash
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME" "DATA_VOLUME" "BACKUP_VOLUME" "CONFIG_VOLUME"
echo "WARNING: This will destroy all data for ${CONTAINER_NAME}"
read -p "Are you sure? (yes/no): " confirm
if [ "$confirm" = "yes" ]; then
bash ./stop.sh
_remove_container "$CONTAINER_NAME"
_remove_volume "$DATA_VOLUME"
_remove_volume "$BACKUP_VOLUME"
_remove_volume "$CONFIG_VOLUME"
echo "Service and all data destroyed"
else
echo "Cancelled"
fi
Testing Templates
After creating a template, validate it:
dropshell test-template /path/to/template
This checks all requirements and reports any issues.