- Systemd service and timer for deployment orchestration - Webhook listener for Git-triggered deployments - Forgejo Actions workflow for CI/CD pipeline - Deployment scripts with rollback capability - Deploy token validation for security
34 lines
970 B
Django/Jinja
34 lines
970 B
Django/Jinja
#!/bin/bash
|
|
set -e
|
|
|
|
APP=$1 # e.g. "my-api"
|
|
VERSION=$2 # e.g. "a3f5c91" (commit SHA from app repo)
|
|
ENV=$3 # e.g. "prod" or "staging"
|
|
|
|
if [ -z "$APP" ] || [ -z "$VERSION" ] || [ -z "$ENV" ]; then
|
|
echo "Usage: $0 <app> <version> <env>"
|
|
echo "Example: $0 my-api a3f5c91 prod"
|
|
exit 1
|
|
fi
|
|
|
|
# Concurrency lock - prevent simultaneous deploys of the same app
|
|
exec 9>/var/lock/deploy-${APP}.lock
|
|
flock -n 9 || { echo "Deploy already in progress for $APP"; exit 1; }
|
|
|
|
echo "Deploying $APP @ $VERSION to $ENV"
|
|
|
|
# Build vault args only if password file exists and is non-empty
|
|
VAULT_ARGS=""
|
|
if [ -s "/opt/deploy/.vault_pass" ]; then
|
|
VAULT_ARGS="--vault-password-file /opt/deploy/.vault_pass"
|
|
fi
|
|
|
|
# Run ansible locally on the web host (which is the deployment server)
|
|
ansible-playbook \
|
|
-i "localhost," \
|
|
-c local \
|
|
"/opt/deploy/playbooks/deploy-app.yml" \
|
|
--extra-vars "app_version=$VERSION app_name=$APP env=$ENV" \
|
|
$VAULT_ARGS
|
|
|
|
echo "Done."
|