Authelia Docker Compose 部署指南

在 Ubuntu 22.04 用 Compose 从零部署 Authelia v4.39.28 + Nginx auth_request + 演示应用:密钥注入、自签 HTTPS、用户库初始化与端到端认证链路实测

AutheliaAutheliaDockerLinux2026/10/18

Authelia Docker Compose 部署指南

目标:在 Ubuntu 22.04 服务器上用 Docker Compose 从零部署一套「Authelia 统一认证 + Nginx auth_request 反代 + 演示应用」的最小可用栈,完成 HTTPS 接入、密钥注入、用户数据库初始化,并用真实回显跑通「未登录 302 跳转 → 登录拿到会话 → 带 cookie 访问 200」的完整认证链路。已在 Ubuntu 22.04 实测通过(Authelia v4.39.28)。

一、环境信息

本篇所有命令与回显均在以下环境实测采集,照抄执行即可复现:

  • 操作系统:Ubuntu 22.04(内核 5.15+,x86_64)
  • Docker:29.8.1;Docker Compose:v5.5.1(docker compose 插件形态)
  • Authelia:authelia/authelia:4.39.28(摘要 sha256:bd97cff4fcbf…d43a6f54)
  • Nginx 反向代理:nginx:1.27-alpine(摘要 sha256:65645c7bb6a0…2f2a10)
  • 演示后端:nginx:alpine(静态页,不出服务器端口)
  • 服务器端口规划:Authelia 9091、演示反代 8098(部署前已用 ss -ltn 复核空闲)
  • 工作目录:/opt/authelia/(本篇全部文件落在这里)
  • 域名家族:example.com(演示用,authelia.example.com 为登录门户、app.example.com 为受保护应用,通过 /etc/hosts 本地解析)
  • Authelia 数据目录:/opt/authelia/authelia/data/(对应容器内 /config,SQLite 数据库落在这里)

💡 说明:example.com 是保留演示域名,生产环境请换成你自己的真实域名(如 sso.yourdomain.com + app.yourdomain.com),并申请受信任的 TLS 证书。本篇为让内网环境可完整复现,采用自签证书。

二、镜像选型说明

镜像标签角色选型理由
authelia/authelia4.39.28认证服务器官方镜像;锁定具体版本号而非 latest,保证回显可复现、升级可控
nginx1.27-alpine反向代理(auth_request)1.27 为当前稳定主线,alpine 变体体积小;官方 Authelia 集成文档以 Nginx 为主要示例
nginxalpine演示后端用一个纯静态页模拟「受保护应用」,不占用服务器端口,聚焦认证链路本身

选型解读:三个角色用同一网络互通。Authelia 官方镜像的入口是 /app/entrypoint.sh,首次启动会自动修正 /config 目录属主并做存储 schema 迁移(见 4.9 日志回显),因此数据目录必须以可写方式挂载;而 certs 之类只读资源若单独以 :ro 挂进 /config 会触发 chown: Read-only file system 报错(详见十一、常见问题 Q4),本方案把证书放在数据目录内部规避该问题。

三、前置条件

3.1 复核端口空闲

ss -ltn | grep -E ':(9091|8098)\b' && echo '端口被占用' || echo '9091/8098 均空闲'

实测回显:

9091/8098 均空闲

若端口被占用,将 compose.yml 与后文命令中的端口顺延为空闲端口(如 9092/8099),全文保持一致即可。

3.2 配置演示域名解析

echo '127.0.0.1 authelia.example.com app.example.com' >> /etc/hosts
grep -E 'authelia.example|app.example' /etc/hosts

实测回显:

127.0.0.1 authelia.example.com app.example.com

生产环境把这两条解析指向反向代理所在服务器的真实地址,并替换为你自己的域名。

3.3 生成自签 TLS 证书

Authelia 4.39 强制要求 session.cookies[].authelia_url 使用 https 协议(实测使用 http 会在启动时报错并退出,见十一、Q2),因此本方案全链路 HTTPS,先生成一张覆盖 example.com 全部子域的自签证书:

mkdir -p /opt/authelia/certs
openssl req -x509 -newkey rsa:2048 -keyout /opt/authelia/certs/key.pem \
  -out /opt/authelia/certs/cert.pem -days 3650 -nodes \
  -subj "/CN=*.example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:*.example.com,DNS:localhost,IP:127.0.0.1"
ls -l /opt/authelia/certs/

实测回显:

total 16
-rw-r--r-- 1 root root 1204 Oct 18 15:12 cert.pem
-rw------- 1 root root 1704 Oct 18 15:12 key.pem

3.4 建立目录结构

mkdir -p /opt/authelia/{authelia/data/certs,nginx/conf.d,demo}
cp /opt/authelia/certs/cert.pem /opt/authelia/certs/key.pem /opt/authelia/authelia/data/certs/
find /opt/authelia -type d | sort

实测回显:

/opt/authelia
/opt/authelia/authelia
/opt/authelia/authelia/data
/opt/authelia/authelia/data/certs
/opt/authelia/certs
/opt/authelia/demo
/opt/authelia/nginx
/opt/authelia/nginx/conf.d

目录含义:authelia/data/ 是 Authelia 的数据根(挂载为容器内 /config,证书、配置、SQLite 数据库都放这里,保证 entrypoint 的 chown 正常执行);certs/ 是 Nginx 侧的证书;nginx/conf.d/ 放反代配置;demo/ 放演示应用页面。

四、部署步骤

本节按「密钥 → 哈希 → 配置文件 → 编排文件 → 启动 → 验证」的顺序完成从零部署,每一步都有实测回显。

4.1 生成系统级密钥

Authelia 需要 3 个系统级密钥,全部用 openssl 随机生成,通过环境变量注入、不落配置文件明文:

openssl rand -hex 32

实测回显(执行 3 次分别得到 JWT、会话、存储加密密钥):

274c79d96662a0980186cf1d0192b94032b7db9d7211918d8128cb126b15c737
c13249d1dd3698d2e8e485fc0798af3f0f92e8c9471197eb7f0363792193c50a
4a67ac8bc8ee1072013821918596f56479eee30d171fb0e5b9f46a2ec350d0a9

💡 说明:openssl rand -hex 32 输出 64 位十六进制字符(256 bit 熵)。三个密钥用途不同:JWT_SECRET 签发密码重置 JWT;SESSION_SECRET 对会话 cookie 做签名与加密;STORAGE_ENCRYPTION_KEY 加密存储后端中的敏感列(如 2FA 设备密钥)。三个值必须互不相同,且生产环境严禁复用本篇演示值。

4.2 生成用户密码哈希

用官方工具为演示管理员 admin(密码 q1w2e3r4)生成 argon2id 哈希:

docker run --rm authelia/authelia:4.39.28 authelia crypto hash generate argon2 --password 'q1w2e3r4'

实测回显:

Digest: $argon2id$v=19$m=65536,t=3,p=4$COvCyJXZxaXzM4RRCMyEJQ$/CtM5BKqBlXD6Txbey1wQwPiz+CwbcSYjRxh811kG10

💡 技术拓展:--password 明文只在生成瞬间使用,最终落盘的是单向哈希。Argon2id 之外官方还支持 scrypt、pbkdf2、bcrypt、sha2crypt 等:

算法参数形态适用建议
argon2idm=65536,t=3,p=4(默认)当前首选,抗 GPU 破解
scryptN,r,p 可调需要与旧系统兼容时
pbkdf2迭代次数可调有 FIPS 合规要求时
sha2crypt弱于上述三种仅存量为旧数据迁移

本方案采用默认 argon2id(官方默认参数已足够安全,无需调整)。

4.3 写入 .env 密钥文件

cat > /opt/authelia/.env <<'EOF'
JWT_SECRET=274c79d96662a0980186cf1d0192b94032b7db9d7211918d8128cb126b15c737
SESSION_SECRET=c13249d1dd3698d2e8e485fc0798af3f0f92e8c9471197eb7f0363792193c50a
STORAGE_ENCRYPTION_KEY=4a67ac8bc8ee1072013821918596f56479eee30d171fb0e5b9f46a2ec350d0a9
EOF
chmod 600 /opt/authelia/.env
ls -l /opt/authelia/.env

实测回显:

-rw------- 1 root root 208 Oct 18 15:12 /opt/authelia/.env

Compose 会自动读取工作目录下的 .env,compose.yml 中的 ${JWT_SECRET} 等占位符在创建服务时被替换注入。

4.4 写入主配置 configuration.yml

cat > /opt/authelia/authelia/data/configuration.yml <<'EOF'
server:
  address: tcp://0.0.0.0:9091/
  tls:
    certificate: /config/certs/cert.pem
    key: /config/certs/key.pem

log:
  level: info

identity_validation:
  reset_password:
    jwt_lifespan: 5m
    jwt_algorithm: HS256
  elevated_session:
    code_lifespan: 5m
    elevation_lifespan: 10m
    characters: 8

authentication_backend:
  file:
    path: /config/users.yml
    password:
      algorithm: argon2
      argon2:
        variant: argon2id
        iterations: 3
        memory: 65536
        parallelism: 4

session:
  name: authelia_session
  expiration: 1h
  inactivity: 5m
  remember_me: 1M
  cookies:
    - name: authelia_session
      domain: example.com
      authelia_url: https://authelia.example.com:9091
      default_redirection_url: https://app.example.com:8098/

storage:
  local:
    path: /config/db.sqlite3

access_control:
  default_policy: deny
  rules:
    - domain: app.example.com
      policy: one_factor

regulation:
  max_retries: 3
  find_time: 2m
  ban_time: 5m

notifier:
  disable_startup_check: true
  filesystem:
    filename: /config/notification.txt
EOF

逐项解说(关键项):

  • server.address:4.38 起的新写法,替代旧的 host/port 两键(旧写法实测会打出 deprecation 警告,见十一、Q3);tls 段启用 HTTPS;
  • identity_validation.reset_password:密码重置 JWT 的有效期与算法;elevated_session 是 4.39 的新机制——用户修改安全设置前须输入一次性验证码提权(验证码经 notifier 下发),code_lifespan 为验证码有效期、elevation_lifespan 为提权后的持续时长、characters 为码长;
  • authentication_backend.file:用 YAML 文件做用户库;password.argon2 段约定新哈希的参数,与 4.2 生成的 m=65536,t=3,p=4 一致;
  • session.cookies:4.38+ 的多域名会话结构。domain: example.com 让 cookie 对该域全部子域生效;authelia_url 必须是 https(强制校验);default_redirection_url 是登录成功后的默认去向;expiration 绝对有效期 1 小时、inactivity 不活跃超时 5 分钟、remember_me 勾选「记住我」后的会话延长到 1 个月;
  • storage.local:SQLite 模式,数据库文件 /config/db.sqlite3(对应宿主机 /opt/authelia/authelia/data/db.sqlite3);
  • access_control:默认全拒(deny),仅放行 app.example.com 且策略为 one_factor(登录一次即可访问);
  • regulation:2 分钟内连续 3 次登录失败封禁来源 5 分钟(实测验证见本组件运维手册);
  • notifier.filesystem:把通知(身份验证一次性码等)写入文件,这是无 SMTP 环境的最小通知方案;disable_startup_check: true 跳过启动时的 SMTP 连通性检查(文件模式本来就不需要检查,若配置 SMTP 则应保持默认 false)。

4.5 写入用户文件 users.yml

cat > /opt/authelia/authelia/data/users.yml <<'EOF'
users:
  admin:
    displayname: "Administrator"
    password: $argon2id$v=19$m=65536,t=3,p=4$COvCyJXZxaXzM4RRCMyEJQ$/CtM5BKqBlXD6Txbey1wQwPiz+CwbcSYjRxh811kG10
    email: admin@example.com
    groups:
      - admins
      - dev
EOF

逐项说明:users 下的键名(admin)即登录用户名;password 直接粘贴 4.2 的完整哈希串;email 必填(身份验证码、密码重置都发到这里);groups 用于访问控制规则按组授权。需要更多用户就平行增加条目,改完执行 docker compose restart authelia 生效。

4.6 写入 Nginx 反代配置

cat > /opt/authelia/nginx/conf.d/default.conf <<'EOF'
# 未认证时跳转到 Authelia 登录页的目标地址(官方集成写法)
map $http_host $target_url {
    default https://$http_host$request_uri;
}

server {
    listen 8098 ssl;
    server_name app.example.com;

    ssl_certificate /etc/nginx/certs/cert.pem;
    ssl_certificate_key /etc/nginx/certs/key.pem;

    # Authelia /api/verify 内部子请求
    location /internal/authelia/authverify {
        internal;
        proxy_pass https://authelia:9091/api/verify;
        proxy_ssl_verify off;
        proxy_ssl_server_name on;
        proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Method $request_method;
        proxy_set_header X-Forwarded-Uri $request_uri;
        proxy_set_header Accept "application/json";
        proxy_set_header Content-Length "";
        proxy_set_header Connection "";
        proxy_pass_request_body off;
    }

    location / {
        auth_request /internal/authelia/authverify;
        error_page 401 =302 https://authelia.example.com:9091/?rd=$target_url;

        proxy_pass http://demo;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
EOF

逐项解说:

  • map $http_host $target_url:把「用户原本想访问的完整地址」拼出来,未认证 302 时作为 rd 参数回传,登录后 Authelia 才能把用户送回原页面;
  • /internal/authelia/authverify:internal 确保该路径只能被 Nginx 内部子请求访问,外部直接请求返回 404;proxy_pass 指向 Authelia 的校验端点;X-Original-URL 等请求头把原始请求的 URL、方法、来源完整传给 Authelia;自签证书场景必须 proxy_ssl_verify off,生产环境换成受信任证书后应改回校验;
  • auth_request:Nginx 的认证子请求机制——每个外部请求先经 authverify 校验,返回 2xx 放行、401/403 拒绝;
  • error_page 401 =302 …?rd=$target_url:把 Authelia 的 401 转换成 302 跳登录页;
  • 认证通过后 proxy_pass http://demo 转发给演示应用;proxy_ssl_* 之外,Content-Length: "" + Connection: "" + proxy_pass_request_body off 是 auth_request 子请求的标准三件套(子请求无 body)。

4.7 写入演示应用页面

cat > /opt/authelia/demo/index.html <<'EOF'
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <title>Authelia 保护下的演示应用</title>
</head>
<body>
  <h1>Hello from Demo App</h1>
  <p>如果你能看到本页,说明已通过 Authelia 认证。</p>
</body>
</html>
EOF

4.8 写入编排文件 compose.yml

cat > /opt/authelia/compose.yml <<'EOF'
services:
  authelia:
    image: authelia/authelia:4.39.28
    container_name: authelia-v4-app
    restart: unless-stopped
    environment:
      - AUTHELIA_SESSION_SECRET=${SESSION_SECRET}
      - AUTHELIA_STORAGE_ENCRYPTION_KEY=${STORAGE_ENCRYPTION_KEY}
      - AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET=${JWT_SECRET}
    volumes:
      - ./authelia/data:/config
    ports:
      - "9091:9091"
    networks:
      - authnet

  nginx:
    image: nginx:1.27-alpine
    container_name: authelia-v4-nginx
    restart: unless-stopped
    volumes:
      - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf:ro
      - ./certs:/etc/nginx/certs:ro
    ports:
      - "8098:8098"
    depends_on:
      - authelia
      - demo
    networks:
      - authnet

  demo:
    image: nginx:alpine
    container_name: authelia-v4-demo
    restart: unless-stopped
    volumes:
      - ./demo/index.html:/usr/share/nginx/html/index.html:ro
    networks:
      - authnet

networks:
  authnet:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.23.0/24
EOF
cd /opt/authelia && docker compose config -q && echo 'compose 配置校验通过'

实测回显:

compose 配置校验通过

逐项解说:

  • 密钥注入路径:.env 的值 → ${VAR} → 容器环境变量 AUTHELIA_SESSION_SECRET 等。注意前缀必须是 AUTHELIA_,后接配置项的完整点路径转大写下划线,例如 session.secret → AUTHELIA_SESSION_SECRET、storage.encryption_key → AUTHELIA_STORAGE_ENCRYPTION_KEY、identity_validation.reset_password.jwt_secret → AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET。环境变量名写错时 Authelia 仍会启动但打 not expected 警告且配置不生效(实测复现见十一、Q1);
  • container_name:固定名字便于日志与排查;demo 不映射端口,只暴露在网络内;
  • networks.authnet:显式指定子网 10.89.23.0/24,避免与宿主机局域网段冲突;创建后可用 docker network inspect 与 ip route get <网关IP> 自查路由未被网桥劫持;
  • 证书挂载:Nginx 侧 :ro 只读即可;Authelia 侧证书放在可写的 /config 内部(见二、末尾说明)。

4.9 启动并确认状态

cd /opt/authelia && docker compose up -d

实测回显:

 Container authelia-v4-nginx Created
 Container authelia-v4-app Started
 Container authelia-v4-demo Started
 Container authelia-v4-nginx Started

首次启动 Authelia 会自动做存储 schema 迁移(建库建表)。查看日志:

docker logs authelia-v4-app 2>&1 | grep -E 'starting|migrat|complete|Listening'

实测回显(首次启动):

time="2026-10-18T07:15:18Z" level=info msg="Authelia v4.39.28 is starting"
time="2026-10-18T07:15:18Z" level=info msg="Log severity set to info"
time="2026-10-18T07:15:18Z" level=info msg="Storage schema is being checked for updates"
time="2026-10-18T07:15:18Z" level=info msg="Storage schema is already up to date"
time="2026-10-18T07:15:24Z" level=info msg="Startup complete"
time="2026-10-18T07:15:24Z" level=info msg="Listening for TLS connections on '[::]:9091' path '/'" server=main service=server

⚠️ 首次启动日志中若出现 Storage schema migration from 0 to 29 is being attempted / is complete 属正常现象(全新 SQLite 库从 schema 0 建到当前版本 29)。若出现 level=fatal msg="Can't continue due to the errors loading the configuration",说明配置有错未启动成功,按十一、常见问题逐条排查。

状态确认(等 healthcheck 通过,约 10 秒):

docker compose ps

实测回显:

NAME                IMAGE                       COMMAND                   SERVICE    CREATED          STATUS                    PORTS
authelia-v4-app     authelia/authelia:4.39.28   "/app/entrypoint.sh"      authelia   21 seconds ago   Up 21 seconds (healthy)   0.0.0.0:9091->9091/tcp, [::]:9091->9091/tcp
authelia-v4-demo    nginx:alpine                "/docker-entrypoint.…"    demo       18 minutes ago   Up 18 minutes             80/tcp
authelia-v4-nginx   nginx:1.27-alpine           "/docker-entrypoint.…"    nginx      18 minutes ago   Up 16 minutes             80/tcp, 0.0.0.0:8098->8098/tcp, [::]:8098->8098/tcp

4.10 健康检查与 API 探活

curl -sk https://127.0.0.1:9091/api/health; echo

实测回显:

{"status":"OK"}
curl -sk --resolve authelia.example.com:9091:127.0.0.1 https://authelia.example.com:9091/api/state

实测回显:

{"status":"OK","data":{"username":"","authentication_level":0,"factor_knowledge":false,"default_redirection_url":"https://app.example.com:8098/"}}

回显解读:username 为空、authentication_level: 0 表示当前是匿名会话(未登录)。/api/state 必须用配置域名访问——直接 curl https://127.0.0.1:9091/api/state 会因 cookie 域校验返回 403(实测确认,见十一、Q6)。

4.11 端到端认证链路实测

以下三个请求构成完整链路,全部为真实回显。

第一步:未认证访问受保护应用,应 302 跳登录页。

curl -sk --resolve app.example.com:8098:127.0.0.1 -i https://app.example.com:8098/ | head -8

实测回显:

HTTP/1.1 302 Moved Temporarily
Server: nginx/1.27.5
Date: Sun, 18 Oct 2026 07:16:51 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: https://authelia.example.com:9091/?rd=https://app.example.com:8098/

Location 正确携带了回跳地址 ?rd=…,说明 map 与 error_page 链路正常。

第二步:调用登录接口获取会话(演示账号 admin / q1w2e3r4)。

curl -sk --resolve authelia.example.com:9091:127.0.0.1 -i \
  -X POST https://authelia.example.com:9091/api/firstfactor \
  -H 'Origin: https://authelia.example.com:9091' \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"q1w2e3r4","rememberMe":true}' | head -22

实测回显(节选关键头与响应体):

HTTP/1.1 200 OK
Date: Sun, 18 Oct 2026 07:17:02 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 67
Set-Cookie: authelia_session=N#FleNgyVQj47ElmTNQS6FLvwGHfaly!; expires=Sun, 18 Oct 2026 08:17:01 GMT; domain=example.com; path=/; HttpOnly; secure; SameSite=Lax

{"status":"OK","data":{"redirect":"https://app.example.com:8098/"}}

回显解读:200 即一因子认证通过;Set-Cookie 中的会话 cookie 域为 example.com(对子域 app.example.com 生效),并带有 HttpOnly、secure、SameSite=Lax 安全属性;expires 比 Date 晚 1 小时,对应 session.expiration: 1h;响应体的 redirect 指向默认跳转地址。请求头里的 Origin 是必需的——Authelia 校验来源防止跨站伪造。

第三步:带着会话 cookie 再次访问受保护应用,应返回演示页。

curl -sk --resolve app.example.com:8098:127.0.0.1 -i \
  https://app.example.com:8098/ \
  -H 'Cookie: authelia_session=N#FleNgyVQj47ElmTNQS6FLvwGHfaly!' | head -12

实测回显:

HTTP/1.1 200 OK
Server: nginx/1.27.5
Date: Sun, 18 Oct 2026 07:17:11 GMT
Content-Type: text/html
Content-Length: 252
Last-Modified: Sun, 18 Oct 2026 07:10:17 GMT

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <title>Authelia 保护下的演示应用</title>
</head>

第四步:直接验证 Authelia 的校验端点 /api/verify。

带有效会话:

curl -sk -i https://127.0.0.1:9091/api/verify \
  -H 'Cookie: authelia_session=N#FleNgyVQj47ElmTNQS6FLvwGHfaly!' \
  -H 'X-Original-URL: https://app.example.com:8098/' | head -8

实测回显:

HTTP/1.1 200 OK
Date: Sun, 18 Oct 2026 07:17:27 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 6
Remote-User: admin
Remote-Groups: admins,dev
Remote-Name: Administrator
Remote-Email: admin@example.com

不带会话:

curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1:9091/api/verify \
  -H 'X-Original-URL: https://app.example.com:8098/'

实测回显:

401

回显解读:认证通过时 /api/verify 除了 200 还返回 Remote-User、Remote-Groups、Remote-Name、Remote-Email 四个身份头——这正是 Nginx 可以进一步注入给后端应用的用户身份信息;未认证返回 401,与 auth_request 的放行/拒绝逻辑一致。

至此部署与验证全部完成。浏览器访问 https://app.example.com:8098/ 会看到 Authelia 登录门户,输入 admin / q1w2e3r4 后即可到达演示页(自签证书浏览器会有告警,属预期)。

五、数据持久化说明

部署完成后,/opt/authelia/authelia/data/(容器内 /config)里会生成全部持久化数据:

ls -l /opt/authelia/authelia/data/

实测回显:

total 320
drwxr-xr-x 3 root root   4096 Oct 18 15:22 certs
-rw-r--r-- 1 root root   1092 Oct 18 15:21 configuration.yml
-rw-r--r-- 1 root root 311296 Oct 18 15:22 db.sqlite3
-rw------- 1 root root    229 Oct 18 15:13 users.yml
  • db.sqlite3:存储后端(会话元数据、2FA 设备绑定、防暴力破解封禁记录、OIDC 会话等),这是唯一需要备份的运行时文件;
  • configuration.yml / users.yml:配置与用户库(源码性质,进配置管理工具);
  • certs/:TLS 证书;
  • notification.txt:文件通知的输出(出现一次性验证码等通知时生成)。

⚠️ 注意:storage.encryption_key(.env 中的 STORAGE_ENCRYPTION_KEY)与 db.sqlite3 是绑定关系——更换密钥后数据库中的加密列无法解密,2FA 设备绑定会全部失效。备份必须两者一起备份;同样,把数据库拷到新环境必须带上原密钥。

六、环境变量表

.env 变量注入容器后的环境变量名对应配置项用途生成方式
JWT_SECRETAUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRETidentity_validation.reset_password.jwt_secret密码重置 JWT 签名openssl rand -hex 32
SESSION_SECRETAUTHELIA_SESSION_SECRETsession.secret会话 cookie 签名与加密openssl rand -hex 32
STORAGE_ENCRYPTION_KEYAUTHELIA_STORAGE_ENCRYPTION_KEYstorage.encryption_key存储敏感列加密(≥20 字符)openssl rand -hex 32

表格解读:三行的映射规律一致——AUTHELIA_ 前缀 + 配置点路径大写化。官方 secrets 文档列出的同名 _FILE 后缀变体(如 AUTHELIA_SESSION_SECRET_FILE)指向存放密钥的文件路径,密钥内容放文件而非环境变量,适合编排系统里有 secrets 卷的场景;本篇采用直接值注入的最小形式。

七、配置参数说明

本篇涉及的主配置就是 4.4 的 configuration.yml,此处按段给出「在本方案中的作用 + 改动影响」,完整参数逐项详解见《Authelia 4.39 配置参数详解》。

配置段本方案取值改动影响
server9091 + TLS改端口需同步 ports: 与反代 proxy_pass;TLS 证书路径在 /config/certs/
session.cookiesexample.com 域换域名时 domain/authelia_url/default_redirection_url 三处联动改,并同步 hosts/证书 SAN
session 时长expiration 1h / inactivity 5m数值支持 1h/5m/1M 等后缀;调大 inactivity 会降低安全性
storage.local/config/db.sqlite3换 MySQL/PostgreSQL 时改用 storage.mysql/storage.postgres 段
access_control默认 deny + app 域 one_factor增加 two_factor 规则后用户需注册 2FA 设备才能访问
regulation3 次 / 2 分钟 / 封 5 分钟阈值过低会误伤内网扫描器
notifier.filesystem/config/notification.txt生产建议改 notifier.smtp,否则用户收不到验证码邮件

八、配置文件挂载清单

宿主机路径容器内路径挂载服务读写作用
/opt/authelia/authelia/data/configauthelia读写数据根:配置、用户库、SQLite、证书、通知文件
/opt/authelia/nginx/conf.d/default.conf/etc/nginx/conf.d/default.confnginx只读反代与 auth_request 配置
/opt/authelia/certs/etc/nginx/certsnginx只读反代 TLS 证书
/opt/authelia/demo/index.html/usr/share/nginx/html/index.htmldemo只读演示页

说明:Authelia 侧整个 /config 用读写挂载是硬要求——官方 entrypoint 启动时对 /config 递归 chown,只读子路径会报 chown: Read-only file system(虽不阻断启动,但日志持续报错)。所有「只读性质」的资源在 Authelia 侧放进 /config 内部即可;Nginx 侧无此问题,保持 :ro 最小权限。

九、等价 docker run 命令

不使用 Compose 时,三条命令等价于上述三服务(先建同名网络):

docker network create -d bridge --subnet 10.89.23.0/24 authnet

服务一:Authelia 认证服务器

docker run -d --name authelia-v4-app --restart unless-stopped \
  --network authnet -p 9091:9091 \
  -e AUTHELIA_SESSION_SECRET=c13249d1dd3698d2e8e485fc0798af3f0f92e8c9471197eb7f0363792193c50a \
  -e AUTHELIA_STORAGE_ENCRYPTION_KEY=4a67ac8bc8ee1072013821918596f56479eee30d171fb0e5b9f46a2ec350d0a9 \
  -e AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET=274c79d96662a0980186cf1d0192b94032b7db9d7211918d8128cb126b15c737 \
  -v /opt/authelia/authelia/data:/config \
  authelia/authelia:4.39.28

服务二:Nginx 反向代理

docker run -d --name authelia-v4-nginx --restart unless-stopped \
  --network authnet -p 8098:8098 \
  -v /opt/authelia/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf:ro \
  -v /opt/authelia/certs:/etc/nginx/certs:ro \
  nginx:1.27-alpine

服务三:演示后端

docker run -d --name authelia-v4-demo --restart unless-stopped \
  --network authnet \
  -v /opt/authelia/demo/index.html:/usr/share/nginx/html/index.html:ro \
  nginx:alpine

⚠️ 注意:密钥值直接写在 docker run 命令行里会进入 shell 历史,仅用于一次性验证;长期运行建议仍用 Compose + .env(或 --env-file)。Compose 与手工容器二选一,同名网络/容器并存会冲突。

十、常用运维命令

cd /opt/authelia

# 查看三服务状态与健康值
docker compose ps

# 跟踪 Authelia 日志(登录成功/失败、封禁都会在这里)
docker compose logs -f authelia

# 修改 configuration.yml / users.yml 后使其生效
docker compose restart authelia

# 修改反代配置后先校验语法再平滑重载
docker compose exec nginx nginx -t
docker compose restart nginx

# 全栈停止 / 启动(数据保留)
docker compose down
docker compose up -d

# 完全移除(含网络;数据目录 /opt/authelia/authelia/data 不会被删除)
docker compose down --remove-orphans

docker compose exec nginx nginx -t 的实测回显:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

十一、常见问题

Q1:启动日志出现 configuration environment variable not expected: AUTHELIA_SESSION_SECRET,认证相关配置全部没生效。 实测现象:首启日志出现 level=warning msg="Configuration: configuration environment variable not expected: AUTHELIA_SESSION_ENCRYPTION_KEY",随后报 session 相关配置缺失。定位:Authelia 只识别 AUTHELIA_ 前缀 + 配置点路径的变量名,拼写错一个字母或用了不存在的配置键(如 4.39 已移除的 session.encryption_key 对应变量)就会整条忽略。解决:对照六、环境变量表的映射关系修正 .env 与 compose.yml 的变量名,重启后日志中 not expected 警告应归零(实测修正后 grep -cE 'not expected' 输出 0)。

Q2:启动失败,日志报 option 'authelia_url' does not have a secure scheme with a value of 'http://authelia.example.com:9091'。 定位:4.39 强制 session.cookies[].authelia_url 必须是 https。解决:为 Authelia 配置 server.tls 证书并把 authelia_url、default_redirection_url 全部改为 https://,反向代理与测试命令同步用 https(自签场景 curl 加 -k)。修正后实测正常启动:Listening for TLS connections on '[::]:9091'。

Q3:日志出现多条 configuration key ... is deprecated in 4.38.0 警告。 实测原文节选:

level=warning msg="Configuration: configuration keys 'server.host', 'server.port', and 'server.path' are deprecated in 4.38.0 and has been replaced by 'server.address' in the format of '[tcp[(4|6)]://]<hostname>[:<port>][/<path>]' ..."
level=warning msg="Configuration: configuration key 'session.remember_me_duration' is deprecated in 4.38.0 and has been replaced by 'session.remember_me' ..."

说明旧写法仍能自动映射、不影响启动,但会在 5.0 移除。解决:server.host/port 合并为 server.address: tcp://0.0.0.0:9091/,remember_me_duration 改名 remember_me,警告即消失。

Q4:日志持续报 chown: /config/certs/cert.pem: Read-only file system。 定位:把证书等只读资源以 :ro 单独挂进 /config 子路径,与官方 entrypoint 对 /config 的 chown 冲突。该报错不阻断启动,但很吵。解决:把证书移到数据目录内部(本方案的 /config/certs/),仅挂一个可写的 ./authelia/data:/config。

Q5:/api/state 用 curl https://127.0.0.1:9091/api/state 访问返回 403 Forbidden。 定位:/api/state 与登录接口受会话域校验,Host 必须匹配 session.cookies[].domain 配置的域名(example.com),127.0.0.1 不在域内。解决:加 --resolve authelia.example.com:9091:127.0.0.1 用配置域名访问(4.10 已给出实测对照)。/api/health 与 /api/verify 无此限制,可用 IP 直连。

Q6:浏览器登录跳回登录页循环(rd 参数丢失或 cookie 未带上)。 定位思路:① session.cookies[].domain 与实际访问域名不一致(cookie 根本没发给浏览器);② 反代未加 error_page 401 =302 …?rd=$target_url 导致 302 无 Location;③ 走了 http 明文代理,secure 属性 cookie 被浏览器丢弃。逐一对照 4.6 的反代配置与 3.2 的域名解析检查即可。可用 4.11 的四步 curl 链路分层定位:哪一步的回显与本篇不符,问题就在哪一层。

Q7:端口 9091/8098 被占用。 实测处理:用 ss -ltn | grep -E ':(9091|8098)\b' 找出占用者;若确认是其他服务长期占用,顺延端口并保证三处一致——compose.yml 的 ports:、configuration.yml 的 server.address、反代 proxy_pass https://authelia:<端口>,以及 authelia_url 中的端口。

十二、参考链接