99bc36439e
Deploy production / deploy (push) Failing after 8s
- Updated deployment specification to reflect the new architecture involving servers A, B, and C. - Revised README to describe the new deployment method using Gitea Runner and SSH. - Modified `compose.production.yaml` to remove build context and use image tags directly. - Enhanced deployment documentation to clarify configuration steps and environment variable requirements. - Introduced `deploy-remote.sh` script for handling remote deployment tasks over SSH. - Added unit tests for deployment scripts to ensure robustness and error handling. - Updated `deploy-production.sh` to streamline image pulling and deployment processes.
63 lines
2.5 KiB
Bash
63 lines
2.5 KiB
Bash
#!/usr/bin/env bash
|
|
# Send a release bundle and environment to server B. No application .env is written.
|
|
# Requires Bash/OpenSSH locally and Bash/tar/base64/Docker Compose on server B.
|
|
# Returns the remote deployment status; credentials never appear in SSH arguments.
|
|
set -Eeuo pipefail
|
|
umask 077
|
|
|
|
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
|
for key in PROD_HOST PROD_USER DEPLOY_PATH PROD_SSH_KEY PROD_KNOWN_HOSTS IMAGE_PREFIX DEPLOY_TAG REGISTRY_USERNAME REGISTRY_PASSWORD WQ_EMAIL WQ_PASSWORD DATABASE_URL ADMIN_PASSWORD ENCRYPTION_KEY PUBLIC_ORIGIN; do
|
|
if [[ -z "${!key:-}" ]]; then
|
|
echo "Missing required Gitea configuration: $key" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
if [[ "$DEPLOY_PATH" != /* || ! "$DEPLOY_TAG" =~ ^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$ ]]; then
|
|
echo 'DEPLOY_PATH must be absolute and DEPLOY_TAG must be a valid Docker tag.' >&2
|
|
exit 1
|
|
fi
|
|
|
|
ssh_dir=$(mktemp -d)
|
|
trap 'rm -rf -- "$ssh_dir"' EXIT
|
|
trap 'exit 130' INT
|
|
trap 'exit 143' TERM
|
|
trap 'exit 129' HUP
|
|
printf '%s\n' "$PROD_SSH_KEY" > "$ssh_dir/id"
|
|
printf '%s\n' "$PROD_KNOWN_HOSTS" > "$ssh_dir/known_hosts"
|
|
unset PROD_SSH_KEY PROD_KNOWN_HOSTS
|
|
ssh_options=(
|
|
-F /dev/null -T
|
|
-i "$ssh_dir/id"
|
|
-p "${PROD_PORT:-22}"
|
|
-l "$PROD_USER"
|
|
-o BatchMode=yes
|
|
-o IdentitiesOnly=yes
|
|
-o StrictHostKeyChecking=yes
|
|
-o "UserKnownHostsFile=$ssh_dir/known_hosts"
|
|
-o GlobalKnownHostsFile=/dev/null
|
|
-o ConnectTimeout=15
|
|
-o ServerAliveInterval=15
|
|
-o ServerAliveCountMax=4
|
|
)
|
|
|
|
# Bash %q preserves quotes, dollar signs and newlines without evaluating values.
|
|
# Only this allowlist crosses SSH; private keys and the runner's environment stay local.
|
|
{
|
|
printf 'set -Eeuo pipefail\numask 077\n'
|
|
for key in DEPLOY_PATH IMAGE_PREFIX DEPLOY_TAG REGISTRY_USERNAME REGISTRY_PASSWORD WQ_EMAIL WQ_PASSWORD DATABASE_URL ADMIN_PASSWORD ENCRYPTION_KEY PUBLIC_ORIGIN ADMIN_USERNAME MCP_ENABLED; do
|
|
printf 'export %s=%q\n' "$key" "${!key:-}"
|
|
done
|
|
cat <<'REMOTE'
|
|
mkdir -p -- "$DEPLOY_PATH/releases"
|
|
release_dir=$(mktemp -d "$DEPLOY_PATH/releases/$DEPLOY_TAG.XXXXXX")
|
|
cd "$release_dir"
|
|
base64 -d <<'WQ_RELEASE_BUNDLE' | tar -xzf -
|
|
REMOTE
|
|
# A small base64 archive lets one SSH connection carry files and shell-quoted env.
|
|
# Each attempt gets its own directory, so competing jobs cannot overwrite files.
|
|
COPYFILE_DISABLE=1 tar -czf - compose.production.yaml scripts/deploy-production.sh | base64
|
|
printf '\nWQ_RELEASE_BUNDLE\n'
|
|
# Docker must not consume the SSH script input. B does not need a Git checkout.
|
|
printf 'exec bash scripts/deploy-production.sh </dev/null\n'
|
|
} | ssh "${ssh_options[@]}" -- "$PROD_HOST" 'bash --noprofile --norc -se'
|