Environment variables¶
Everything argos reads from the process environment. Values not in this list are NOT consumed by argos — runtime settings live in the settings table and edit through the panel.
The source of truth is backend/internal/config/config.go. This page mirrors it at the commit that shipped each release; if you suspect drift, check the code.
Mandatory secrets¶
Argos refuses to boot without these.
ARGOS_SESSION_SECRET¶
- Type: string, 32+ bytes recommended.
- Purpose: seed for session tokens.
- How to generate:
openssl rand -hex 32. - Rotation: changing it invalidates every existing session on the next restart. All users have to re-log-in.
ARGOS_MASTER_KEY¶
- Type: exactly 32 bytes, hex-encoded (64 hex chars).
- Purpose: AES-GCM key for at-rest encryption of OIDC client_secret, SMTP password, Telegram bot token, VAPID private key, TOTP secrets, recovery codes.
- How to generate:
openssl rand -hex 32. - Rotation: non-trivial. Changing the key makes every encrypted secret unrecoverable. Keep it safe in a password manager and back it up alongside the panel backups (in a separate vault so a single leak does not lose both).
Initial admin bootstrap¶
Runs exactly once on first boot; subsequent starts are no-ops.
ARGOS_INITIAL_ADMIN_USER¶
- Type: string.
- Default:
admin. - Behaviour: if the user does not exist, create it. If it exists, skip. Idempotent.
ARGOS_INITIAL_ADMIN_PASSWORD¶
- Type: string, 8+ chars (bcrypt minimum).
- Required if
ARGOS_INITIAL_ADMIN_USERdoes not already exist — otherwise the boot fails with a clear error. - Not required after first boot. Argos does NOT rotate an existing admin's password when this var changes on restart (pinned by
TestBootstrapin the test suite).
Panel mode¶
ARGOS_PANEL_MODE¶
- Type:
lanorbehind_caddy. - Default:
lan. - Effect: see Installation for the full matrix. Short version:
lan: port 8080 published, cookies notSecure, HSTS not sent,middleware.RealIPNOT installed (X-Real-IP ignored to prevent spoof).behind_caddy: port 8080 internal only, cookiesSecure, HSTS + CSP sent, X-Real-IP trusted from Caddy.
ARGOS_PANEL_DOMAIN¶
- Type: string (DNS name).
- Required when
ARGOS_PANEL_MODE=behind_caddy. - Used for: bootstrap host row on first boot (so Caddy starts serving the panel immediately), ForwardAuth redirect target.
Read pool¶
ARGOS_READ_POOL¶
- Default
1. The panel opens a second SQLite handle withmode=roandquery_only(2 connections) and routes GET handlers, the dashboard loaders and the read side of the notification repo, backup manager, country jobs, AppSec status and timeout cache through it. WAL lets those reads run while the writer holds a purge batch or a checkpoint fsync (v1.3.41.0; the table of what stays on the writer is indocs/architecture/storage.md). 0is the kill-switch: the read handle is not opened and every read falls back to the writer connection (v1.3.40.4 behaviour). Set it in.envand runmake deploy-prod; no image rollback. The boot log says which mode is active (read pool enabled/read pool disabled by ARGOS_READ_POOL=0).
Listen + paths¶
ARGOS_LISTEN¶
- Type: host:port.
- Default:
:8080. - Change only when running argos outside Docker Compose.
ARGOS_DB_PATH¶
- Type: filesystem path.
- Default:
./argos.db(inside the container, mapped to/data/argos.dbvia theargos_datavolume).
ARGOS_CADDY_ADMIN¶
- Type: URL.
- Default:
http://localhost:2019(inside the container; the compose file sets it tohttp://caddy:2019). - Purpose: Caddy admin API endpoint for config pushes.
ARGOS_CADDY_TLS_DIAL¶
- Type: host:port.
- Default:
caddy:443. - Purpose: address argos uses when probing Caddy for cert state.
ARGOS_CADDY_ACCESS_LOG¶
- Type: filesystem path.
- Default:
/var/log/caddy/access.log. - Purpose: file the log ingestor tails for
caddy_accesssource rows.
ARGOS_CADDY_ERRORS_LOG¶
- Type: path.
- Default:
/var/log/caddy/errors.log. - Purpose:
caddy_errorsource rows.
ARGOS_CADDY_WAF_AUDIT_LOG¶
- Type: path.
- Default:
/var/log/caddy/waf-audit.log. - Purpose:
waf_auditsource rows.
ARGOS_CRS_RULES_DIR¶
- Type: directory path.
- Default:
/etc/coraza/crs/rules. - Purpose: where argos reads the CRS rule list for the panel's rule browser + exclusions UI.
Container resource limits (compose)¶
Read by docker-compose.yml, not by the panel binary. They apply when the container is (re)created; docker update --memory <m> --memory-swap <2m> <container> changes the running cgroup without a restart, and the .env value is what the next recreate applies.
CROWDSEC_MEM_LIMIT¶
- Default:
384m(v1.3.39.1;256mbefore). CrowdSec with the community blocklist, AppSec and the panel's alert reads sat at 190-231 MB on the reference prod (90 % of the old cap at peak). The panel container that reads/v1/alertsevery ~48 s adds about 35 MB of transient RSS. memory-swapis twice the limit in the compose file.
CROWDSEC_CPU_LIMIT¶
- Default:
0.5.
CADDY_MEM_LIMIT, CADDY_CPU_LIMIT¶
- Default:
256m,0.5.
ACME¶
ARGOS_ACME_CA_URL¶
- Type: URL (https) or empty.
- Default: empty (falls back to the
acme.ca_urlsetting, which itself defaults to Caddy's built-in Let's Encrypt production). - Purpose: hard override of the ACME directory every
tls_mode=autohost asks Caddy to issue against. Survives DB restores and Caddy restarts — set it when you need a guaranteed CA regardless of what the panel or a backup says. - Precedence:
ARGOS_ACME_CA_URL > host.tls_acme_ca_url > acme.ca_url setting > "". - Common values:
- production:
https://acme-v02.api.letsencrypt.org/directory - staging:
https://acme-staging-v02.api.letsencrypt.org/directory
- production:
When set, it is emitted into the generated Caddy config as the ca field of every ACME issuer on the next reconcile. Unset it (delete the line + docker compose up -d) to return to the DB-driven setting.
See Reverse proxy → ACME CA options and Tuning → ACME CA for development.
Logging¶
ARGOS_LOG_LEVEL¶
- Type:
debug/info/warn/error. - Default:
info. - Use: set to
debugtemporarily when diagnosing an issue. Chatty; don't leave it on.
CrowdSec bouncer (read by Caddy, NOT by argos)¶
These live in .env because docker-compose.yml forwards them to the caddy container, not to argos. They are listed here for completeness.
CROWDSEC_BOUNCER_API_KEY¶
- Paste the key
cscli bouncers add caddy-edgeprints. - Caddy's bouncer plugin reads this at startup. Changing requires a Caddy restart (
docker compose restart caddy).
CLOUDFLARE_API_TOKEN¶
- Required when any host uses
tls_challenge=dns(the default). Optional otherwise: hosts ontls_challenge=http/tls-alpnnever call Cloudflare, andtls_mode=nonehosts skip ACME entirely. - Scope the token at Cloudflare to
Zone:DNS:Editon the zone you are managing. Do NOT reuse a Zone:DNS:Write or global API key. - Caddy's
cloudflare-dnsmodule reads it at ACME-challenge time; argos itself does not call Cloudflare. - The panel validates at host-create time: saving a host with
tls_challenge=dnswhile the token is empty returns a clear 4xx so the misconfiguration surfaces before issuance loops. - Empty / unset is fine —
docker compose upno longer hard-fails on a missing value (fixed in the 1.0.0 post-release cycle).
What is NOT in env¶
Runtime knobs live in the settings table and are editable from the panel UI:
logs.retention_days,logs.max_entriessession.absolute_timeout_hours,session.idle_timeout_hoursbackup.schedule,backup.retention_days,backup.enabledacme.ca_url(see ARGOS_ACME_CA_URL for the env-level override)oidc.*(issuer, client_id, client_secret_encrypted, scopes, cookie_parent_domain, auto_provision, allowed_emails, allowed_domains, require_email_verified)crowdsec.*(enabled, lapi_url, poll_interval_seconds, bouncer_api_key, machine_user, machine_password)appsec.modenotifications.vapid_*
Full catalog: Database schema.
Suggested .env template¶
# Mandatory
ARGOS_SESSION_SECRET=<openssl rand -hex 32>
ARGOS_MASTER_KEY=<openssl rand -hex 32>
ARGOS_INITIAL_ADMIN_PASSWORD=<strong password>
# Panel mode
ARGOS_PANEL_MODE=lan
# ARGOS_PANEL_MODE=behind_caddy
# ARGOS_PANEL_DOMAIN=panel.example.com
# Optional but common
ARGOS_INITIAL_ADMIN_USER=admin
ARGOS_LOG_LEVEL=info
# If using CrowdSec:
# CROWDSEC_BOUNCER_API_KEY=<from cscli bouncers add>
# If using DNS-01 ACME with Cloudflare (wildcard certs, typically):
# CLOUDFLARE_API_TOKEN=<Zone:DNS:Edit scoped>
Related¶
- Installation — first-run.
- Upgrading — changes + env.