Authentik 自托管 SSO:Docker Compose 配置与 Traefik
使用 Docker Compose 部署 Authentik,为所有自托管应用提供统一登录。本文说明关键环境变量、akadmin 初始账户、两个密钥,以及 Traefik forward auth 配置。
为您托管的每个应用使用一个登录
Authentik 是一个自托管 SSO(单点登录)服务器:用户只需登录一次,其后的每个应用都会接受该会话,而不是要求用户分别输入密码。安装过程使用官方 Docker Compose 文件和两个生成的密钥。真正需要仔细配置的是后续步骤:将反向代理指向 Authentik,并通过 forward auth 保护一个现有应用。
Authentik 在该 Compose 文件中以三个服务运行:PostgreSQL 数据库、server 进程和 worker 进程。服务器容器还会运行嵌入式 outpost。该组件会为每个受保护的应用回答“此请求是否已登录?”。截至 2026 年 7 月,2026.5 是当前版本。项目要求主机至少具有 2 个 CPU 核心和 2 GB RAM。请将其视为最低配置。主机运行一天后,PostgreSQL 和 worker 都会占用内存。
开始前的准备工作
您需要安装带有 Compose v2 插件的 Docker Engine,可使用 docker compose version 进行确认。如果该命令输出错误而不是版本号,请先安装此插件再继续;相关基础内容请参阅在 VPS 上使用 Docker Compose 运行应用。您还需要将 DNS A 记录指向服务器,以下示例中的主机名为 auth.example.com,因为 Authentik 会根据浏览器使用的主机名生成重定向 URL。
请以 docker 组中的普通用户运行此堆栈,而不要使用 root。该组的成员权限等同于主机上的 root 权限,因此应仅将其分配给一个部署账户,不要分配给其他账户,具体可参考VPS 上遵循最小权限原则的用户账户。
使用官方 Compose 文件安装
sudo install -d -o "$USER" -g "$USER" /opt/authentik
cd /opt/authentik
wget https://docs.goauthentik.io/compose.yml
echo "PG_PASS=$(openssl rand -base64 36 | tr -d '\n')" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env
docker compose pull
docker compose up -ddocker compose ps 应列出三个容器,其中 postgresql 报告 healthy,server 报告 worker,并且 running 报告 PG_PASS。首次启动会运行数据库迁移,因此请等待一分钟,Web 界面才会响应。
生成的两个值都很重要,原因不同。AUTHENTIK_SECRET_KEY 是 PostgreSQL 密码,长度上限为 99 个字符。.env 用于签名会话和令牌,因此之后修改它会使所有用户退出登录,并使已签发的所有 API 令牌失效。将 ${PG_PASS:?database password required} 的权限保持为 600,并在安全位置保留一份副本,因为恢复的数据库如果没有与之匹配的密钥,就没有人能够登录。
Compose 文件使用 docker compose up -d 形式读取这两个值,这意味着文件缺失时 Compose 会拒绝启动。从错误目录运行 required variable AUTHENTIK_SECRET_KEY is missing a value: secret key required 会打印 .env,然后停止。该消息表示路径问题,而不是配置问题。
重要的环境变量
其他内容都写入同一个 .env 文件。Authentik 会将两个下划线映射为嵌套配置键,因此 AUTHENTIK_EMAIL__HOST 会设置 email.host。单个下划线会被忽略,且不会显示警告。这是设置看起来不起作用的最常见原因。
AUTHENTIK_BOOTSTRAP_PASSWORD会在首次启动时设置内置akadmin用户的密码,因此无需在公开 Web 表单中输入密码。AUTHENTIK_BOOTSTRAP_EMAIL和AUTHENTIK_BOOTSTRAP_TOKEN以相同方式设置该用户的地址和 API 令牌。COMPOSE_PORT_HTTP和COMPOSE_PORT_HTTPS将对外发布的端口从默认值 9000 和 9443 更改为其他端口。AUTHENTIK_EMAIL__HOST、AUTHENTIK_EMAIL__PORT、AUTHENTIK_EMAIL__USERNAME、AUTHENTIK_EMAIL__PASSWORD、AUTHENTIK_EMAIL__USE_TLS和AUTHENTIK_EMAIL__FROM配置出站邮件。未设置这些变量时,Authentik 会在端口 25 上尝试使用localhost,因此密码重置邮件会因连接错误而失败,并在 worker 日志中记录错误。AUTHENTIK_LOG_LEVEL=debug会在登录流程出现异常时启用所需的详细信息。排查完成后,将其改回info。AUTHENTIK_ERROR_REPORTING__ENABLED默认为false。仅当您愿意将崩溃报告发送给上游时,才将其设置为true。
这些内容以明文形式存储在文件中,因此应像管理其他凭据存储一样保护该目录。密码管理器(例如 自行托管的 Vaultwarden 实例)比笔记本电脑上的便签更适合保存恢复副本。
首次登录和 admin 账户
在浏览器中打开 http://SERVER_IP:9000。Authentik 会显示初始设置流程,并要求您为默认的 akadmin 用户设置密码。如果您已经设置了 AUTHENTIK_BOOTSTRAP_PASSWORD,则该步骤已完成,您会直接进入登录页面。
在 Directory 下进入 Users,为自己创建一个普通 admin 用户,将其添加到 authentik Admins 组,然后使用该账户登录。保留 akadmin 作为紧急恢复账户,并将其长密码离线保存。日常工作使用共享的内置账户会破坏审计日志,因为每个事件都显示为 akadmin,无法表明具体操作人员。
将 Authentik 放在反向代理后
将端口 9000 发布到互联网可以工作,但您需要 TLS(传输层安全)和正式的主机名。如果您已经在运行使用 Traefik 作为多个 Compose 应用的反向代理中的配置,请使用覆盖文件将 Authentik 加入同一个外部 proxy 网络。将 docker-compose.override.yml 创建在 compose.yml 旁边:
services:
server:
networks:
- default
- proxy
labels:
traefik.enable: "true"
traefik.docker.network: proxy
traefik.http.routers.authentik.rule: Host(`auth.example.com`)
traefik.http.routers.authentik.entrypoints: websecure
traefik.http.routers.authentik.tls.certresolver: le
traefik.http.services.authentik.loadbalancer.server.port: "9000"
networks:
proxy:
external: true使用 docker compose up -d 应用该配置。Compose 会自动合并覆盖文件,因此 server 服务会保留官方文件中的所有配置,并获得这些标签。使用 curl -I https://auth.example.com/if/user/ 检查,正常情况下它应响应 HTTP/2 200。Traefik 返回 404 page not found,表示容器不在 proxy 网络中,Traefik 无法将流量路由到无法访问的容器。
主机名正常工作后,在覆盖文件中将已发布端口绑定到 127.0.0.1,这样只能通过代理访问。
使用 forward auth 保护单个应用
Authentik 的代理提供程序有 3 种模式,选错模式可能浪费 1 小时。Proxy 表示由 outpost 自身将流量转发到上游应用。Forward auth (single application) 表示由您自己的反向代理转发流量,只向 Authentik 请求确认用户是否已登录。Forward auth (domain level) 使用单个提供程序保护同一父域名下的所有应用,但需要为每个应用配置授权规则。当前端使用 Traefik 时,应选择 forward auth (single application)。
在 Web 界面中,打开 Applications,然后打开 Providers,创建 Proxy Provider,选择 forward auth single application 模式,并将外部主机设置为 https://app.example.com。创建一个指向该提供程序的 Application。然后打开 Outposts,编辑 authentik Embedded Outpost,并将新应用移到其 selected applications 中。outpost 只会处理已分配给它的应用,因此如果跳过最后一步,即使提供程序配置正确,也不会返回任何内容。
在 Authentik 容器上定义一次中间件,然后让每个受保护的应用引用它:
traefik.http.middlewares.authentik.forwardauth.address: http://server:9000/outpost.goauthentik.io/auth/traefik
traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: "true"
traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-versionauthResponseHeaders 是 Traefik 从 Authentik 的响应中复制到发往上游的请求的标头列表。如果省略它,应用仍会受到保护,但无法获知用户身份。因此,任何读取 X-authentik-username 以自动登录的功能都会保持未登录状态。
受保护的应用本身需要 2 个路由,而不是 1 个:
labels:
traefik.enable: "true"
traefik.http.routers.myapp.rule: Host(`app.example.com`)
traefik.http.routers.myapp.entrypoints: websecure
traefik.http.routers.myapp.tls.certresolver: le
traefik.http.routers.myapp.middlewares: authentik@docker
traefik.http.routers.myapp-auth.rule: Host(`app.example.com`) && PathPrefix(`/outpost.goauthentik.io/`)
traefik.http.routers.myapp-auth.entrypoints: websecure
traefik.http.routers.myapp-auth.tls.certresolver: le
traefik.http.routers.myapp-auth.priority: "15"
traefik.http.routers.myapp-auth.service: authentik第二个路由是最容易遗漏的部分。登录后,Authentik 会将浏览器重定向到 应用主机名下 /outpost.goauthentik.io/ 的路径,而不是 auth.example.com 下的路径。如果没有路由将此前缀路径发送到 Authentik 服务,请求就会到达您的应用。应用会返回 404,登录流程也不会完成。较高的 priority 会使特定路径规则优先于同一域名上的普通 Host() 规则。
在隐私浏览器窗口中进行测试。浏览器应被重定向到 auth.example.com,完成登录后返回应用。Authentik 端的 docker compose logs -f server 会为每次尝试打印一条授权事件,用于确认请求是否到达 Authentik。
您实际会遇到的故障
应用与登录页面之间无限重定向。 提供商上的外部主机名与浏览器使用的主机名不匹配,通常是提供商中的 http:// 与地址栏中的 https:// 不一致。随后,会话 cookie 被设置到另一个源,因此每次返回时都会被视为新的匿名请求。修正外部主机名,并清除这两个域名的 cookie,然后重新测试。
/outpost.goauthentik.io/start 返回 404。 outpost 路由器缺失,或其优先级低于该主机的全匹配路由器。
应用加载,但始终不要求登录。 middlewares 标签引用了不存在的中间件。Traefik 不会对此发出警告,因此 authentik@docker 中的拼写错误只会导致没有中间件运行。打开 Traefik 控制面板,确认路由器列出了该中间件。
成功登录后 Authentik 返回 403。 用户已通过身份验证,但未获授权:应用配置了该用户不满足的策略绑定或组要求。管理界面的 Events 日志会指出拒绝该请求的策略。
Keycloak 更适合的场景
Keycloak 是较早的项目,由 Red Hat 支持。对于传统企业身份管理,它通常是更强的选择,尤其适合复杂的 SAML 联合身份认证、同时代理来自多个外部身份提供商的登录,以及将 realm 导出和导入作为有文档记录的迁移路径。对部分组织而言,背后的商业支持在正式评估中也很重要。代价是 Keycloak 没有自带代理。因此,要保护不支持 OIDC(OpenID Connect)的应用,必须在旁边运行类似 oauth2-proxy 的组件。Authentik 内置的 proxy provider 已经集成了这一功能。这也是大多数同时运行多种应用的自托管用户最终选择 Authentik 的原因。
备份和升级
恢复需要以下3项:PostgreSQL 数据库、./data 目录和 .env。
cd /opt/authentik
docker compose exec -T postgresql pg_dump -U authentik authentik | gzip > authentik-$(date +%F).sql.gz将该转储文件与 .env 一起保存。仅有转储文件还不够,因为用于保护会话和令牌数据的密钥位于 .env 中。
升级只需更改标签。在 .env 中将 AUTHENTIK_TAG 设置为所需版本,然后运行 docker compose pull,再运行 docker compose up -d。先阅读发行说明,因为 Authentik 使用基于日期的版本号,某些版本包含迁移,这些迁移要求您从上一个版本升级。请在执行 pull 之前创建数据库转储,不要在之后创建。
FAQ
Authentik 可免费自行托管吗?
开源版免费,包含上述所有功能:代理提供程序、forward auth、OIDC (OpenID Connect)、SAML 和 flows engine。付费企业版增加支持服务和部分企业功能,但本文中的功能都不需要许可证。
使用 Authentik 必须依赖 Traefik 吗?
不需要。通过 auth_request,forward auth 可与 nginx 配合使用;通过 forward_auth,也可与 Caddy 配合使用。每种情况下的模式都相同:反向代理针对每个请求向 Authentik 进行验证,受保护主机名下的路径前缀 /outpost.goauthentik.io/ 必须路由到 Authentik,而不是应用。
为什么受保护的应用会在登录页和错误页之间无限循环?
代理提供程序中配置的外部主机与浏览器使用的 URL 不匹配,最常见的情况是 http 与 https 不一致。会话 Cookie 针对一个源签发,却从另一个源读取,因此 Authentik 每次都将请求视为匿名请求。修正外部主机配置,然后清除这两个主机名对应的 Cookie,再次测试。
Authentik 需要多少 RAM?
截至 July 2026,文档规定的最低配置是 2 个 CPU 核心和 2 GB RAM,涵盖 PostgreSQL、server 和 worker。对于只有 2 GB RAM 的服务器,内存压力下 kernel 首先终止 worker。此时后台任务和外发邮件会停止,但登录页面仍可正常工作。如果同一服务器还运行受保护的应用,请分配 4 GB RAM。