Deployment Guide
Deployment Guide
README.md is the primary deployment document for this project.
Source of Truth
Use the deployment section in ../README.md first.
Primary topics now live there:
- production release flow
.vps.configsetup- SSH key/password login notes
- reverse proxy localhost bindings
deploy/Caddyfile.example
Deployment Files
release.sh- build locally, push to GHCR, deploy to VPS over SSHbuild.sh- local production image build/push helperdocker-compose.prod.yml- production stack behind external reverse proxy.vps.config.example- local deploy config template.env.production.example- VPS runtime env templatedeploy/Caddyfile.example- example Caddy config forapp.iot.farmvion.com
Production Model
- Build on local machine with Docker buildx for
linux/amd64 - Push images to GHCR
- Deploy to Ubuntu x64 VPS over SSH with
release.sh - Do not build the app on the VPS
- Use an external reverse proxy in front of the app
Default localhost bindings:
- backend:
127.0.0.1:3000 - frontend:
127.0.0.1:5173
Quick Release
cp .env.production.example .env.production # Fill in values
cp .vps.config.example .vps.config # Fill in values
./release.sh
That’s it. release.sh handles everything: build, push, deploy, migrate, and verify.
Remote Requirements
- Docker + Docker Compose plugin installed on the VPS
- VPS can pull GHCR images
- For password SSH deploys: local
sshpassinstalled and VPS SSH allows password login
Release Sequence
- Build
linux/amd64images locally - Push images to GHCR
- Upload
docker-compose.prod.ymland.env.productionto the VPS - Validate compose config and required env keys on remote
- Pull backend and frontend images on remote
- Start infra services (postgres, redis, emqx, minio, portainer)
- Wait for postgres to be healthy (not just running)
- Run backend migrations
- Start backend and frontend
- Verify containers are running and healthy
Notes
- Frontend
VITE_*values are build-time values. Set them before running./release.sh. - Database SSL is off by default for the current VPS compose flow. Set
DATABASE_SSL=trueonly when your database requires TLS. REMOTE_DOCKER_LOGIN=1enables GHCR login on remote if the VPS cannot pull images directly.- Postgres health check waits for
healthystatus before running migrations, ensuring the database is fully ready. - Container health verification confirms backend and frontend are healthy after deployment.
- Keep
README.mdupdated first. This file is only a trimmed deployment reference.