feat: add migration support for VPS deployment with backup functionality
This commit is contained in:
@@ -120,6 +120,34 @@ If the Caddy container also needs to be recreated:
|
|||||||
DEPLOY_CADDY=1 pnpm deploy:vps
|
DEPLOY_CADDY=1 pnpm deploy:vps
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Payload Migrations
|
||||||
|
|
||||||
|
Routine deploys do not run migrations. For schema-changing commits, create and
|
||||||
|
commit the Payload migration files, then deploy with migrations enabled:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
RUN_MIGRATIONS=1 pnpm deploy:vps
|
||||||
|
```
|
||||||
|
|
||||||
|
That mode:
|
||||||
|
|
||||||
|
1. syncs the committed code
|
||||||
|
2. builds the new Docker image
|
||||||
|
3. stops the app container
|
||||||
|
4. copies `shared/content.db` to `backups/content-*-pre-migrate.db`
|
||||||
|
5. runs `pnpm payload migrate` in a one-off app container
|
||||||
|
6. starts the app container again
|
||||||
|
|
||||||
|
To run migrations against the already deployed code/image without syncing code:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm vps:migrate
|
||||||
|
```
|
||||||
|
|
||||||
|
Run migrations only when the commit includes migration files under
|
||||||
|
`src/migrations/`. For plain frontend/content-rendering changes, use the normal
|
||||||
|
`pnpm deploy:vps` path.
|
||||||
|
|
||||||
## Status And Logs
|
## Status And Logs
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
"test:e2e": "cross-env NODE_OPTIONS=\"--no-deprecation --import=tsx/esm\" playwright test --config=playwright.config.ts",
|
"test:e2e": "cross-env NODE_OPTIONS=\"--no-deprecation --import=tsx/esm\" playwright test --config=playwright.config.ts",
|
||||||
"test:int": "cross-env NODE_OPTIONS=--no-deprecation vitest run --config ./vitest.config.mts",
|
"test:int": "cross-env NODE_OPTIONS=--no-deprecation vitest run --config ./vitest.config.mts",
|
||||||
"vps:backup-db": "bash scripts/vps-backup-db.sh",
|
"vps:backup-db": "bash scripts/vps-backup-db.sh",
|
||||||
|
"vps:migrate": "bash scripts/vps-migrate.sh",
|
||||||
"vps:rollback:n8n": "bash scripts/vps-rollback-n8n.sh",
|
"vps:rollback:n8n": "bash scripts/vps-rollback-n8n.sh",
|
||||||
"vps:status": "bash scripts/vps-status.sh"
|
"vps:status": "bash scripts/vps-status.sh"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ APP_DOMAIN="${APP_DOMAIN:-srv1.bayerischer-mittelstandspreis.de}"
|
|||||||
PUBLIC_URL="${PUBLIC_URL:-https://$APP_DOMAIN}"
|
PUBLIC_URL="${PUBLIC_URL:-https://$APP_DOMAIN}"
|
||||||
ALLOW_DIRTY="${ALLOW_DIRTY:-0}"
|
ALLOW_DIRTY="${ALLOW_DIRTY:-0}"
|
||||||
DEPLOY_CADDY="${DEPLOY_CADDY:-0}"
|
DEPLOY_CADDY="${DEPLOY_CADDY:-0}"
|
||||||
|
RUN_MIGRATIONS="${RUN_MIGRATIONS:-0}"
|
||||||
SKIP_VERIFY="${SKIP_VERIFY:-0}"
|
SKIP_VERIFY="${SKIP_VERIFY:-0}"
|
||||||
|
|
||||||
SSH_TARGET="$SSH_USER@$VPS_HOST"
|
SSH_TARGET="$SSH_USER@$VPS_HOST"
|
||||||
@@ -53,7 +54,26 @@ ssh -i "$SSH_KEY" -p "$VPS_PORT" "$SSH_TARGET" "
|
|||||||
set -e
|
set -e
|
||||||
cd '$APP_ROOT'
|
cd '$APP_ROOT'
|
||||||
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' build app
|
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' build app
|
||||||
|
if [ '$RUN_MIGRATIONS' = '1' ]; then
|
||||||
|
backup_dir='$APP_ROOT/backups'
|
||||||
|
backup_file=\"\$backup_dir/content-\$(date +%Y%m%d-%H%M%S)-pre-migrate.db\"
|
||||||
|
|
||||||
|
sudo install -d -o '$SSH_USER' -g '$SSH_USER' \"\$backup_dir\"
|
||||||
|
|
||||||
|
restart_app() {
|
||||||
|
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' up -d app >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
trap restart_app EXIT
|
||||||
|
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' stop app >/dev/null
|
||||||
|
cp -p '$APP_ROOT/shared/content.db' \"\$backup_file\"
|
||||||
|
echo \"Created pre-migration backup: \$backup_file\"
|
||||||
|
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' run --rm --no-deps app pnpm payload migrate
|
||||||
|
restart_app
|
||||||
|
trap - EXIT
|
||||||
|
else
|
||||||
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' up -d app
|
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' up -d app
|
||||||
|
fi
|
||||||
if [ '$DEPLOY_CADDY' = '1' ]; then
|
if [ '$DEPLOY_CADDY' = '1' ]; then
|
||||||
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' up -d caddy
|
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' up -d caddy
|
||||||
fi
|
fi
|
||||||
|
|||||||
36
scripts/vps-migrate.sh
Executable file
36
scripts/vps-migrate.sh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SSH_USER="${SSH_USER:-syntaxbullet}"
|
||||||
|
VPS_HOST="${VPS_HOST:-srv1.bayerischer-mittelstandspreis.de}"
|
||||||
|
VPS_PORT="${VPS_PORT:-22}"
|
||||||
|
SSH_KEY="${SSH_KEY:-$HOME/.ssh/bmp-vps-deploy}"
|
||||||
|
APP_ROOT="${APP_ROOT:-/var/www/bmp-website}"
|
||||||
|
APP_DOMAIN="${APP_DOMAIN:-srv1.bayerischer-mittelstandspreis.de}"
|
||||||
|
|
||||||
|
SSH_TARGET="$SSH_USER@$VPS_HOST"
|
||||||
|
COMPOSE_FILE="$APP_ROOT/current/deploy/vps/docker-compose.yml"
|
||||||
|
|
||||||
|
ssh -i "$SSH_KEY" -p "$VPS_PORT" "$SSH_TARGET" "
|
||||||
|
set -e
|
||||||
|
cd '$APP_ROOT'
|
||||||
|
|
||||||
|
backup_dir='$APP_ROOT/backups'
|
||||||
|
backup_file=\"\$backup_dir/content-\$(date +%Y%m%d-%H%M%S)-pre-migrate.db\"
|
||||||
|
|
||||||
|
sudo install -d -o '$SSH_USER' -g '$SSH_USER' \"\$backup_dir\"
|
||||||
|
|
||||||
|
restart_app() {
|
||||||
|
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' up -d app >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
trap restart_app EXIT
|
||||||
|
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' stop app >/dev/null
|
||||||
|
cp -p '$APP_ROOT/shared/content.db' \"\$backup_file\"
|
||||||
|
echo \"Created pre-migration backup: \$backup_file\"
|
||||||
|
APP_ROOT='$APP_ROOT' APP_DOMAIN='$APP_DOMAIN' sudo docker compose -f '$COMPOSE_FILE' run --rm --no-deps app pnpm payload migrate
|
||||||
|
restart_app
|
||||||
|
trap - EXIT
|
||||||
|
|
||||||
|
sudo docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
|
||||||
|
"
|
||||||
Reference in New Issue
Block a user