Files
dropshell/TEMPLATES.md
Your Name d03bb9541c
All checks were successful
Build-Test-Publish / build (linux/arm64) (push) Successful in 18s
Build-Test-Publish / build (linux/amd64) (push) Successful in 35s
add templates.md
2025-09-10 09:31:31 +12:00

9.6 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:

# 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"

2. config/service.env

Default service configuration that can be overridden per 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)

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 container
  • create_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 directory
  • CONFIG_PATH - Path to the service configuration directory
  • SCRIPT_DIR - Directory containing the template scripts
  • All variables from .template_info.env and service.env

Validation Requirements

Templates must pass these validation checks:

  1. Required files exist: config/.template_info.env, config/service.env, install.sh, uninstall.sh
  2. Scripts are executable: All .sh files must have execute permissions
  3. TEMPLATE variable matches: The TEMPLATE variable in .template_info.env must match the directory name
  4. Valid environment files: Both .env files must be parseable

Best Practices

  1. Always use _check_required_env_vars at the start of scripts to validate inputs
  2. Handle errors gracefully with || _die "Error message"
  3. Use Docker volumes for persistent data that survives container recreation
  4. Document configuration in README.txt for users
  5. Support idempotency - scripts should handle being run multiple times
  6. Clean up properly in uninstall/destroy scripts
  7. Use standard naming - volumes as ${CONTAINER_NAME}_data, configs as ${CONTAINER_NAME}_config
  8. 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.