自托管 Authentik 做 SSO(2026):Docker-compose 栈 + 第一个集成

Authentik 是开源的身份提供商(IdP)。在你的应用和用户中间做中介,
一个二进制说 OIDC、SAML、LDAP、SCIM、RADIUS、以及 proxy-outpost forward-auth。
截至本文撰写时,当前发布线是 2026.5.x(最新 tag 是 2026.5.4,
2026-07-08 发布),3 个月一个版本,Calendar versioning(年份.月份.补丁号)。

和其他常见自托管 SSO 方案的关系:Authentik 在 Authelia(轻量 proxy)和
Keycloak(企业 Java 栈)之间——UI 现代、对开发者友好、API 完整。

一段为什么用 Authentik

过去 5 年,自托管用户的 SSO 选项基本是这三个:

  • Authelia——单容器 reverse-proxy 前置过滤器。快、轻、但只做 forward-auth
    和 OIDC,要深度用户管理 / 复杂应用集成时空间不够。
  • Keycloak——功能完整 + 完整 SAML/OIDC/LDAP 支持。代价是 Java + 一坨
    概念(realm/client/role/permission 五层抽象),UI 写给 IdM 工程师。
  • Authentik——现代化的中间位置。API 优先 + JSON-based 配置 + 漂亮的
    Lit 单页应用 UI。Postgres 后端,~70MB 镜像做出来很轻量。

2026 年的实际差异(按 GoAuthentik 团队在 2026.5 release post 写的):

  • 单一应用连接一个 user,而不是一个应用连一个 client secret。Application +
    Provider 模型更接近现实。
  • 所有配置都在 API 里,每个 admin 面板动作都是一个 REST 调用。Terraform /
    Pulumi provider 是一等公民。
  • 完整 SCIM、proxy outpost、forward auth,都在一个 docker-compose 栈里
    出厂就有。

部署——2026.5.x 的官方 docker-compose

这是 2026.5 系列的官方 docker-compose.yml(基本来自 gen-postgres 那个
官方蓝本);已经不需要 Redis 了——2025.10 之后所有缓存/任务队列/WebSocket
迁到 Postgres:

Yaml
services:
  postgresql:
    image: docker.io/library/postgres:16-alpine
    env_file:
      - .env
    environment:
      POSTGRES_DB: ${PG_DB:-authentik}
      POSTGRES_USER: ${PG_USER:-authentik}
      POSTGRES_PASSWORD: ${PG_PASS:?database password required}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${PG_USER}"]
      interval: 5s
      timeout: 5s
      retries: 5
    volumes:
      - database:/var/lib/postgresql/data
    networks:
      - authentik-net
    restart: unless-stopped

  server:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.5.4}
    command: server
    depends_on:
      postgresql:
        condition: service_healthy
    env_file:
      - .env
    environment:
      AUTHENTIK_POSTGRESQL__HOST: postgresql
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
    ports:
      - "${AUTHENTIK_PORT_HTTP:-9000}:9000"
    volumes:
      - ./media:/media
      - ./custom-templates:/templates
    networks:
      - authentik-net
    restart: unless-stopped

  worker:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.5.4}
    command: worker
    depends_on:
      postgresql:
        condition: service_healthy
    env_file:
      - .env
    environment:
      AUTHENTIK_POSTGRESQL__HOST: postgresql
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock   # manage outposts
      - ./media:/media
      - ./custom-templates:/templates
    networks:
      - authentik-net
    restart: unless-stopped

networks:
  authentik-net:
    driver: bridge

volumes:
  database:

.env 最低需要:

Bash
PG_USER=authentik
PG_PASS=__________
AUTHENTIK_SECRET_KEY=<openssl rand -hex 32>
AUTHENTIK_TAG=2026.5.4
AUTHENTIK_PORT_HTTP=9000

注意:latest container tag 在 2025.2 被弃用了,现在冻结了——必须
pin 到具体版本
(这里是 2026.5.4)。

Postgres 是唯一支持的数据库——Authentik 重度依赖 PG-specific 特性
pgtriggerpglock、JSONB 函数),不打算支持 MySQL。

首次启动

docker compose up -d 后,打开 <your-server>:9000/if/flow/initial-setup/
斜杠别忘了——不带斜杠直接 404)。

第一次访问浏览器会跑内置的 initial-setup Flow,让你给默认 akadmin 用户
设密码(外加 email/username)。这个用户自动获得 superuser 权限。

之后:

  1. 用 akadmin 登入
  2. 至少创建一个非 superuser 的 user
  3. 跑 Application wizard,创建第一个 Application(它会同时创建绑定的
    Application 和 Provider)

需要非交互式安装(Terraform / Helm / IaC)的话,用环境变量:

Bash
AUTHENTIK_BOOTSTRAP_EMAIL=admin@example.com
AUTHENTIK_BOOTSTRAP_PASSWORD=_________   # 或 AUTHENTIK_BOOTSTRAP_PASSWORD_HASH(2026.5 起)
AUTHENTIK_BOOTSTRAP_TOKEN=<用于 Terraform / blueprint runner 的 API token>
AUTHENTIK_BOOTSTRAP_LDAP_PASSWORD=<可选>

:bootstrap env vars 在没挂载蓝图时不生效(issue #7546,仍然 open)。
如果挂了一个空的 /blueprints 目录,会变成一个完全 bootstrap 但没 admin
用户的实例——别这么干,要么挂一份真的 blueprint,要么用浏览器流程。

给现有应用加 SSO

Authentik 的”应用”概念 = 一个 OAuth2/OIDC/SAML/LDAP provider + 它的元数据。
给一个支持 OIDC 的应用接 SSO(比如 Gitea、Grafana、Jellyfin、Nextcloud),
通常是这样的:

  1. Admin → Applications → Create with Provider (OIDC)
  2. 选 redirect URI(应用给的),Authentik 显示 client ID + secret
  3. 在应用那边粘上 Authentik 给的 URL:
    • Authorization: https://authentik.example.com/application/o/authorize/
    • Token: https://authentik.example.com/application/o/token/
    • Userinfo: https://authentik.example.com/application/o/userinfo/
  4. 第一次登录时,Authentik 提示用户接受 scope

Nextcloud 这边还有两个坑要小心:

  • Nextcloud 的 user_oidc app 对 client secret 长度有 64 字符限制
  • 要设 nextcloud_user_id + nextcloud_quota 这两个 user 属性 mapping

Grafana:环境变量 GF_AUTH_GENERIC_OAUTH_* 配,URL 用 https://authentik.example.com/application/o/authorize/ 等。

Jellyfin 用社区 OIDC 插件。GitLab 用 built-in OmniAuth OIDC。

一个集成示例:Grafana OIDC

最常见的 practical 集成。Grafana 支持 generic OIDC,Authentik 配合非常干净。

Authentik 侧

  1. Admin → Applications → Create
  2. Name: Grafana,Slug: grafana
  3. Provider type: OAuth2/OpenID
  4. Client type: Confidential
  5. Redirect URI: https://grafana.example.com/login/generic_oauth
  6. Copy Client ID + Client Secret

Grafana 侧grafana.ini):

Ini
[auth.generic_oauth]
enabled = true
name = Authentik
client_id = <from authentik>
client_secret = <from authentik>
scopes = openid email profile
auth_url = https://authentik.example.com/application/o/authorize/
token_url = https://authentik.example.com/application/o/token/
api_url = https://authentik.example.com/application/o/userinfo/

重启 Grafana,第一次登录会被重定向到 Authentik,做一次标准 OIDC 流程——
自动创建 Grafana user(如果之前不存在)。

Outpost:给 legacy 应用做 forward auth

传统应用没原生 OIDC 支持——直接代理 SSO 网关是 Authentik “Proxy outpost” 的
用途。Go 写的小二进制,跟 authentik server 交互,把未认证请求反向代理到
目标应用之前弹登录。

两种部署模式:

  • Forward auth(单应用)——outpost 当中间层,不光拦认证,也代理流量
  • Proxy mode(独立 process)——outpost 跑专用容器/进程,处理大流量

Server 容器自带 embedded outpost;如果要独立 outpost(K8s、跨主机的部署),
/var/run/docker.sock 挂上 worker 容器,worker 用 Docker API 起 outpost。

坑(2026 版)

  • :latest 不可用——2025.2 被冻结了,pin 到 2026.5.4 这种具体 tag。
  • 没有 Redis 了——2025.10 起全 Postgres。旧 compose 里 redis 容器可以
    docker compose up -d --remove-orphans 清掉(K8s 删 Redis PVC/PV)。
  • Postgres 是唯一——MySQL/SQLite 不支持。Authentik 用 PG-specific 特性
    重度,不是数据库无关层。
  • 首次设置 URL 末尾斜杠不能省——/if/flow/initial-setup/ 不带斜杠直
    接 404。
  • recovery key 60 分钟过期(2025.10 起,旧版本是几年)。忘了 akadmin
    密码要在服务器容器里跑 ak create_recovery_key 生成一次性 URL,60 分钟
    内必须用
  • *`AUTHENTIKBOOTSTRAP` 配 blueprint 才生效**——直接传这些 env vars 而
    没蓝图,结果是完整的实例但没 admin user(issue #7546,wontfix/legacy)。
  • Terraform provider 用户 OIDC 客户端 secret 长度 64 字符限制(Nextcloud
    user_oidc app 限制)。
  • /media/custom-templates 一定要挂上去——掉这两卷,全局 media
    文件和自定义登录页面会丢。
  • 3 个月 release 节奏——计划每次升级时跳一两个版本做迁移测试。UPGRADE.md
    每个版本都有,记得读。

升级

零停机升级流程:

Bash
# 1. 改 .env 里 AUTHENTIK_TAG 到新版本
sed -i 's/AUTHENTIK_TAG=2026.5.4/AUTHENTIK_TAG=2026.8.0/' .env

# 2. 拉新镜像
docker compose pull

# 3. 起新容器(server 先起,worker 后起)
docker compose up -d

Authentik 容器跑内置 schema migration;失败会自动回滚。但总有 reads 一下
UPGRADE.md
——版本之间偶尔有手动迁移步骤(极少但有)。

你应不应该用 Authentik

用的场景:

  • 你要给 3+ 个不同协议/不同语言的自托管应用加统一登录
  • 想要 Terraform / 配置即代码管理你的 IdP
  • 已经在用 Postgres
  • 想要现代 UI 给非技术 admin 用户用

不用的场景:

  • 有一个反向代理后面的应用——Authelia 一行 config 就行
  • 要 LDAP / Active Directory——OpenLDAP 或 samba 自带就行
  • 你需要托管 SAML/IdP 联邦给上万员工——Keycloak 或 Okta 是为这种量设计的

一句话总结

如果你 2026 年自托管,并且不只跑一两个服务,Authentik 是当前最对路的
self-hosted SSO 解决方案
。官方镜像在 ghcr.io/goauthentik/server
docker-compose.yml 用上面的模板就行,Postgres-only,3 个月 release 节奏,
pin 一个稳定版本能直接跑。

参考资料

最后修改: 2026年7月16日

作者

评论

发表评论

您的邮箱地址不会被公开。