Files
worldquant-alpha-system/scripts/deploy-remote.sh
T

63 lines
2.5 KiB
Bash
Raw Normal View History

#!/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'