Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the VPS/CI deployment flow to use a single Docker Compose–based deploy entrypoint for both staging (dev) and production (main), moving persistent runtime data out of the git checkout and into host directories.
Changes:
- Introduces
deploy/scripts/deploy-stack.sh+prepare-persistent-data.shto standardize deploys, backups, and one-time data migration. - Switches production/staging Compose stacks to bind-mount uploads + leaderboard from
HOST_DATA_ROOTand adds an API healthcheck. - Updates GitHub Actions deploy workflow, VPS setup script, and documentation to match the new flow.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/setup_vps.sh | Creates host data/backup roots and uses the new Docker-based deploy scripts instead of venv/systemd-based deploy. |
| docs/deployment/cicd.md | Documents the new CI/CD deploy flow, env mapping, and one-time cutover steps. |
| deploy/scripts/prepare-persistent-data.sh | One-time migration from legacy uploads volume and repo-local leaderboard into HOST_DATA_ROOT; disables legacy systemd units. |
| deploy/scripts/deploy-stack.sh | Main deploy entrypoint: git sync, backup, prepare persistent storage, compose validation, service startup, build, migrate, recreate, health checks. |
| deploy/scripts/backup-compose-data.sh | Moves backups under BACKUP_ROOT, supports host-backed uploads/leaderboard, and copies .env into backups. |
| deploy/env/.env.staging.example | Adds HOST_DATA_ROOT/BACKUP_ROOT and updates comments for host-backed data. |
| deploy/env/.env.production.example | Adds HOST_DATA_ROOT/BACKUP_ROOT and updates comments for host-backed data. |
| deploy/docker/docker-compose.staging.yml | Replaces uploads/leaderboard volumes with bind mounts from HOST_DATA_ROOT; adds API healthcheck; removes uploads volume. |
| deploy/docker/docker-compose.prod.yml | Same as staging: bind mounts + healthcheck; removes uploads volume. |
| deploy/docker/Dockerfile | Stops copying repo uploads/; ensures expected upload subdirs exist in the image. |
| README.md | Updates VPS deploy instructions and documents host-backed persistence for staging/production. |
| .gitignore | Un-ignores docs/deployment/cicd.md while keeping other /docs ignored. |
| .github/workflows/deploy.yml | Simplifies SSH deploy jobs to call deploy-stack.sh (no local checkout). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| git checkout main || git checkout -b main --track origin/main | ||
| if [ ! -f .env ]; then | ||
| cp .env.production.example .env | ||
| cp deploy/env/.env.production.example .env | ||
| BOOTSTRAP_PENDING=1 | ||
| fi | ||
| python3 -m venv .venv | ||
| . .venv/bin/activate | ||
| python -m pip install --upgrade pip | ||
| pip install -r requirements.txt | ||
| mkdir -p uploads uploads/avatars uploads/attachments logs | ||
| if [ "${BOOTSTRAP_PENDING}" -eq 0 ]; then | ||
| alembic upgrade head | ||
| fi | ||
| deactivate | ||
| mkdir -p "${PROD_DATA_ROOT}/uploads/avatars" "${PROD_DATA_ROOT}/uploads/attachments" "${PROD_DATA_ROOT}/leaderboard" |
|
|
||
| cp "${repo_root}/.env" "${target_dir}/.env" | ||
|
|
||
| find "${backup_root}" -mindepth 1 -maxdepth 1 -type d | sort | head -n -10 | xargs -r rm -rf |
| copy_volume_to_dir() { | ||
| local volume_name="$1" | ||
| local target_dir="$2" | ||
|
|
||
| docker run --rm \ | ||
| -v "${volume_name}:/source:ro" \ | ||
| -v "${target_dir}:/target" \ | ||
| alpine:3.20 \ | ||
| sh -lc 'cd /source && tar -cf - . | tar -xf - -C /target' | ||
| } |
There was a problem hiding this comment.
Pull request overview
This PR reworks the staging/production CI/CD deployment flow to use a single Docker Compose–based deploy entrypoint, moving persistent runtime data (uploads/leaderboard) and backups out of the git checkout and into host directories on the VPS.
Changes:
- Introduces
deploy/scripts/deploy-stack.shas the unified deploy entrypoint (used by GitHub Actions and VPS bootstrap). - Migrates persistence from Docker named volumes / repo-local data to host bind mounts via
HOST_DATA_ROOT, plus adds one-time migration + backup tooling. - Updates docs/README and VPS bootstrap to match the new Docker-based deploy flow.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
scripts/setup_vps.sh |
Bootstraps prod/staging checkouts + host persistence dirs; switches to Docker-based deploy script. |
docs/deployment/cicd.md |
Documents the new CI/CD + persistence + migration flow. |
deploy/scripts/prepare-persistent-data.sh |
One-time migration from legacy uploads volume and repo-local leaderboard into host storage; disables legacy systemd units. |
deploy/scripts/deploy-stack.sh |
New unified deploy orchestration (git sync, backup, migration, compose up, migrations, health checks). |
deploy/scripts/backup-compose-data.sh |
Updates backup logic to use BACKUP_ROOT and host-backed uploads/leaderboard when available; snapshots .env. |
deploy/env/.env.staging.example |
Adds HOST_DATA_ROOT / BACKUP_ROOT and clarifies persistence behavior. |
deploy/env/.env.production.example |
Adds HOST_DATA_ROOT / BACKUP_ROOT and clarifies persistence behavior. |
deploy/docker/docker-compose.staging.yml |
Switches uploads/leaderboard to host bind mounts; adds API healthcheck; removes uploads named volume. |
deploy/docker/docker-compose.prod.yml |
Switches uploads/leaderboard to host bind mounts; adds API healthcheck; removes uploads named volume. |
deploy/docker/Dockerfile |
Stops copying repo-local uploads/; ensures uploads subdirs exist in image. |
README.md |
Updates deployment instructions and references to new deploy scripts/persistence approach. |
.gitignore |
Un-ignores docs/deployment/cicd.md so the new deployment doc is committed. |
.github/workflows/deploy.yml |
Simplifies SSH deploy steps to call deploy-stack.sh (and removes local checkout step). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| "${compose_cmd[@]}" config >/dev/null | ||
| "${compose_cmd[@]}" up -d --no-recreate postgres redis | ||
| wait_for_service postgres 120 | ||
| wait_for_service redis 60 |
| if [ ! -f .env ]; then | ||
| cp .env.production.example .env | ||
| cp deploy/env/.env.production.example .env | ||
| BOOTSTRAP_PENDING=1 | ||
| fi |
| if [ ! -f .env ]; then | ||
| cp .env.staging.example .env | ||
| cp deploy/env/.env.staging.example .env | ||
| BOOTSTRAP_PENDING=1 | ||
| fi |
| backup_root="${BACKUP_ROOT%/}/${env_name}" | ||
| timestamp="$(date +%Y%m%d-%H%M%S)" | ||
| target_dir="${backup_root}/${timestamp}" | ||
| mkdir -p "${target_dir}" |
| tar_directory "${legacy_leaderboard_dir}" "${target_dir}/leaderboard.tar.gz" || true | ||
| fi | ||
|
|
||
| cp "${repo_root}/.env" "${target_dir}/.env" |
| ;; | ||
| esac | ||
|
|
||
| mkdir -p "${HOST_DATA_ROOT}" "${BACKUP_ROOT}" |
| BOOTSTRAP_PENDING=0 | ||
|
|
||
| mkdir -p "${PROD_PATH}" "${STAGING_PATH}" | ||
| mkdir -p "${PROD_PATH}" "${STAGING_PATH}" "${PROD_DATA_ROOT}" "${STAGING_DATA_ROOT}" "${BACKUP_ROOT}" |
No description provided.