Authelia Docker Compose 部署指南
在 Ubuntu 22.04 用 Compose 从零部署 Authelia v4.39.28 + Nginx auth_request + 演示应用:密钥注入、自签 HTTPS、用户库初始化与端到端认证链路实测
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/authelia | 4.39.28 | 认证服务器 | 官方镜像;锁定具体版本号而非 latest,保证回显可复现、升级可控 |
| nginx | 1.27-alpine | 反向代理(auth_request) | 1.27 为当前稳定主线,alpine 变体体积小;官方 Authelia 集成文档以 Nginx 为主要示例 |
| nginx | alpine | 演示后端 | 用一个纯静态页模拟「受保护应用」,不占用服务器端口,聚焦认证链路本身 |
选型解读:三个角色用同一网络互通。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 等:
算法 参数形态 适用建议 argon2id m=65536,t=3,p=4(默认) 当前首选,抗 GPU 破解 scrypt N,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_SECRET | AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET | identity_validation.reset_password.jwt_secret | 密码重置 JWT 签名 | openssl rand -hex 32 |
| SESSION_SECRET | AUTHELIA_SESSION_SECRET | session.secret | 会话 cookie 签名与加密 | openssl rand -hex 32 |
| STORAGE_ENCRYPTION_KEY | AUTHELIA_STORAGE_ENCRYPTION_KEY | storage.encryption_key | 存储敏感列加密(≥20 字符) | openssl rand -hex 32 |
表格解读:三行的映射规律一致——AUTHELIA_ 前缀 + 配置点路径大写化。官方 secrets 文档列出的同名 _FILE 后缀变体(如 AUTHELIA_SESSION_SECRET_FILE)指向存放密钥的文件路径,密钥内容放文件而非环境变量,适合编排系统里有 secrets 卷的场景;本篇采用直接值注入的最小形式。
七、配置参数说明
本篇涉及的主配置就是 4.4 的 configuration.yml,此处按段给出「在本方案中的作用 + 改动影响」,完整参数逐项详解见《Authelia 4.39 配置参数详解》。
| 配置段 | 本方案取值 | 改动影响 |
|---|---|---|
| server | 9091 + TLS | 改端口需同步 ports: 与反代 proxy_pass;TLS 证书路径在 /config/certs/ |
| session.cookies | example.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 设备才能访问 |
| regulation | 3 次 / 2 分钟 / 封 5 分钟 | 阈值过低会误伤内网扫描器 |
| notifier.filesystem | /config/notification.txt | 生产建议改 notifier.smtp,否则用户收不到验证码邮件 |
八、配置文件挂载清单
| 宿主机路径 | 容器内路径 | 挂载服务 | 读写 | 作用 |
|---|---|---|---|---|
| /opt/authelia/authelia/data | /config | authelia | 读写 | 数据根:配置、用户库、SQLite、证书、通知文件 |
| /opt/authelia/nginx/conf.d/default.conf | /etc/nginx/conf.d/default.conf | nginx | 只读 | 反代与 auth_request 配置 |
| /opt/authelia/certs | /etc/nginx/certs | nginx | 只读 | 反代 TLS 证书 |
| /opt/authelia/demo/index.html | /usr/share/nginx/html/index.html | demo | 只读 | 演示页 |
说明: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 中的端口。
十二、参考链接
- 官方部署文档(Get Started):https://www.authelia.com/configuration/prologue/get-started/
- 官方 Secrets 注入方式:https://www.authelia.com/configuration/methods/secrets/
- 环境变量配置方法:https://www.authelia.com/configuration/methods/environment-variables/
- Nginx 集成参考(auth_request):https://www.authelia.com/integration/proxies/nginx/
- 会话配置文档:https://www.authelia.com/configuration/session/introduction/
- 文件用户后端文档:https://www.authelia.com/configuration/first-factor/file/
- 密码哈希生成工具:https://www.authelia.com/reference/cli/authelia/authelia_crypto_hash/
- 本专栏选型篇:https://www.quzuo.net/document/ao7cgAvGtzVB