2.6 KiB
Deploying Deadhead
The production stack runs on one machine with Docker Compose: Postgres, the API
server and Caddy. Caddy serves the web app, proxies /api to the server and
gets HTTPS certificates for the domain automatically.
Before the first start
- DNS: point an
Arecord fordeadhead.belowland.comat the public IP of the network the server is on. - Router: forward TCP ports 80 and 443 (and UDP 443 for HTTP/3) to the server. Let's Encrypt checks port 80 before it issues a certificate.
- Docker: Docker Engine with the Compose plugin (
docker compose version). - Settings: in this folder,
cp .env.example .envand fill inPOSTGRES_PASSWORDandBETTER_AUTH_SECRET(the comments say how to make them). Keep.envprivate; it is ignored by git.
Start and update
From this folder, on the server:
git pull
APP_BUILD=$(git rev-parse --short HEAD) docker compose up -d --build
The server applies database migrations on every start, then begins serving.
docker compose ps shows each service's health; docker compose logs -f server
follows the API log. The About screen in Settings shows the build you deployed.
On a LAN only (no domain)
Set SITE_ADDRESS=:80 and PUBLIC_URL=http://<server-ip> in .env. Caddy
then serves plain HTTP. Installing the app to a phone home screen needs HTTPS,
so this is for testing.
Check a build before deploying
deploy/check.sh
This builds and starts the whole stack under a separate project name with throwaway secrets, on port 8088. It checks the API, the app, caching, a guest sign-up with a tutorial run, and a backup restored into a fresh database. Then it removes everything. It never touches the real stack.
Backups
The backup service writes a compressed dump of the database every night at
BACKUP_HOUR:00 (TZ, default UTC) to BACKUP_DIR, and deletes dumps older
than BACKUP_KEEP_DAYS. Point BACKUP_DIR at a folder that lives on another
disk, such as a NAS share mounted on the server (for example through
/etc/fstab). Make sure the share is mounted before Docker starts, or the
dumps land on the server's own disk.
Take a backup now:
docker compose exec backup /scripts/backup.sh
Test a restore without touching the live data. This loads the newest dump into
a separate deadhead_restore database:
docker compose exec backup /scripts/restore.sh
Recover the live database from a dump (stop the server first so nothing writes while it loads):
docker compose stop server
docker compose exec backup /scripts/restore.sh /backups/deadhead-<stamp>.dump deadhead
docker compose start server