Files
bmp-website-2026/docs/vps-deployment.md
2026-07-13 12:33:09 +02:00

200 lines
4.6 KiB
Markdown

# VPS deployment
The live VPS deployment runs this Payload/Next app with Docker Compose and Caddy.
Current default target:
```text
https://srv1.bayerischer-mittelstandspreis.de
```
The app is intentionally split into committed code and uncommitted runtime state.
## Server Layout
```text
/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:
```text
deploy/vps/docker-compose.yml
```
It starts:
- `bmp_website`: the Next/Payload app
- `bmp_caddy`: Caddy reverse proxy on ports `80` and `443`
Caddy reuses the certificate volumes from the former n8n deployment:
```text
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`
- `.dockerignore`
- `deploy/vps/docker-compose.yml`
- deployment scripts
Do not commit:
- `.env`
- `content.db`
- `public/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:
```bash
pnpm deploy:vps
```
The deploy script:
1. refuses to deploy a dirty worktree
2. rsyncs code to `/var/www/bmp-website/current`
3. excludes runtime state, dependency caches, generated files, and local agent tooling
4. writes the deployed Git revision to `.deploy-revision`
5. builds the Docker image on the VPS
6. recreates only the `bmp_website` app container
7. verifies `/` and `/admin`, retrying transient startup failures for up to 60 seconds
The required workflow is:
```text
commit locally -> deploy that commit -> verify production
```
## Configuration
The scripts default to the current VPS:
```bash
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:
```bash
APP_DOMAIN=www.example.com pnpm deploy:vps
```
If the Caddy container also needs to be recreated:
```bash
DEPLOY_CADDY=1 pnpm deploy:vps
```
The post-deploy verification tolerates brief `502` responses while Next/Payload
starts. Its retry behavior can be adjusted when needed:
```bash
VERIFY_RETRIES=30
VERIFY_RETRY_DELAY_SECONDS=2
VERIFY_RETRY_MAX_SECONDS=60
VERIFY_REQUEST_TIMEOUT_SECONDS=20
```
Set `SKIP_VERIFY=1` only when verification is being performed separately.
## 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
```bash
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:
```bash
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:
```bash
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.