Authentik 自托管 SSO:Docker Compose 配置指南
通过 Docker Compose 部署 Authentik,实现所有应用一次登录。本文说明关键环境变量、akadmin 初始账户,以及 Traefik forward auth 的接入配置。
为托管的每个应用使用一个登录
Authentik 是一款自托管 SSO(单点登录)服务器:用户只需登录一次,其后的每个应用都会接受该会话,而不是要求用户分别设置密码。安装过程使用官方 Docker Compose 文件和 2 个生成的密钥。真正需要仔细配置的是后续步骤:将反向代理指向 Authentik,并通过 forward auth 将一个现有应用置于其保护之下。
Authentik 在该 Compose 文件中以 3 个服务运行:PostgreSQL 数据库、一个 server 进程和一个 worker 进程。服务器容器还会运行内置 outpost。该组件会为每个受保护的应用回答“此请求是否已登录?”。截至 25 October 2026,2026.8.5 是当前版本。该版本于 21 October 2026 发布,是 2026.8 系列的最新补丁版本。该系列于 18 August 以 2026.8.0 开始,2026.8.5 取代了 14 October 发布的 2026.8.4,成为官方 Compose 文件中的默认镜像标签。项目要求主机至少具有 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 应列出 3 个容器,且全部处于运行状态;检查通过后,postgresql 应报告 healthy。首次启动会运行数据库迁移,因此请等待 1 分钟,直到 Web 界面开始响应。
这 2 个生成的值分别很重要。PG_PASS 是 PostgreSQL 密码。Authentik 安装文档说明不支持长度超过 99 个字符的密码,因此如果自行选择密码,请将长度保持在该限制以内;生成的密码远短于此限制。AUTHENTIK_SECRET_KEY 是 Authentik 用来签名 Cookie 的密钥。其配置文档说明,更改该密钥会使活动会话失效,因此之后生成新密钥会将所有已登录用户注销。将 .env 的权限保持为模式 600,并将副本与备份一起安全保存,以便恢复后继续使用服务器原来的密钥。
Compose 文件使用 ${VAR:?message} 形式将这 2 个值标记为必需值:PostgreSQL 服务使用 ${PG_PASS:?database password required},服务器和 worker 使用 ${AUTHENTIK_SECRET_KEY:?secret key required}。这意味着文件缺失时,Compose 会拒绝启动。从错误的目录运行 docker compose up -d 时,会输出类似 required variable AUTHENTIK_SECRET_KEY is missing a value: secret key required 的行,然后停止。该消息表示路径问题,而不是配置问题。
重要的环境变量
其他内容都写入同一个 .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 实例,不要记录在笔记本电脑上的普通笔记中。
首次登录和管理员帐户
在浏览器中打开 http://SERVER_IP:9000。Authentik 会显示初始设置流程,并要求你为默认的 akadmin 用户设置密码。如果你已经设置了 AUTHENTIK_BOOTSTRAP_PASSWORD,则该步骤已完成,系统会直接显示登录页面。
在 Directory 下进入 Users,为自己创建一个普通管理员用户,然后将其加入 authentik Admins 组,并使用该帐户登录。将 akadmin 保留为紧急恢复帐户,并在线下保存一个长密码。如果错误的 flow 或 stage 导致你无法登录,docker compose run --rm server create_recovery_key 10 akadmin 从 /opt/authentik 运行后会输出一个链接,直接以 akadmin 身份登录。持有该链接的任何人都拥有相同的访问权限,因此应像保护密码一样保护它。日常工作使用共享的内置帐户会破坏审计日志,因为每个事件都显示为 akadmin,无法表明实际操作者是谁。该问题也会影响 Authentik 下游的系统:例如 一个让每个人使用自己 agent 的自托管 OneCLI harness,只有在到达该系统的身份属于某个具体人员,而不是全团队共享的登录帐户时,才能留下清晰可读的操作记录。
将 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,表示没有路由器匹配该请求。请检查标签是否已传递到容器、Host() 规则是否与主机名完全匹配,以及请求是否到达路由器监听的 HTTPS 入口点。
主机名正常工作后,在覆盖文件中将已发布端口绑定到 127.0.0.1,这样只能通过代理访问该服务。
使用 Forward Auth 保护单个应用
Authentik 的 Proxy Provider 有 3 种模式。选错模式可能浪费 1 小时。Proxy 表示由 outpost 自身将流量转发到上游应用。Forward auth (single application) 表示仍由您自己的反向代理转发流量,只向 Authentik 查询请求是否已登录。Forward auth (domain level) 使用单个 provider 保护同一父域名下的所有应用,但代价是无法配置按应用区分的授权规则。Traefik 位于前端时,应选择 forward auth (single application)。如果需要一个具体应用进行实践,可以先使用 自托管的 AFFiNE 工作区。这类内部工具通常只应允许您自己的设备访问,而不应暴露给其他来源。团队工具更能体现这一点:将 自托管的 Chatwoot 客服工作台 放在同一个 provider 后面,所有处理收件箱的人员每天只需登录一次,无需再共享一个密码。
在 Web 界面中,打开 Applications,然后打开 Providers,创建一个 Proxy Provider,选择 forward auth single application 模式,并将外部主机设置为 https://app.example.com。创建一个指向该 provider 的 Application。然后打开 Outposts,编辑 authentik Embedded Outpost,并将新应用加入其 selected applications。outpost 只会处理已分配给它的应用。因此,跳过最后一步会导致 provider 配置正确,但仍不返回任何内容。
在 Authentik 容器上定义一次 middleware,然后让每个受保护的应用引用它:
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-entitlements,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 进行自动登录的功能都会保持未登录状态。在保留自身登录状态的应用前面,这个问题最明显。例如 自托管的 openGym 健身追踪器 使用 passkey 登录时,这些请求头决定同一页面需要一次提示还是两次提示。
受保护的应用本身需要 2 个 router,而不是 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第二个 router 是最容易遗漏的部分。登录后,Authentik 会将浏览器返回到 应用主机名下 /outpost.goauthentik.io/ 中的路径,而不是返回到 auth.example.com。如果没有 router 将此前缀路径转发到 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 dashboard,确认路由列出了该中间件。
成功登录后 Authentik 返回 403。用户已通过身份验证,但未获授权:应用配置了该用户不满足的策略绑定或组要求。管理界面的 Events 日志会指出拒绝请求的策略。
Keycloak 更适合的场景
Keycloak 是由 Red Hat 支持的老牌项目,更适合经典的企业级身份管理场景:复杂的 SAML 联合身份认证,同时代理来自多个外部身份提供商的登录,以及将 realm 导出和导入作为有文档记录的迁移路径。对一些组织而言,背后的商业支持在正式评估中也很重要。代价是 Keycloak 没有自带代理,因此如果要保护不支持 OIDC(OpenID Connect)或 SAML 的应用,就需要在旁边运行类似 oauth2-proxy 的组件。Authentik 内置的代理提供商正好承担这一职责,并且已经完成集成,这也是大多数运行多种应用的自托管用户最终选择 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 一起保存。转储文件不包含 AUTHENTIK_SECRET_KEY 的副本,而使用不同的密钥恢复会使所有活动会话失效,因此保留原密钥可以让恢复后的服务器继续保持原来的状态。
升级通过更改标签完成。在 .env 中将 AUTHENTIK_TAG 设置为目标版本,然后依次运行 docker compose pull 和 docker compose up -d。如果从未设置 AUTHENTIK_TAG,版本就会使用 compose.yml 文件中写入的默认值。因此,下载该文件的新版本即可完成升级,这也是官方升级文档描述的方法。请先阅读发行说明。Authentik 使用基于日期的版本号。截至 October 2026,其文档要求升级时按主版本顺序进行:先升级到当前系列的最新补丁版本,然后依次经过之后的每个系列,不得跳过任何系列。Authentik 不支持降级,因此应在 pull 之前创建数据库转储,而不是之后。
FAQ
Authentik 可以免费自托管吗?
开源版本可免费使用,并涵盖上述全部功能:代理提供程序、forward auth、OIDC(OpenID Connect)、SAML 和 flows engine。付费企业级别会增加支持服务和部分企业功能,但本文中的配置不需要许可证。
使用 Authentik 是否必须安装 Traefik?
不需要。nginx 可通过 auth_request 使用 forward auth,Caddy 可通过 forward_auth 使用。每种情况下的模式都相同:反向代理针对每个请求向 Authentik 查询,受保护主机名上的路径前缀 /outpost.goauthentik.io/ 必须路由到 Authentik,而不是应用。
为什么受保护的应用会在登录和错误页面之间无限循环?
代理提供程序中配置的外部主机名与浏览器使用的 URL 不匹配,最常见的是 http 与 https 不一致。会话 Cookie 为一个源签发,却从另一个源读取,因此 Authentik 每次都会将请求视为匿名请求。修正外部主机名,然后清除这两个主机名对应的 Cookie,再次测试。
Authentik 需要多少 RAM?
截至 October 2026,文档规定的最低配置是 2 个 CPU 核心和 2 GB RAM,供 PostgreSQL、server 和 worker 共同使用。在 2 GB 主机上,内存压力可能唤醒内核的 OOM killer。它会终止 badness score 最高的进程:该分数大致等于进程使用的允许内存占比,再加上其 oom_score_adj。如果最终终止的是 worker,表现为后台任务和外发邮件停止,而登录页面仍可正常工作。如果同一台服务器还运行受保护的应用,请配置 4 GB RAM。