Skip to content

Compose Profiles

FreeSDN uses Docker Compose profiles to gate optional services. The core stack (Postgres, logdb, Valkey, API, worker, scheduler, pg-backup, Caddy edge) runs at every tier without any profile. Profiles add capabilities on top.

Set profiles in your env file as a comma-separated list:

Terminal window
# In .env.pro
COMPOSE_PROFILES=io-worker,monitoring

Or override from the command line for a one-off run:

Terminal window
docker compose --env-file .env.pro --profile cameras up -d go2rtc

Adds: worker-io

Queues handled: discovery, sync, metrics

This worker handles vendor API calls: device discovery, controller sync, and metrics collection. These tasks are slow (network I/O bound) and can block the default worker if they share a queue. The io-worker profile isolates them so adapter timeouts do not starve quick tasks like alert notifications and heartbeats.

When to use: Pro and Max tiers. If you manage more than ~20 devices or run scheduled discovery, enable this profile.

Terminal window
COMPOSE_PROFILES=io-worker,...
WORKER_IO_QUEUES=discovery,sync,metrics
CELERY_IO_CONCURRENCY=2 # raise to 4 on Max if you have many controllers
WORKER_IO_MEM_LIMIT=1G

Adds: flower

Port: Internal only (not published to the host in production)

Flower is the Celery task monitoring UI. It shows worker status, task history, queue depths, and allows manual task revocation. In production, Flower is internal-only - access it via a tunnel or the admin reverse proxy.

When to use: Pro and Max tiers, or whenever you want visibility into Celery.

Terminal window
COMPOSE_PROFILES=...,monitoring
FLOWER_BASIC_AUTH=admin:__CHANGE_ME__

Access Flower by proxying into the container:

Terminal window
# Flower is bridge-internal - no host port is published. Use an SSH tunnel:
ssh -L 5555:localhost:5555 user@host
# Or exec into the worker and inspect tasks directly:
docker compose --env-file .env.pro exec flower celery -A app.core.celery_app inspect active

Adds: go2rtc

go2rtc provides RTSP-to-HLS/WebRTC transcoding for the Video Surveillance module. Without this profile, camera live streams in the UI may not work (depending on the browser and stream format).

When to use: Any tier where you use the Video Surveillance module with live streaming.

Terminal window
COMPOSE_PROFILES=...,cameras

Adds: pgbouncer (for the primary DB) and pgbouncer-logdb (for TimescaleDB)

PgBouncer sits between the application containers and PostgreSQL and multiplexes many application connections onto a smaller number of actual DB connections. This prevents “too many clients” errors when Gunicorn workers, Celery workers, and scheduled tasks all hold connection pools simultaneously.

When to use: Max tier, or Pro tier once you exceed ~50 managed devices or start seeing TooManyConnectionsError in API logs.

Terminal window
COMPOSE_PROFILES=...,pooling
# After enabling, point the application at PgBouncer instead of Postgres:
DB_HOST=pgbouncer
DB_PORT=6432
LOGDB_HOST=pgbouncer-logdb
LOGDB_PORT=6432

Adds: pg-backup-offsite (rclone-based sync sidecar)

The dr profile runs an rclone process that copies the locally-encrypted GPG dumps from the pg_backups volume to your configured off-site destination (S3, Backblaze B2, Azure Blob, GCS, SFTP, WebDAV, and 60+ other providers). Off-site retention defaults to 30 days and runs independently of local 7-day retention.

When to use: Max tier. Strongly recommended for any production deployment where data loss would have business impact.

Terminal window
COMPOSE_PROFILES=...,dr
BACKUP_OFFSITE_REMOTE=backupremote # name of the remote in rclone.conf
BACKUP_OFFSITE_PATH=freesdn-backups # path/bucket on the remote

One-time setup:

Terminal window
# Generate rclone config on any machine with rclone installed:
rclone config
# Save the resulting config as ./secrets/rclone.conf in the repo

See Backups and Restore for the full backup strategy, GPG key setup, and restore procedure.


Adds: prometheus, redis-exporter, postgres-exporter, logdb-exporter

This profile starts a Prometheus instance configured to scrape the FreeSDN API’s /metrics endpoint (auth token required) and the three infrastructure exporters. The Prometheus scrape config is loaded from docker/prometheus/prometheus.yml; alert rules are loaded from docs/prometheus/alerts.yml.

When to use: Pro and Max tiers when you want integrated Prometheus metrics. For large deployments with an existing Prometheus infrastructure, scrape the /metrics endpoint directly instead.

Terminal window
COMPOSE_PROFILES=...,metrics
METRICS_AUTH_TOKEN=<openssl rand -hex 32> # required; see Configuration

See Monitoring for the key custom metrics and recommended Grafana dashboards.


Adds: edge-nginx as an alternative edge proxy

Use this instead of the default Caddy edge when your environment standardizes on nginx, or when TLS is terminated at an upstream hardware/cloud load balancer. See Networking and TLS for the detailed usage pattern.

Terminal window
# Use nginx edge, suppress Caddy
COMPOSE_PROFILES=nginx,...
# Then start with --scale edge=0 to prevent Caddy from starting
docker compose --env-file .env.pro up -d --scale edge=0
TierTypical COMPOSE_PROFILES value
Lite(empty - core services only)
Proio-worker,monitoring
Pro + camerasio-worker,monitoring,cameras
Pro + poolingio-worker,monitoring,pooling
Maxio-worker,monitoring,pooling,dr
Max + metricsio-worker,monitoring,pooling,dr,metrics
Max + camerasio-worker,monitoring,pooling,dr,cameras