Deploying
Run the server and workers with Docker, Kubernetes or systemd, size the store, and shut workers down gracefully.
A production deployment is a server (or two), Postgres, and as many workers as you need. Start with the recipe closest to what you already run.
Docker Compose
services:
sextant:
image: registry.sextant.example/sextant:2.4
command: ["server", "--config", "/etc/sextant/sextant.toml"]
ports: ["7420:7420"]
volumes: ["./sextant.toml:/etc/sextant/sextant.toml:ro"]
environment:
SEXTANT_STORE_DSN: postgres://sextant:${DB_PASSWORD}@db:5432/sextant
depends_on: [db]
worker:
image: registry.sextant.example/sextant:2.4
command: ["worker", "--queues", "default,emails"]
environment:
SEXTANT_URL: http://sextant:7420
SEXTANT_TOKEN: ${SEXTANT_TOKEN}
deploy: { replicas: 3 }
stop_grace_period: 60s
db:
image: postgres:17
environment: { POSTGRES_USER: sextant, POSTGRES_PASSWORD: "${DB_PASSWORD}", POSTGRES_DB: sextant }
volumes: ["pgdata:/var/lib/postgresql/data"]
volumes:
pgdata: {}Kubernetes
Run the server as a Deployment with two replicas and a Service, and the workers as a separate Deployment you scale on queue wait.
apiVersion: apps/v1
kind: Deployment
metadata: { name: sextant-worker }
spec:
replicas: 3
selector: { matchLabels: { app: sextant-worker } }
template:
metadata: { labels: { app: sextant-worker } }
spec:
terminationGracePeriodSeconds: 60
containers:
- name: worker
image: registry.sextant.example/sextant:2.4
args: ["worker", "--queues", "default,emails", "--concurrency", "20"]
envFrom: [{ secretRef: { name: sextant-client } }]
resources: { requests: { cpu: 250m, memory: 256Mi } }Scale on sextant_queue_wait_seconds rather than CPU: workers waiting on the network use little CPU while the queue grows.
systemd
[Unit]
Description=Sextant worker
After=network-online.target
[Service]
EnvironmentFile=/etc/sextant/client.env
ExecStart=/usr/local/bin/sextant worker --queues default
Restart=on-failure
TimeoutStopSec=60
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.targetGraceful shutdown
On SIGTERM a worker stops taking new jobs, lets running handlers finish and exits. If a handler outlives --shutdown-timeout (30 seconds by default), the worker cancels it and releases the lease, and the job goes back to queued with the attempt counted.
Set your platform’s stop grace period slightly above --shutdown-timeout, as in the examples, so that the platform does not SIGKILL first.
Sizing
- Postgres: 2 vCPU and 4 GB handle tens of thousands of jobs per hour. The jobs table is the main consumer of space; lower
retentionbefore you buy disk. - Server: 256 MB of memory per replica is typical.
- Workers:
concurrencyis per process. Total parallelism for a queue is capped by the queue’s ownconcurrency, summed over all workers.
Upgrading
Servers and workers of the same minor version are always compatible. Upgrade the server first, run sextant migrate up if the release notes ask for it, then roll the workers.