180 lines
6.3 KiB
YAML
180 lines
6.3 KiB
YAML
# ============================================
|
|
# Authelia — TrueNAS Compose
|
|
# ============================================
|
|
# Target: TrueNAS regular Docker / Portainer Git-backed Compose deployment.
|
|
# Source pattern:
|
|
# - TrueNAS Docker data root: /mnt/HomeStorage02/Docker/Authelia/...
|
|
# - Runtime secrets are supplied through Portainer stack environment variables.
|
|
# - The one-shot init service writes initial config/users files only when missing.
|
|
#
|
|
# Deploy:
|
|
# docker compose --env-file authelia-truenas.env -f authelia-truenas-compose.yml up -d
|
|
#
|
|
# Validate:
|
|
# docker compose --env-file authelia-truenas.env.example -f authelia-truenas-compose.yml config
|
|
#
|
|
# Notes:
|
|
# - Do not commit real JWT/session/storage secrets or password hashes.
|
|
# - Redis is used for sessions; SQLite is used for Authelia storage.
|
|
# - Initial policy protects guide.wheelz.lab for admins only.
|
|
# ============================================
|
|
|
|
services:
|
|
authelia-init:
|
|
image: alpine:3.20
|
|
container_name: authelia-init
|
|
restart: "no"
|
|
environment:
|
|
AUTHELIA_BOOTSTRAP_USER: ${AUTHELIA_BOOTSTRAP_USER:-wheelz}
|
|
AUTHELIA_BOOTSTRAP_DISPLAY_NAME: ${AUTHELIA_BOOTSTRAP_DISPLAY_NAME:-Wheelz}
|
|
AUTHELIA_BOOTSTRAP_EMAIL: ${AUTHELIA_BOOTSTRAP_EMAIL:-wheelz@example.invalid}
|
|
AUTHELIA_BOOTSTRAP_PASSWORD_HASH: ${AUTHELIA_BOOTSTRAP_PASSWORD_HASH:?set AUTHELIA_BOOTSTRAP_PASSWORD_HASH in runtime env}
|
|
volumes:
|
|
- ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/Authelia/config:/config
|
|
command:
|
|
- /bin/sh
|
|
- -ec
|
|
- |
|
|
mkdir -p /config
|
|
chmod 700 /config
|
|
|
|
if [ ! -f /config/configuration.yml ]; then
|
|
cat > /config/configuration.yml <<'EOF'
|
|
server:
|
|
address: tcp://0.0.0.0:9091/
|
|
|
|
log:
|
|
level: info
|
|
|
|
theme: dark
|
|
|
|
totp:
|
|
issuer: wheelytho.com
|
|
|
|
authentication_backend:
|
|
ldap:
|
|
implementation: custom
|
|
address: ldap://lldap:3890
|
|
timeout: 5 seconds
|
|
start_tls: false
|
|
base_dn: dc=wheelz,dc=lab
|
|
additional_users_dn: ou=people
|
|
users_filter: (&({username_attribute}={input})(objectClass=person))
|
|
additional_groups_dn: ou=groups
|
|
groups_filter: (member={dn})
|
|
group_search_mode: filter
|
|
user: uid=admin,ou=people,dc=wheelz,dc=lab
|
|
attributes:
|
|
username: uid
|
|
display_name: displayName
|
|
mail: mail
|
|
group_name: cn
|
|
|
|
access_control:
|
|
default_policy: deny
|
|
rules:
|
|
- domain: guide.wheelz.lab
|
|
policy: two_factor
|
|
subject:
|
|
- group:admins
|
|
|
|
session:
|
|
name: authelia_session
|
|
same_site: lax
|
|
redis:
|
|
host: authelia-redis
|
|
port: 6379
|
|
cookies:
|
|
- domain: wheelz.lab
|
|
authelia_url: https://auth.wheelz.lab
|
|
default_redirection_url: https://guide.wheelz.lab
|
|
|
|
storage:
|
|
local:
|
|
path: /config/db.sqlite3
|
|
|
|
notifier:
|
|
filesystem:
|
|
filename: /config/notification.txt
|
|
|
|
identity_validation:
|
|
reset_password:
|
|
jwt_lifespan: 5 minutes
|
|
jwt_algorithm: HS256
|
|
EOF
|
|
fi
|
|
|
|
if [ ! -f /config/users_database.yml ]; then
|
|
: "$${AUTHELIA_BOOTSTRAP_PASSWORD_HASH:?AUTHELIA_BOOTSTRAP_PASSWORD_HASH is required}"
|
|
cat > /config/users_database.yml <<EOF
|
|
users:
|
|
$${AUTHELIA_BOOTSTRAP_USER:-wheelz}:
|
|
disabled: false
|
|
displayname: "$${AUTHELIA_BOOTSTRAP_DISPLAY_NAME:-Wheelz}"
|
|
password: "$${AUTHELIA_BOOTSTRAP_PASSWORD_HASH}"
|
|
email: "$${AUTHELIA_BOOTSTRAP_EMAIL:-wheelz@example.invalid}"
|
|
groups:
|
|
- admins
|
|
- family
|
|
EOF
|
|
chmod 600 /config/users_database.yml
|
|
fi
|
|
|
|
authelia-redis:
|
|
image: redis:7-alpine
|
|
container_name: authelia-redis
|
|
restart: unless-stopped
|
|
command: ["redis-server", "--appendonly", "yes"]
|
|
volumes:
|
|
- ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/Authelia/redis:/data
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
|
|
|
|
lldap:
|
|
image: ${LLDAP_IMAGE:-lldap/lldap}:${LLDAP_TAG:-stable}
|
|
container_name: lldap
|
|
restart: unless-stopped
|
|
ports:
|
|
# Web UI for family/user management. LDAP stays internal to the Docker network unless explicitly published later.
|
|
- "${LLDAP_HTTP_PORT:-17170}:17170"
|
|
environment:
|
|
TZ: ${TZ:-America/Chicago}
|
|
UID: ${LLDAP_UID:-1000}
|
|
GID: ${LLDAP_GID:-1000}
|
|
LLDAP_JWT_SECRET: ${LLDAP_JWT_SECRET:?set LLDAP_JWT_SECRET in runtime env}
|
|
LLDAP_KEY_SEED: ${LLDAP_KEY_SEED:?set LLDAP_KEY_SEED in runtime env}
|
|
LLDAP_LDAP_BASE_DN: ${LLDAP_LDAP_BASE_DN:-dc=wheelz,dc=lab}
|
|
LLDAP_LDAP_USER_PASS: ${LLDAP_LDAP_USER_PASS:?set LLDAP_LDAP_USER_PASS in runtime env}
|
|
LLDAP_LDAP_USER_EMAIL: ${LLDAP_LDAP_USER_EMAIL:-wheelz@example.invalid}
|
|
volumes:
|
|
- ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/Authelia/lldap:/data
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
|
|
authelia:
|
|
image: ${AUTHELIA_IMAGE:-authelia/authelia}:${AUTHELIA_TAG:-4.39.10}
|
|
container_name: authelia
|
|
restart: unless-stopped
|
|
depends_on:
|
|
authelia-init:
|
|
condition: service_completed_successfully
|
|
authelia-redis:
|
|
condition: service_started
|
|
lldap:
|
|
condition: service_started
|
|
ports:
|
|
- "${AUTHELIA_HTTP_PORT:-9091}:9091"
|
|
environment:
|
|
TZ: ${TZ:-America/Chicago}
|
|
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET: ${AUTHELIA_JWT_SECRET:?set AUTHELIA_JWT_SECRET in runtime env}
|
|
AUTHELIA_SESSION_SECRET: ${AUTHELIA_SESSION_SECRET:?set AUTHELIA_SESSION_SECRET in runtime env}
|
|
AUTHELIA_STORAGE_ENCRYPTION_KEY: ${AUTHELIA_STORAGE_ENCRYPTION_KEY:?set AUTHELIA_STORAGE_ENCRYPTION_KEY in runtime env}
|
|
# Active Directory LDAP bind password. The live configuration.yml references this
|
|
# through Authelia's env override; do not commit the real value.
|
|
AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD: ${AD_BIND_PASSWORD:?set AD_BIND_PASSWORD in runtime env}
|
|
volumes:
|
|
- ${TRUENAS_DOCKER_ROOT:-/mnt/HomeStorage02/Docker}/Authelia/config:/config
|
|
security_opt:
|
|
- no-new-privileges:true
|