Production-oriented Docker Compose stack for blinkerbit/aird: Caddy (TLS + reverse proxy), Authelia (forward authentication and two-factor), and Aird installed with uv in a small Python image (see aird/Dockerfile).
You run docker compose up -d --build (or docker compose up --build the first time).
- The
prepareservice runs once and exits. It creates.envandauthelia/configuration.yml(fromauthelia/configuration.yml.template). - Secrets are generated with OpenSSL if missing: all Authelia keys and both Aird tokens (long, random).
- You must supply public hostnames and an ACME email either by answering prompts or by exporting them before Compose (see below).
- After
preparesucceeds, Authelia, Aird, and Caddy start as before.
The repo includes a stub .env (empty keys only) so Compose can load the project before prepare runs. After bootstrap, that file holds live secrets — do not push updates to a shared branch; rotate credentials if it was ever committed with real values.
- Public DNS A records for the Aird hostname and the Authelia hostname.
- Docker Engine and Compose v2.24+.
- Ports 80 and 443 reachable from the internet (Let’s Encrypt HTTP-01).
From the repo root, with a terminal attached (so prompts work):
docker compose up --buildAnswer the prompts for:
- Aird hostname (e.g.
aird.example.com) - Authelia hostname (e.g.
auth.example.com) - ACME email (Let’s Encrypt registration)
- Cookie domain (default suggested from the Aird hostname — use your registrable domain, e.g.
example.com)
When prepare finishes, start the stack detached if you like:
docker compose up -dIf prompts do not appear (for example with docker compose up -d on first boot), use the non-interactive method or:
docker compose run --rm -it prepare
docker compose up -d --buildExport the three required values, then bring the stack up:
bash
export AIR_HOST=aird.example.com
export AUTH_HOST=auth.example.com
export ACME_EMAIL=you@example.com
# optional: export COOKIE_DOMAIN=example.com
docker compose up -d --buildPowerShell
$env:AIR_HOST = "aird.example.com"
$env:AUTH_HOST = "auth.example.com"
$env:ACME_EMAIL = "you@example.com"
docker compose up -d --buildprepare will still generate any missing secrets and write .env and authelia/configuration.yml.
.envholds secrets after bootstrap — treat it like production key material (private fork,git update-index --skip-worktree .env, or secrets manager).authelia/configuration.ymlis gitignored — it is generated; editauthelia/configuration.yml.templateif you need to change Authelia behavior, then delete.env/configuration.ymland re-run bootstrap, or adjust manually once and keep backups.- Edit
authelia/users_database.ymlfor users. The sampleadminpassword isauthelia— change it immediately after login (password policy applies on change).
Traffic hits Caddy on ports 80 and 443. Authelia is on AUTH_HOST. Aird is on AIR_HOST behind Authelia forward auth. The Aird container is not published to the host except through Caddy.
- Authelia gates access and enforces two-factor for the app host.
- Aird may still enforce its own login, tokens, multi-user mode, or LDAP (Aird README).
- Pinned images: Caddy and Authelia use specific patch tags in
compose.yaml; Aird is pinned inaird/Dockerfile. - Compose hardening:
security_opt: no-new-privileges,cap_drop: [ALL](Caddy addsNET_BIND_SERVICEonly), read-only roots for Caddy and Aird withtmpfson/tmp; Aird setsPYTHONDONTWRITEBYTECODE=1. - Caddy: strips
Server, HSTS withincludeSubDomains,nosniff,X-Frame-Options,Referrer-Policy, and a narrowPermissions-Policythat does not block camera/microphone (Aird WebRTC / P2P). - Authelia (template):
two_factorfor the app host, strict session cookies (switch cookiesame_sitetolaxif logins misbehave), short inactivity, no remember-me, tight regulation, passkeys enabled, Argon2 tuning, standard password policy on password changes, password reset disabled until you add real SMTP. - Bootstrap: Authelia and Aird secrets are cryptographically generated when missing; no default placeholder secrets in
.env. - Optional: Restrict Aird to admins with
subject: 'group:admins'on the app rule in the template; strip the Authelia session cookie upstream per Authelia’s Caddy advanced example. - Client IPs in Aird: Aird sees the proxy unless you configure trusted forwarded headers in Aird itself.
- Primary store:
.envgenerated byprepare. - The
secrets/directory remains available for advanced layouts (gitignored).
The template uses the filesystem notifier. For production mail and password reset, configure SMTP in the template, enable password_reset, and follow Authelia notifier documentation.
- Logs:
docker compose logs -f caddy authelia aird - Upgrades:
docker compose pull && docker compose up -d --build - Backups: named volumes
authelia_data,aird_data,caddy_data