# Dropshell Template Development Guide ## Overview Dropshell templates are service deployment configurations that allow users to easily install and manage Docker-based services on remote servers. Each template provides a standardized interface for service lifecycle management. ## Template Architecture ### Directory Structure ``` template-name/ ├── config/ │ └── service.env # Service configuration variables ├── install.sh # Installation script (REQUIRED) ├── uninstall.sh # Uninstallation script (REQUIRED) ├── start.sh # Start service script (REQUIRED) ├── stop.sh # Stop service script (REQUIRED) ├── status.sh # Check service status (REQUIRED) ├── logs.sh # View service logs (optional) ├── backup.sh # Backup service data (optional) ├── restore.sh # Restore service data (optional) ├── destroy.sh # Complete removal including data (optional) ├── ports.sh # Display exposed ports (optional) ├── ssh.sh # SSH into container (optional) └── _volumes.sh # Volume helper functions (optional) ``` ## Required Scripts ### 1. install.sh - Pull Docker images - Create necessary volumes/directories - Verify configuration files exist - Stop and remove existing containers (if any) - Start the service - Must source `${AGENT_PATH}/common.sh` ### 2. uninstall.sh - Stop the running container - Remove the container - Optionally clean up volumes (usually not) - Must source `${AGENT_PATH}/common.sh` ### 3. start.sh - Define Docker run command with all parameters - Use `_create_and_start_container` helper function - Verify container is running - Must source `${AGENT_PATH}/common.sh` ### 4. stop.sh - Stop the running container gracefully - Use `_stop_container` helper function - Must source `${AGENT_PATH}/common.sh` ### 5. status.sh - Check if container exists and is running - Display container status information - Return appropriate exit codes - Must source `${AGENT_PATH}/common.sh` ## Configuration (service.env) The `config/service.env` file contains service-specific variables: ```bash # Service identification CONTAINER_NAME=service-name IMAGE_REGISTRY=docker.io IMAGE_REPO=vendor/image IMAGE_TAG=latest # Volumes (if using Docker volumes) DATA_VOLUME=${CONTAINER_NAME}_data CONFIG_VOLUME=${CONTAINER_NAME}_config # Directories (if using host paths) DATA_PATH=${SERVICE_PATH}/data CONFIG_PATH=${SERVICE_PATH}/config # Service-specific settings PORT=8080 ENABLE_FEATURE=true ``` ## Common Functions (from common.sh) Available helper functions: - `_die "message"` - Print error and exit - `_check_docker_installed` - Verify Docker availability - `_check_required_env_vars "VAR1" "VAR2"` - Validate environment - `_create_and_start_container "$cmd" "$name"` - Start container - `_is_container_exists "$name"` - Check if container exists - `_is_container_running "$name"` - Check if running - `_stop_container "$name"` - Stop container - `_remove_container "$name"` - Remove container - `_create_folder "$path"` - Create directory with permissions ## Best Practices ### 1. User Permissions - Templates run as the `dropshell` user (non-root) - User is in the `docker` group - Avoid using `sudo` in scripts - Set appropriate file permissions (usually 777 for shared volumes) ### 2. Container Management - Always use `--restart unless-stopped` for reliability - Name containers consistently using `$CONTAINER_NAME` - Use official Docker images when possible - Pin specific versions rather than using `:latest` in production ### 3. Data Persistence - Use Docker volumes or host directories for persistent data - Separate config from data volumes - Document backup/restore procedures - Never delete data in uninstall.sh (only in destroy.sh) ### 4. Network Configuration - Expose ports using `-p HOST:CONTAINER` - Document all exposed ports - Consider using Docker networks for multi-container setups ### 5. Error Handling - Use `set -e` at script start (optional, common.sh handles most) - Check command success with proper error messages - Use `_die` for fatal errors - Provide meaningful feedback to users ### 6. Environment Variables Available from dropshell: - `${AGENT_PATH}` - Path to agent scripts (contains common.sh) - `${SERVICE_PATH}` - Path to service directory on server - `${CONFIG_PATH}` - Path to service config directory - All variables from service.env ## Creating a New Template ### Step 1: Create Template Structure ```bash mkdir template-name mkdir template-name/config ``` ### Step 2: Create service.env Define all configuration variables with sensible defaults. ### Step 3: Implement Required Scripts Start with the five required scripts, following the patterns from existing templates. ### Step 4: Test Locally ```bash ./test.sh # Run validation tests ./test_template.sh template-name # Integration test if dropshell installed ``` ### Step 5: Add to versions.json ```json { "template-name": "1.0.0" } ``` ### Step 6: Document Create a README.txt explaining: - What the service does - Configuration options - Default ports and paths - Any special requirements ## Template Examples ### Simple Service (watchtower) - Single container - Minimal configuration - No exposed ports - Docker socket access ### Web Service (caddy) - HTTP/HTTPS ports - Config files and static content - Multiple volumes - SSL certificate handling ### Complex Service (gitea-runner) - Multiple configuration files - Docker-in-Docker capability - Registration process - Cleanup procedures ## Testing Checklist - [ ] All required scripts present and executable - [ ] service.env contains necessary variables - [ ] Scripts source common.sh correctly - [ ] Container starts and stops properly - [ ] Status script returns correct information - [ ] Uninstall removes container but preserves data - [ ] Install is idempotent (can run multiple times) - [ ] No hardcoded paths (use environment variables) - [ ] Error messages are clear and helpful - [ ] Works without root/sudo access ## Version Management Follow semantic versioning: - **MAJOR**: Breaking changes to configuration or behavior - **MINOR**: New features, backwards compatible - **PATCH**: Bug fixes, backwards compatible Update version with: ```bash ./bump-version.sh template-name patch|minor|major ``` ## Publishing Templates are automatically published when pushed to main branch: 1. CI runs tests 2. Detects changed templates 3. Publishes to templates.dropshell.app 4. Tags with version numbers Manual publishing: ```bash export SOS_WRITE_TOKEN=your-token ./publish.sh template-name ```