Skip to content

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_USER does 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 TestBootstrap in the test suite).

Panel mode

ARGOS_PANEL_MODE

  • Type: lan or behind_caddy.
  • Default: lan.
  • Effect: see Installation for the full matrix. Short version:
    • lan: port 8080 published, cookies not Secure, HSTS not sent, middleware.RealIP NOT installed (X-Real-IP ignored to prevent spoof).
    • behind_caddy: port 8080 internal only, cookies Secure, 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 with mode=ro and query_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 in docs/architecture/storage.md).
  • 0 is 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 .env and run make 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.db via the argos_data volume).

ARGOS_CADDY_ADMIN

  • Type: URL.
  • Default: http://localhost:2019 (inside the container; the compose file sets it to http://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_access source rows.

ARGOS_CADDY_ERRORS_LOG

  • Type: path.
  • Default: /var/log/caddy/errors.log.
  • Purpose: caddy_error source rows.

ARGOS_CADDY_WAF_AUDIT_LOG

  • Type: path.
  • Default: /var/log/caddy/waf-audit.log.
  • Purpose: waf_audit source 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; 256m before). 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/alerts every ~48 s adds about 35 MB of transient RSS.
  • memory-swap is 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_url setting, which itself defaults to Caddy's built-in Let's Encrypt production).
  • Purpose: hard override of the ACME directory every tls_mode=auto host 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

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 debug temporarily 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-edge prints.
  • 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 on tls_challenge=http / tls-alpn never call Cloudflare, and tls_mode=none hosts skip ACME entirely.
  • Scope the token at Cloudflare to Zone:DNS:Edit on the zone you are managing. Do NOT reuse a Zone:DNS:Write or global API key.
  • Caddy's cloudflare-dns module 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=dns while the token is empty returns a clear 4xx so the misconfiguration surfaces before issuance loops.
  • Empty / unset is fine — docker compose up no 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_entries
  • session.absolute_timeout_hours, session.idle_timeout_hours
  • backup.schedule, backup.retention_days, backup.enabled
  • acme.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.mode
  • notifications.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>