fix: deploy with only sudo tee and docker
Some checks failed
Test and deploy staging / staging (push) Failing after 16s
Some checks failed
Test and deploy staging / staging (push) Failing after 16s
The deploy user has passwordless sudo for tee and docker only, so the script stopped at its first sudo install. release.env is rewritten with tee, and the backup container creates the backup directory and sets the file modes itself. HOST_PORT comes from the target, not release.env. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,13 +25,15 @@ else
|
|||||||
environment_name=production
|
environment_name=production
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sudo install -d -m 0755 "$directory"
|
# The deploy user only has passwordless sudo for tee and docker.
|
||||||
if [ ! -f "$directory/release.env" ]; then
|
if [ ! -d "$directory" ]; then
|
||||||
printf 'IMAGE_TAG=%s\nHOST_PORT=%s\n' "$sha" "$host_port" | sudo tee "$directory/release.env" >/dev/null
|
echo "$directory does not exist; create it once on the host" >&2
|
||||||
fi
|
exit 1
|
||||||
if ! grep -q '^HOST_PORT=' "$directory/release.env"; then
|
|
||||||
echo "HOST_PORT=$host_port" | sudo tee -a "$directory/release.env" >/dev/null
|
|
||||||
fi
|
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 <<EOF
|
sudo tee "$compose" >/dev/null <<EOF
|
||||||
services:
|
services:
|
||||||
@@ -59,18 +61,17 @@ networks:
|
|||||||
external: true
|
external: true
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
previous_tag=$(sed -n 's/^IMAGE_TAG=//p' "$directory/release.env" | head -n 1)
|
|
||||||
switched=0
|
switched=0
|
||||||
rollback() {
|
rollback() {
|
||||||
if [ "$switched" -eq 1 ] && [ -n "$previous_tag" ]; then
|
if [ "$switched" -eq 1 ] && [ -n "$previous_tag" ]; then
|
||||||
echo "Health check failed; restoring prior image tag $previous_tag" >&2
|
echo "Health check failed; restoring prior image tag $previous_tag" >&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
|
sudo docker compose --env-file "$directory/release.env" -f "$compose" up -d
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
trap rollback ERR
|
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
|
if [ "${FORCE_DEPLOY:-}" != 1 ] && curl --fail --silent --show-error "http://127.0.0.1:${port}/api/health" > /tmp/esports-health.json; then
|
||||||
python3 - <<'PY'
|
python3 - <<'PY'
|
||||||
import json
|
import json
|
||||||
@@ -107,20 +108,20 @@ backup_dir=/var/backups/esports
|
|||||||
backup_stamp=$(date -u +%Y%m%dT%H%M%SZ)
|
backup_stamp=$(date -u +%Y%m%dT%H%M%SZ)
|
||||||
backup_name="${environment_name}-${backup_stamp}-${sha}.dump"
|
backup_name="${environment_name}-${backup_stamp}-${sha}.dump"
|
||||||
sudo docker pull "$backup_image"
|
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" \
|
sudo docker run --rm --network backend --env-file "$environment" \
|
||||||
--mount "type=bind,source=$backup_dir,target=/backups" \
|
--mount "type=bind,source=$(dirname "$backup_dir"),target=/backups" \
|
||||||
--env "BACKUP_FILE=$backup_name" "$backup_image" \
|
--env "BACKUP_FILE=$(basename "$backup_dir")/$backup_name" "$backup_image" \
|
||||||
sh -eu -c 'pg_dump --format=custom --no-owner --no-acl --file="/backups/$BACKUP_FILE" "${DB_URL:-$DATABASE_URL}"'
|
sh -eu -c 'mkdir -p -m 0700 "/backups/${BACKUP_FILE%/*}"
|
||||||
sudo docker run --rm --mount "type=bind,source=$backup_dir,target=/backups" \
|
pg_dump --format=custom --no-owner --no-acl --file="/backups/$BACKUP_FILE" "${DB_URL:-$DATABASE_URL}"
|
||||||
"$backup_image" pg_restore --list "/backups/$backup_name" >/dev/null
|
chmod 0600 "/backups/$BACKUP_FILE"
|
||||||
sudo chmod 0600 "$backup_dir/$backup_name"
|
pg_restore --list "/backups/$BACKUP_FILE" >/dev/null'
|
||||||
echo "Verified $environment_name database backup at $backup_dir/$backup_name"
|
echo "Verified $environment_name database backup at $backup_dir/$backup_name"
|
||||||
|
|
||||||
sudo docker run --rm --network backend --env-file "$environment" "$image" \
|
sudo docker run --rm --network backend --env-file "$environment" "$image" \
|
||||||
bun scripts/migrate.ts
|
bun scripts/migrate.ts
|
||||||
|
|
||||||
sudo sed -i "s/^IMAGE_TAG=.*/IMAGE_TAG=$sha/" "$directory/release.env"
|
write_release "$sha"
|
||||||
switched=1
|
switched=1
|
||||||
sudo docker compose --env-file "$directory/release.env" -f "$compose" up -d
|
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 \
|
curl --retry 12 --retry-delay 2 --retry-all-errors --fail --silent --show-error \
|
||||||
|
|||||||
Reference in New Issue
Block a user