133 lines
5.3 KiB
YAML
133 lines
5.3 KiB
YAML
name: 'Deploy to Docker (Swarm or Compose)'
|
|
description: |
|
|
Robustly deploys a processed Docker Compose file either to Docker Swarm or regular Docker Compose via SSH.
|
|
Includes detailed debug output, error handling, and cleanup.
|
|
|
|
inputs:
|
|
stack_name:
|
|
description: 'Docker stack or compose project name'
|
|
required: true
|
|
ssh_host:
|
|
description: 'SSH host'
|
|
required: true
|
|
ssh_user:
|
|
description: 'SSH username'
|
|
required: true
|
|
ssh_key:
|
|
description: 'SSH private key'
|
|
required: true
|
|
deploy_file:
|
|
description: 'Path to the processed deployment file'
|
|
required: true
|
|
deploy_mode:
|
|
description: 'Deployment mode: swarm or compose'
|
|
required: false
|
|
default: 'swarm'
|
|
remote_temp_dir:
|
|
description: 'Remote temporary directory for deployment files'
|
|
required: false
|
|
default: '/tmp'
|
|
copy_build_context:
|
|
description: 'Whether to copy Docker build context (Dockerfile and related files) to remote host'
|
|
required: false
|
|
default: 'false'
|
|
build_context_path:
|
|
description: 'Local path to Docker build context (directory containing Dockerfile). Defaults to ./build-context'
|
|
required: false
|
|
default: 'build-context'
|
|
|
|
runs:
|
|
using: 'composite'
|
|
steps:
|
|
- id: deploy
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
STACK_NAME="${{ inputs.stack_name }}"
|
|
SSH_HOST="${{ inputs.ssh_host }}"
|
|
SSH_USER="${{ inputs.ssh_user }}"
|
|
DEPLOY_FILE="${{ inputs.deploy_file }}"
|
|
DEPLOY_MODE="${{ inputs.deploy_mode }}"
|
|
REMOTE_TEMP_DIR="${{ inputs.remote_temp_dir }}/$STACK_NAME"
|
|
COPY_BUILD_CONTEXT="${{ inputs.copy_build_context }}"
|
|
BUILD_CONTEXT_PATH="${{ inputs.build_context_path }}"
|
|
|
|
echo "🚀 Starting deployment of '$STACK_NAME' to host '$SSH_HOST' using mode '$DEPLOY_MODE'"
|
|
|
|
# Validate deploy_mode input
|
|
if [[ "$DEPLOY_MODE" != "swarm" && "$DEPLOY_MODE" != "compose" ]]; then
|
|
echo "❌ ERROR: Invalid deploy_mode '$DEPLOY_MODE'. Must be 'swarm' or 'compose'."
|
|
exit 1
|
|
fi
|
|
|
|
# Check if deployment file exists locally
|
|
if [ ! -f "$DEPLOY_FILE" ]; then
|
|
echo "❌ ERROR: Deployment file '$DEPLOY_FILE' does not exist."
|
|
exit 1
|
|
fi
|
|
|
|
# Create temporary SSH key file
|
|
SSH_KEY_FILE=$(mktemp)
|
|
echo "${{ inputs.ssh_key }}" > "$SSH_KEY_FILE"
|
|
chmod 600 "$SSH_KEY_FILE"
|
|
echo "🔑 DEBUG: Temporary SSH key created at '$SSH_KEY_FILE'"
|
|
|
|
# Ensure remote directory exists
|
|
echo "📁 DEBUG: Creating remote directory '$REMOTE_TEMP_DIR'"
|
|
ssh -o StrictHostKeyChecking=no -i "$SSH_KEY_FILE" \
|
|
"$SSH_USER@$SSH_HOST" \
|
|
"mkdir -p '$REMOTE_TEMP_DIR' && chmod 700 '$REMOTE_TEMP_DIR'"
|
|
|
|
# Copy deployment file to remote host
|
|
echo "📤 DEBUG: Copying deployment file '$DEPLOY_FILE' to remote host at '$REMOTE_TEMP_DIR/docker-compose.yml'"
|
|
scp -o StrictHostKeyChecking=no -i "$SSH_KEY_FILE" \
|
|
"$DEPLOY_FILE" \
|
|
"$SSH_USER@$SSH_HOST:$REMOTE_TEMP_DIR/docker-compose.yml"
|
|
|
|
# Optionally copy Docker build context
|
|
if [ "$COPY_BUILD_CONTEXT" == "true" ]; then
|
|
echo "📂 DEBUG: Copying Docker build context from '$BUILD_CONTEXT_PATH' to remote host"
|
|
scp -o StrictHostKeyChecking=no -i "$SSH_KEY_FILE" -r \
|
|
"$BUILD_CONTEXT_PATH"/* \
|
|
"$SSH_USER@$SSH_HOST:$REMOTE_TEMP_DIR/"
|
|
echo "📋 DEBUG: Listing remote build context directory '$REMOTE_TEMP_DIR'"
|
|
ssh -o StrictHostKeyChecking=no -i "$SSH_KEY_FILE" \
|
|
"$SSH_USER@$SSH_HOST" \
|
|
"ls -lha '$REMOTE_TEMP_DIR'"
|
|
fi
|
|
|
|
# Validate docker-compose file remotely before deploying
|
|
echo "🔍 DEBUG: Validating Docker Compose file remotely"
|
|
ssh -o StrictHostKeyChecking=no -i "$SSH_KEY_FILE" \
|
|
"$SSH_USER@$SSH_HOST" \
|
|
"docker compose -f '$REMOTE_TEMP_DIR/docker-compose.yml' config --quiet"
|
|
echo "✅ DEBUG: Docker Compose file validation succeeded"
|
|
|
|
# Deploy based on mode
|
|
if [ "$DEPLOY_MODE" == "swarm" ]; then
|
|
echo "🚢 DEBUG: Deploying stack '$STACK_NAME' to Docker Swarm"
|
|
ssh -o StrictHostKeyChecking=no -i "$SSH_KEY_FILE" \
|
|
"$SSH_USER@$SSH_HOST" \
|
|
"docker stack deploy -c '$REMOTE_TEMP_DIR/docker-compose.yml' '$STACK_NAME' --with-registry-auth"
|
|
echo "✅ DEBUG: Stack '$STACK_NAME' deployed successfully to Docker Swarm"
|
|
else
|
|
echo "🐳 DEBUG: Deploying project '$STACK_NAME' using Docker Compose"
|
|
ssh -o StrictHostKeyChecking=no -i "$SSH_KEY_FILE" \
|
|
"$SSH_USER@$SSH_HOST" \
|
|
"cd '$REMOTE_TEMP_DIR' && docker compose -p '$STACK_NAME' up -d --remove-orphans"
|
|
echo "✅ DEBUG: Project '$STACK_NAME' deployed successfully using Docker Compose"
|
|
fi
|
|
|
|
# Cleanup remote temporary files
|
|
echo "🧹 DEBUG: Cleaning up remote temporary directory '$REMOTE_TEMP_DIR'"
|
|
ssh -o StrictHostKeyChecking=no -i "$SSH_KEY_FILE" \
|
|
"$SSH_USER@$SSH_HOST" \
|
|
"rm -rf '$REMOTE_TEMP_DIR'"
|
|
|
|
# Cleanup local temporary SSH key file
|
|
rm -f "$SSH_KEY_FILE"
|
|
echo "🔑 DEBUG: Temporary SSH key file '$SSH_KEY_FILE' removed"
|
|
|
|
echo "🎉 Deployment of '$STACK_NAME' completed successfully!"
|