4.3 KiB
VPS deployment
The live VPS deployment runs this Payload/Next app with Docker Compose and Caddy.
Current default target:
https://srv1.bayerischer-mittelstandspreis.de
The app is intentionally split into committed code and uncommitted runtime state.
Server Layout
/var/www/bmp-website/
current/ # synced application code
shared/
.env # production secrets, never committed
content.db # live SQLite database, never committed
media/ # live Payload uploads, never committed
backups/ # server-side DB backups
The Docker Compose file lives in the repo at:
deploy/vps/docker-compose.yml
It starts:
bmp_website: the Next/Payload appbmp_caddy: Caddy reverse proxy on ports80and443
Caddy reuses the certificate volumes from the former n8n deployment:
n8n-docker_caddy_data
n8n-docker_caddy_config
The old n8n containers and volumes may still exist on the server, but are stopped after the BMP deployment takes over public traffic.
What Belongs In Git
Commit:
- application code
- Payload schema/config changes
Dockerfile.dockerignoredeploy/vps/docker-compose.yml- deployment scripts
Do not commit:
.envcontent.dbpublic/media/- production backups
- any secrets
Deploying Code
Normal deploys should be code-only. The live production database and uploads on the VPS are authoritative and must not be overwritten by routine deploys.
From a clean, committed worktree:
pnpm deploy:vps
The deploy script:
- refuses to deploy a dirty worktree by default
- rsyncs code to
/var/www/bmp-website/current - excludes
.env,content.db,public/media,.next, andnode_modules - writes the deployed Git revision to
.deploy-revision - builds the Docker image on the VPS
- recreates only the
bmp_websiteapp container - verifies
/and/admin
If you intentionally need an ad-hoc deploy before committing:
ALLOW_DIRTY=1 pnpm deploy:vps
Use that sparingly. The preferred workflow is:
commit locally -> deploy that commit -> verify production
Configuration
The scripts default to the current VPS:
SSH_USER=syntaxbullet
VPS_HOST=srv1.bayerischer-mittelstandspreis.de
VPS_PORT=22
SSH_KEY=~/.ssh/bmp-vps-deploy
APP_ROOT=/var/www/bmp-website
APP_DOMAIN=srv1.bayerischer-mittelstandspreis.de
Override any value inline when needed:
APP_DOMAIN=www.example.com pnpm deploy:vps
If the Caddy container also needs to be recreated:
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:
RUN_MIGRATIONS=1 pnpm deploy:vps
That mode:
- syncs the committed code
- builds the new Docker image
- stops the app container
- copies
shared/content.dbtobackups/content-*-pre-migrate.db - runs
pnpm payload migratein a one-off app container - starts the app container again
To run migrations against the already deployed code/image without syncing code:
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
pnpm vps:status
This prints:
- deployed revision
- running containers
- old n8n container status
- shared DB/media sizes
- disk usage
- recent app and Caddy logs
Backing Up SQLite
Create a server-side SQLite backup before schema-sensitive deploys:
pnpm vps:backup-db
This briefly stops the app container, copies
/var/www/bmp-website/shared/content.db into /var/www/bmp-website/backups/,
then starts the app container again. Caddy remains running.
Rollback To Old n8n
The old n8n compose project was intentionally not deleted. If you need to replace the BMP site with the previous n8n service:
CONFIRM=replace-bmp-with-n8n pnpm vps:rollback:n8n
This stops the BMP Caddy/app containers and starts /root/n8n-docker.
Production State Caution
After launch, CMS edits and uploads happen on the VPS. Do not sync local
content.db or public/media/ over production unless you are intentionally
restoring or replacing production content and have a current backup.