From 0257a9c75c3a71cf72b35a052c10ed23590d9abd Mon Sep 17 00:00:00 2001 From: j Date: Fri, 19 Dec 2025 17:56:06 +1300 Subject: [PATCH] Update TEMPLATES.md --- TEMPLATES.md | 150 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 140 insertions(+), 10 deletions(-) diff --git a/TEMPLATES.md b/TEMPLATES.md index f7c6a34..290d28f 100644 --- a/TEMPLATES.md +++ b/TEMPLATES.md @@ -307,8 +307,115 @@ _check_required_env_vars "CONTAINER_NAME" docker logs "$CONTAINER_NAME" "$@" ``` -### backup.sh / restore.sh -Handle data backup and restoration for services with persistent data. +### backup.sh + +Backs up persistent data for a service. **OPTIONAL** - if not provided, `dropshell backup` reports "nothing to backup". + +**Environment Variables Provided:** +- `BACKUP_FILE`: Full path where the backup archive (.tgz) must be created +- `TEMP_DIR`: Temporary directory for intermediate files (automatically cleaned up) + +**Requirements:** +- Must be non-interactive (no prompts) +- Must create a tar.gz archive at the exact path specified by `BACKUP_FILE` +- Should back up all persistent data (volumes, paths, files) + +**Example using datacommands_v2.sh:** +```bash +#!/bin/bash +source "${AGENT_PATH}/common.sh" +source "${AGENT_PATH}/datacommands_v2.sh" +_check_required_env_vars "CONTAINER_NAME" "DATA_VOLUME" "CONFIG_PATH" + +# Format: type:label:location +# Types: volume, path, file +backup_items \ + "volume:data:${DATA_VOLUME}" \ + "path:config:${CONFIG_PATH}" \ + "file:settings:/etc/myapp/settings.conf" +``` + +**Example manual implementation:** +```bash +#!/bin/bash +source "${AGENT_PATH}/common.sh" +_check_required_env_vars "CONTAINER_NAME" "DATA_VOLUME" "BACKUP_FILE" "TEMP_DIR" + +# Create working directory +mkdir -p "${TEMP_DIR}/backup" + +# Export data from Docker volume +docker run --rm -v "${DATA_VOLUME}":/source -v "${TEMP_DIR}/backup":/backup \ + debian tar -czf /backup/data.tgz -C /source . + +# Create final archive at BACKUP_FILE path +tar -czf "${BACKUP_FILE}" -C "${TEMP_DIR}/backup" . + +echo "Backup completed successfully" +``` + +### restore.sh + +Restores data from a backup archive. **OPTIONAL** - required only if backup.sh exists. + +**Environment Variables Provided:** +- `BACKUP_FILE`: Full path to the backup archive (.tgz) to restore from +- `TEMP_DIR`: Temporary directory for intermediate files (automatically cleaned up) + +**Requirements:** +- Must be non-interactive (no prompts) +- Must extract and restore data from the archive at `BACKUP_FILE` +- The service is freshly installed before restore.sh runs (volumes/paths may be empty) + +**Important:** When `dropshell restore` runs, it: +1. First backs up any existing data (safety measure) +2. Destroys the old service +3. Reinstalls the service fresh +4. Copies the backup file to the remote server +5. Runs restore.sh + +**Example using datacommands_v2.sh:** +```bash +#!/bin/bash +source "${AGENT_PATH}/common.sh" +source "${AGENT_PATH}/datacommands_v2.sh" +_check_required_env_vars "CONTAINER_NAME" "DATA_VOLUME" "CONFIG_PATH" + +# Must match the same items used in backup.sh +restore_items \ + "volume:data:${DATA_VOLUME}" \ + "path:config:${CONFIG_PATH}" \ + "file:settings:/etc/myapp/settings.conf" +``` + +**Example manual implementation:** +```bash +#!/bin/bash +source "${AGENT_PATH}/common.sh" +_check_required_env_vars "CONTAINER_NAME" "DATA_VOLUME" "BACKUP_FILE" "TEMP_DIR" + +# Extract backup archive +mkdir -p "${TEMP_DIR}/restore" +tar -xzf "${BACKUP_FILE}" -C "${TEMP_DIR}/restore" + +# Restore data to Docker volume +docker volume rm "${DATA_VOLUME}" 2>/dev/null || true +docker volume create "${DATA_VOLUME}" +docker run --rm -v "${DATA_VOLUME}":/target -v "${TEMP_DIR}/restore":/backup \ + debian tar -xzf /backup/data.tgz -C /target + +echo "Restore completed successfully" +``` + +### Backup/Restore Data Types + +The datacommands helper scripts support three data types: + +| Type | Description | Example | +|------|-------------|---------| +| `volume` | Docker named volume | `volume:data:myapp_data` | +| `path` | Directory on the host filesystem | `path:config:/var/lib/myapp` | +| `file` | Single file on the host filesystem | `file:settings:/etc/app.conf` | ## Common Functions (from common.sh) @@ -454,17 +561,40 @@ POSTGRES_DB="myapp" ```bash #!/bin/bash source "${AGENT_PATH}/common.sh" -_check_required_env_vars "CONTAINER_NAME" "BACKUP_VOLUME" "POSTGRES_USER" "POSTGRES_DB" +_check_required_env_vars "CONTAINER_NAME" "POSTGRES_USER" "POSTGRES_DB" "BACKUP_FILE" "TEMP_DIR" -TIMESTAMP=$(date +%Y%m%d_%H%M%S) -BACKUP_FILE="backup_${TIMESTAMP}.sql" +mkdir -p "${TEMP_DIR}/backup" -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}" +# Dump database to temp location +echo "Dumping database..." +docker exec "$CONTAINER_NAME" pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > "${TEMP_DIR}/backup/database.sql" -echo "Backup completed: ${BACKUP_FILE}" +# Create the backup archive at BACKUP_FILE path +tar -czf "${BACKUP_FILE}" -C "${TEMP_DIR}/backup" . + +echo "Backup completed successfully" +``` + +`restore.sh`: +```bash +#!/bin/bash +source "${AGENT_PATH}/common.sh" +_check_required_env_vars "CONTAINER_NAME" "POSTGRES_USER" "POSTGRES_DB" "BACKUP_FILE" "TEMP_DIR" + +mkdir -p "${TEMP_DIR}/restore" + +# Extract the backup archive +tar -xzf "${BACKUP_FILE}" -C "${TEMP_DIR}/restore" + +# Wait for postgres to be ready +echo "Waiting for database to be ready..." +sleep 5 + +# Restore database from dump +echo "Restoring database..." +docker exec -i "$CONTAINER_NAME" psql -U "$POSTGRES_USER" "$POSTGRES_DB" < "${TEMP_DIR}/restore/database.sql" + +echo "Restore completed successfully" ``` `destroy.sh`: