Deploy with Docker Compose
The Compose file in Get started is built for a first look. Four changes make it something you can leave running.
The file
Section titled “The file”services: setup: image: ghcr.io/redfox-soft/oauth-server-ts:<version> command: ['bun', 'run', 'db:setup'] env_file: .env restart: 'no'
oauth: image: ghcr.io/redfox-soft/oauth-server-ts:<version> ports: - '127.0.0.1:3000:3000' env_file: .env depends_on: setup: condition: service_completed_successfully restart: unless-stoppedwith a .env beside it:
ISSUER=https://auth.example.comMONGODB_URI=mongodb+srv://user:password@cluster.example.mongodb.netDATABASE_NAME=OAuthWhat changed, and why
Section titled “What changed, and why”Pin the image tag. Images are published to ghcr.io/redfox-soft/oauth-server-ts on every
release, tagged with the version and with latest. latest means a docker compose pull can move
you across a release you have not read the changelog for. Name the version instead, and change it
deliberately — that is also what makes the upgrade a reviewable diff. The
published tags are listed on the
GitHub releases page and on the
container package page.
Use a database you back up. The Get started file runs mongo:8 on a local named volume, which
is convenient and has no backups. Either point MONGODB_URI at a managed instance —
MongoDB Atlas — or keep the local mongo service and treat the
volume as the production data it is:
mongo: image: mongo:8 volumes: - mongo-data:/data/db healthcheck: test: ['CMD', 'mongosh', '--quiet', '--eval', 'db.runCommand({ ping: 1 }).ok'] interval: 5s timeout: 5s retries: 12 restart: unless-stoppedwith depends_on: { mongo: { condition: service_healthy } } on the setup service, and a scheduled
mongodump against the volume. Everything a deployment cannot lose is in that database: end-user
accounts, clients, the audit trail, and the signing keys.
restart: unless-stopped on the server, restart: 'no' on setup. The setup service is a
one-shot that must exit; restarting it would loop. The server should come back after a host reboot
or a crash — remember that a Machine which cannot reach the datastore exits at boot rather than
serving, so a restart policy is how it recovers when the database comes back.
Bind the port to loopback and put a proxy in front. '127.0.0.1:3000:3000' keeps the plaintext
port off the network. TLS terminates in the proxy, and ISSUER is the public https URL —
Behind a reverse proxy has the nginx and Caddy blocks and the one
setting you must get right there.
Upgrading
Section titled “Upgrading”Change the tag and bring it up again:
docker compose pulldocker compose up -dsetup re-runs on every up, which is intended: it is idempotent, and it is what applies a new
release’s collections, indexes and seed changes. The server waits for it to complete successfully
before starting. The full checklist, including what a restart does and does not carry over, is in
Upgrading.