200 lines
4.6 KiB
Markdown
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.
|