diff --git a/scripts/deploy-remote.sh b/scripts/deploy-remote.sh index 009c0a4..21db159 100755 --- a/scripts/deploy-remote.sh +++ b/scripts/deploy-remote.sh @@ -25,13 +25,15 @@ else environment_name=production fi -sudo install -d -m 0755 "$directory" -if [ ! -f "$directory/release.env" ]; then - printf 'IMAGE_TAG=%s\nHOST_PORT=%s\n' "$sha" "$host_port" | sudo tee "$directory/release.env" >/dev/null -fi -if ! grep -q '^HOST_PORT=' "$directory/release.env"; then - echo "HOST_PORT=$host_port" | sudo tee -a "$directory/release.env" >/dev/null +# The deploy user only has passwordless sudo for tee and docker. +if [ ! -d "$directory" ]; then + echo "$directory does not exist; create it once on the host" >&2 + exit 1 fi +previous_tag=$(sed -n 's/^IMAGE_TAG=//p' "$directory/release.env" 2>/dev/null | head -n 1 || true) +write_release() { + printf 'IMAGE_TAG=%s\nHOST_PORT=%s\n' "$1" "$host_port" | sudo tee "$directory/release.env" >/dev/null +} sudo tee "$compose" >/dev/null <&2 - sudo sed -i "s/^IMAGE_TAG=.*/IMAGE_TAG=$previous_tag/" "$directory/release.env" + write_release "$previous_tag" sudo docker compose --env-file "$directory/release.env" -f "$compose" up -d fi } trap rollback ERR -port=$(sed -n 's/^HOST_PORT=//p' "$directory/release.env" | head -n 1) +port=$host_port if [ "${FORCE_DEPLOY:-}" != 1 ] && curl --fail --silent --show-error "http://127.0.0.1:${port}/api/health" > /tmp/esports-health.json; then python3 - <<'PY' import json @@ -107,20 +108,20 @@ backup_dir=/var/backups/esports backup_stamp=$(date -u +%Y%m%dT%H%M%SZ) backup_name="${environment_name}-${backup_stamp}-${sha}.dump" sudo docker pull "$backup_image" -sudo install -d -m 0700 "$backup_dir" +# The container runs as root, so it creates the directory and sets the modes. sudo docker run --rm --network backend --env-file "$environment" \ - --mount "type=bind,source=$backup_dir,target=/backups" \ - --env "BACKUP_FILE=$backup_name" "$backup_image" \ - sh -eu -c 'pg_dump --format=custom --no-owner --no-acl --file="/backups/$BACKUP_FILE" "${DB_URL:-$DATABASE_URL}"' -sudo docker run --rm --mount "type=bind,source=$backup_dir,target=/backups" \ - "$backup_image" pg_restore --list "/backups/$backup_name" >/dev/null -sudo chmod 0600 "$backup_dir/$backup_name" + --mount "type=bind,source=$(dirname "$backup_dir"),target=/backups" \ + --env "BACKUP_FILE=$(basename "$backup_dir")/$backup_name" "$backup_image" \ + sh -eu -c 'mkdir -p -m 0700 "/backups/${BACKUP_FILE%/*}" + pg_dump --format=custom --no-owner --no-acl --file="/backups/$BACKUP_FILE" "${DB_URL:-$DATABASE_URL}" + chmod 0600 "/backups/$BACKUP_FILE" + pg_restore --list "/backups/$BACKUP_FILE" >/dev/null' echo "Verified $environment_name database backup at $backup_dir/$backup_name" sudo docker run --rm --network backend --env-file "$environment" "$image" \ bun scripts/migrate.ts -sudo sed -i "s/^IMAGE_TAG=.*/IMAGE_TAG=$sha/" "$directory/release.env" +write_release "$sha" switched=1 sudo docker compose --env-file "$directory/release.env" -f "$compose" up -d curl --retry 12 --retry-delay 2 --retry-all-errors --fail --silent --show-error \