Docker deployment¶
The reference deployment is a single container image built from
deploy/Dockerfile via deploy/docker-compose.yml. The container holds the
Vue 3 SPA (statically served) and the FastAPI backend (4 uvicorn workers by
default). Data is a host-mounted volume at ./data.
Image¶
ghcr.io/leehom0123/argus:latest
The image is multi-stage:
- Node builds the frontend with
pnpm build. - Python installs the backend with the standard
pip install -e backend. - The frontend
dist/is copied alongside.
docker compose build builds locally; pushed images live on GHCR.
Compose file¶
# deploy/docker-compose.yml (excerpt)
services:
argus:
build:
context: ..
dockerfile: deploy/Dockerfile
image: ghcr.io/leehom0123/argus:latest
container_name: argus
restart: unless-stopped
ports: ["8000:8000"]
environment:
ARGUS_JWT_SECRET: ${ARGUS_JWT_SECRET:?required}
ARGUS_DB_URL: ${ARGUS_DB_URL:-sqlite+aiosqlite:////app/data/argus.db}
ARGUS_BASE_URL: ${ARGUS_BASE_URL:-https://argus.example.com}
ARGUS_LOG_LEVEL: ${ARGUS_LOG_LEVEL:-info}
ARGUS_ENV: ${ARGUS_ENV:-prod}
# …SMTP, retention, OAuth env vars (see deploy/.env.example)…
volumes:
- ./data:/app/data
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:8000/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
The ./data host folder holds the SQLite DB and any spill / backup
artifacts. Back this up — see Backups & retention.
Lifecycle¶
cd deploy
cp .env.example .env # edit secrets
docker compose up -d --build # build + start
docker compose ps # health check
docker compose logs -f # tail logs
docker compose exec argus alembic current # current DB revision
docker compose down # stop, keep data
docker compose down -v # ⚠ stop and DELETE data
The container's entrypoint (deploy/entrypoint.sh) runs Alembic migrations
before exec-ing uvicorn — there is no separate migration step.
Behind a reverse proxy¶
The shipped reference is deploy/nginx.snippet.conf. The key items it
captures:
- The SSE endpoint needs
proxy_buffering offand a longproxy_read_timeoutso live events are not coalesced. proxy_http_version 1.1and an emptyConnectionheader for keepalive.- Standard
X-Forwarded-*headers so the backend sees the real client.
Set ARGUS_BASE_URL=https://your.domain in .env so generated email
links and the CORS allow-list use the right host.
Scaling¶
ARGUS_WORKERS=Ncontrols uvicorn workers (read by the entrypoint). Default 4. Set to 1 for the SQLite dev loop; scale towardN_CORESwhen running on Postgres.- In-process singletons (retention sweep, SQLite backup, watchdog,
notifications dispatcher) are coordinated with fcntl advisory locks
under
ARGUS_LOCK_DIR(default/tmp) so only one worker runs each. - For PostgreSQL, see Database.
Build vs pull¶
docker compose up --build rebuilds locally — useful for development or
behind a firewall that blocks GHCR. Drop --build to pull the published
image.
See also¶
- Configuration — every env var.
- Database — SQLite vs PostgreSQL.
- Argus Agent — host-side companion daemon (in Sibyl).