SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-28

Authentik 自托管 SSO:Docker Compose 与 Traefik 配置

使用 Docker Compose 部署 Authentik,实现所有应用共用一个登录入口。本文说明关键环境变量、akadmin 初始化,以及通过 Traefik forward auth 保护现有应用。

托管的每个应用使用一个登录入口

Authentik 是一个自托管 SSO(单点登录)服务器:用户只需登录一次,后端的每个应用都会接受该会话,不再要求用户为每个应用单独设置密码。安装过程使用官方 Docker Compose 文件和两个生成的密钥。真正需要仔细配置的是后续步骤:将反向代理指向 Authentik,并通过 forward auth 为一个现有应用启用统一认证。

Authentik 在该 Compose 文件中以 3 个服务运行: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 -d

docker compose ps 应列出 3 个容器,其中 postgresql 应报告 healthyserver 应报告 worker,且 running 应报告 running。首次启动会执行数据库迁移,因此请等待 1 分钟后再访问 Web 界面。

这两个生成的值都很重要,但原因不同。PG_PASS 是 PostgreSQL 密码,长度上限为 99 个字符。AUTHENTIK_SECRET_KEY 用于签名会话和令牌,因此之后更改它会使所有用户退出登录,并使已签发的所有 API 令牌失效。将 .env 的权限保持为 600,并将其副本保存到安全位置,因为恢复数据库时如果没有匹配的密钥,任何人都无法登录该数据库。

Compose 文件使用 ${PG_PASS:?database password 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_EMAILAUTHENTIK_BOOTSTRAP_TOKEN 会以相同方式设置该用户的地址和 API 令牌。
  • COMPOSE_PORT_HTTPCOMPOSE_PORT_HTTPS 会将对外发布的端口从默认值 9000 和 9443 改为其他端口。
  • AUTHENTIK_EMAIL__HOSTAUTHENTIK_EMAIL__PORTAUTHENTIK_EMAIL__USERNAMEAUTHENTIK_EMAIL__PASSWORDAUTHENTIK_EMAIL__USE_TLSAUTHENTIK_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 保留为紧急备用账户,并将一个足够长的密码离线保存。日常工作使用共享的内置账户会破坏审计日志,因为每个事件都显示为 akadmin,无法表明实际操作人员。这个问题也会延伸到 Authentik 下游的系统:例如 为每个人提供独立代理的自托管 OneCLI harness,只有在接收的身份对应一名具体用户,而不是全团队共享的登录账户时,才能留下清晰可读的操作记录。

将 Authentik 放在反向代理之后

将端口 9000 发布到互联网可以工作,但您还需要 TLS(传输层安全)和一个真实的主机名。如果您已经按照使用 Traefik 作为多个 Compose 应用的反向代理中的配置运行,请使用覆盖文件将 Authentik 加入同一个外部 proxy 网络。在 compose.yml 旁创建 docker-compose.override.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)。如果您需要一个具体应用进行实践,可以先选择 自托管 AFFiNE 工作区。这类内部工具通常只应允许您自己的设备访问,而不应暴露给其他来源。团队工具更能体现这一点:将 自托管 Chatwoot 客服工作台 放在同一个提供程序后面后,所有处理收件箱的人员每天只需登录一次,不必再共享一个密码。

在 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-version

authResponseHeaders 是 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 路由,或者该路由的优先级低于此主机的 catch-all 路由。

应用加载后始终不要求登录。middlewares 标签引用了不存在的中间件。Traefik 不会对此发出警告,因此 authentik@docker 中的拼写错误只会导致没有中间件运行。打开 Traefik 控制面板,确认路由列出了该中间件。

成功登录后 Authentik 返回 403。用户已通过身份验证,但未获得授权:应用配置了该用户不满足的策略绑定或组要求。管理界面的 Events 日志会显示拒绝请求的策略。

Keycloak 更适合的情况

Keycloak 是较早的项目,由 Red Hat 提供支持。对于经典的企业身份管理场景,它通常是更强的选择,例如复杂的 SAML 联邦、同时代理来自多个外部身份提供商的登录,以及将 realm 导出和导入作为有文档说明的迁移路径。对部分组织而言,Keycloak 背后的商业支持在正式评估中也很重要。代价是 Keycloak 没有自带代理。要保护不支持 OIDC(OpenID Connect)的应用,就需要在旁边运行类似 oauth2-proxy 的组件。Authentik 内置的 proxy provider 已经集成了这部分功能,这也是大多数同时运行多种应用的自托管用户最终选择它的原因。

备份与升级

还原需要以下三项: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 pulldocker compose up -d。先阅读版本说明,因为 Authentik 使用基于日期的版本号,某些版本包含迁移操作,要求从前一个版本升级到该版本。应在 pull 之前创建数据库转储,而不是之后。

FAQ

Authentik 可免费自行托管吗?

开源版免费,包含上述全部功能:代理提供程序、Forward Auth、OIDC(OpenID Connect)、SAML 和流程引擎。付费企业版增加支持服务和部分企业功能,但本文介绍的内容都不需要许可证。

使用 Authentik 必须安装 Traefik 吗?

不需要。通过 auth_request,Forward Auth 可与 nginx 配合使用;通过 forward_auth,也可与 Caddy 配合使用。每种情况下的模式相同:反向代理针对每个请求向 Authentik 发起验证,受保护主机名下的路径前缀 /outpost.goauthentik.io/ 必须路由到 Authentik,而不是应用。

为什么受保护的应用会在登录页和错误页之间无限跳转?

代理提供程序中配置的外部主机名与浏览器使用的 URL 不匹配,最常见的情况是 httphttps 不一致。会话 cookie 针对一个源签发,却在另一个源读取,因此 Authentik 每次看到的都是匿名请求。修正外部主机名,然后清除这两个主机名对应的 cookie,再次测试。

Authentik 需要多少 RAM?

截至 2026 年 7 月,文档规定的最低配置是 2 个 CPU 核心和 2 GB RAM,涵盖 PostgreSQL、server 和 worker。内存只有 2 GB 的主机在内存压力下,worker 会首先被内核终止;表现为后台任务和外发邮件停止,但登录页面仍可正常工作。如果同一台服务器还运行受保护的应用,请提供 4 GB RAM。