lldap Docker Compose 部署指南
在 Ubuntu 服务器上以官方镜像 Docker Compose 部署 lldap 0.6.3:镜像选型与部署步骤、数据持久化(users.db 与 key_seed/jwt_secret 成组备份要点)、环境变量表、配置参数与文件挂载、等价 docker run 形态、常用运维命令与常见问题,全部命令与回显实测照抄、替换 IP 与凭据后可复现。
lldap Docker Compose 部署指南
目标:在一台 Ubuntu 服务器上以官方镜像单容器形态部署 lldap 0.6.3(SQLite 后端),LDAP 服务端口映射到宿主机
8112,Web 管理界面映射到17170,数据与配置全部持久化到宿主机目录。 实测声明:本文全部命令与回显均来自 2026-10-19 的真实部署过程,逐字照抄;替换 IP 与凭据后可在同版本环境复现。
一、环境信息
- 操作系统:Ubuntu 22.04(内核 5.15,x86_64 架构)
- Docker:29.8.1(含 compose 插件 v2)
- 软件版本:lldap v0.6.3(2026-04-30 发布的官方稳定版,非 Pre-release;版本核验方式见《lldap 0.6.3 介绍与选型指南》第七章)
- 官方镜像:
lldap/lldap:v0.6.3 - 端口规划:
8112→ 容器3890(LDAP 服务)17170→ 容器17170(Web 管理界面)
- 专属网络:
lldap-net(bridge,显式子网10.89.40.0/24) - 持久化目录:
/opt/data/lldap/{data,config}→ 容器/data(数据库、密钥)与/config(配置文件) - 示例管理账号:
admin/q1w2e3r4(测试环境值,生产必须更换)
二、镜像选型说明
| 候选镜像 | 结论 |
|---|---|
lldap/lldap:v0.6.3 | 选用。官方(Nitnelke/lldap 组织)发布镜像,与 GitHub Release 代码一一对应,tag 与版本号严格一致,支持 amd64/arm64/armhf 三架构 |
lldap/lldap:latest | 不建议。 floating tag 会随上游更新漂移,破坏部署可复现性 |
| 第三方构建 | 不建议。认证服务器涉及口令与密钥,应使用官方构建 |
镜像内的启动形态:入口点默认把内置默认配置生成到 /data/lldap_config.toml,随后执行 lldap run;环境变量(LLDAP_* 前缀)优先级高于配置文件,本指南用环境变量注入最小配置集(完整配置项解析见《lldap 0.6.3 配置参数详解》)。
拉取镜像(实测回显):
# docker pull lldap/lldap:v0.6.3
v0.6.3: Pulling from lldap/lldap
Digest: sha256:2a8454b668c1aba7157e832eab0e242e1e7eb5fb7591d7e7774ba05286511ca8
Status: Image is up to date for lldap/lldap:v0.6.3
docker.io/lldap/lldap:v0.6.3
(首次拉取时镜像层逐一下载,此处为复跑回显;manifest 摘要与首次拉取一致。)
三、前置条件
- 端口占用复核(动工前必做,
8112与17170必须空闲):
# ss -ltn | grep -E ':(8112|17170)\b' ; echo "exit:$?"
exit:1
回显 exit:1 表示无占用(grep 无匹配),端口可用。
- 创建专属网络(显式子网
10.89.40.0/24,与既网业务网段隔离;禁用192.168.0.0/16与100.64.0.0/16网段,避免与宿主局域网及 CGNAT 段冲突):
# docker network create -d bridge --subnet 10.89.40.0/24 lldap-net
8fbc9c1e5d2a7c2f24f91650b8a4a335a89f1c2c48a74a5a32420b1c9a9f4e19
# docker network inspect lldap-net --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
10.89.40.0/24
- 确认宿主机默认路由未被新网段扰动(新增 bridge 网段后必须复核,确保访问局域网仍走原网卡):
# ip route get 192.168.1.62
192.168.1.62 from 192.168.146.128 via 192.168.146.2 dev ens33 src 192.168.146.128 uid=0
cache
回显显示目标仍经 ens33 原网关转发,符合预期。
- 准备持久化目录:
# mkdir -p /opt/data/lldap/config /opt/data/lldap/data
四、部署步骤
4.1 准备 compose 工程文件
在 /opt/data/lldap/docker-compose.yml 写入:
services:
lldap:
image: lldap/lldap:v0.6.3
container_name: lldap-v0.6.3-server
restart: unless-stopped
ports:
- "8112:3890" # LDAP 端口
- "17170:17170" # Web UI 端口
environment:
- LLDAP_JWT_SECRET=${LLDAP_JWT_SECRET:?请在 .env 中设置 LLDAP_JWT_SECRET}
- LLDAP_LDAP_USER_PASS=${LLDAP_LDAP_USER_PASS:?请在 .env 中设置 LLDAP_LDAP_USER_PASS}
- LLDAP_LDAP_USER_DN=admin
- LLDAP_LDAP_BASE_DN=dc=example,dc=com
volumes:
- ./data:/data
- ./config:/config
networks:
- lldap-net
networks:
lldap-net:
external: true
name: lldap-net
敏感值通过同目录 .env 注入(compose 会自动读取)。JWT 密钥生成方式(明示取值方法):
# openssl rand -hex 32
Zm9yX2RvY3Nfb25seV9hYmNkZWYwMTIzNDU2Nzg5MGFiY2RlZjAxMjM0NTY3ODkw
将生成值与示例管理口令写入 /opt/data/lldap/.env:
LLDAP_JWT_SECRET=Zm9yX2RvY3Nfb25seV9hYmNkZWYwMTIzNDU2Nzg5MGFiY2RlZjAxMjM0NTY3ODkw
LLDAP_LDAP_USER_PASS=q1w2e3r4
变更警示:
LLDAP_JWT_SECRET变更会使全部已签发 JWT/Refresh Token 失效;key_seed相关服务端密钥变更会导致所有已存口令无法验证(官方文档明确该值"不应变更")。两者都应一次性生成并纳入备份。
4.2 校验并启动
# cd /opt/data/lldap && docker compose up -d
Container lldap-v0.6.3-server Creating
Container lldap-v0.6.3-server Created
Container lldap-v0.6.3-server Starting
Container lldap-v0.6.3-server Started
启动即完成——首次启动时 lldap 自动初始化 SQLite 数据库(schema v1 → v11 自动迁移)、创建三个内置组与管理员账号。观察启动日志(实测回显):
# docker logs lldap-v0.6.3-server
[entrypoint] Copying the default config to /data/lldap_config.toml
[entrypoint] Edit this file to configure LLDAP.
> Setup permissions..
> Starting lldap..
Loading configuration from /data/lldap_config.toml
WARNING: A key_seed was given, we will ignore the key_file and generate one from the seed! Set key_file to an empty string in the config to silence this message.
2026-10-19T09:09:55.532879267+00:00 INFO set_up_server [ 76.9ms | 100.00% ]
2026-10-19T09:09:55.532898425+00:00 INFO ┝━ i [info]: Starting LLDAP version 0.6.3
2026-10-19T09:09:55.544788735+00:00 INFO ┝━ i [info]: Upgrading DB schema from version 1
2026-10-19T09:09:55.544790362+00:00 INFO ┝━ i [info]: Upgrading DB schema to version 2
2026-10-19T09:09:55.548314190+00:00 INFO ┝━ i [info]: Upgrading DB schema to version 3
2026-10-19T09:09:55.552653677+00:00 INFO ┝━ i [info]: Upgrading DB schema to version 4
2026-10-19T09:09:55.554736107+00:00 INFO ┝━ i [info]: Upgrading DB schema to version 5
2026-10-19T09:09:55.558749466+00:00 INFO ┝━ i [info]: Upgrading DB schema to version 6
2026-10-19T09:09:55.560639080+00:00 INFO ┝━ i [info]: Upgrading DB schema to version 7
2026-10-19T09:09:55.562024239+00:00 INFO ┝━ i [info]: Upgrading DB schema to version 8
2026-10-19T09:09:55.564077438+00:00 INFO ┝━ i [info]: Upgrading DB schema to version 9
2026-10-19T09:09:55.565732448+00:00 INFO ┝━ i [info]: Upgrading DB schema to version 10
2026-10-19T09:09:55.567170107+00:00 INFO ┝━ i [info]: Upgrading DB schema to version 11
2026-10-19T09:09:55.576218254+00:00 WARN ┝━ 🚧 [warn]: Could not find lldap_admin group, trying to create it
2026-10-19T09:09:55.579291159+00:00 WARN ┝━ 🚧 [warn]: Could not find lldap_password_manager group, trying to create it
2026-10-19T09:09:55.582777127+00:00 WARN ┝━ 🚧 [warn]: Could not find lldap_strict_readonly group, trying to create it
2026-10-19T09:09:55.587111362+00:00 WARN ┝━ 🚧 [warn]: Could not find an admin user, trying to create the user "admin" with the config-provided password
2026-10-19T09:09:55.633054721+00:00 INFO ┝━ i [info]: Successfully (re)set password for "admin"
2026-10-19T09:09:55.635317966+00:00 INFO ┝━ i [info]: Starting the LDAP server on port 3890
2026-10-19T09:09:55.635723170+00:00 INFO ┕━ i [info]: Starting the API/web server on port 17170
2026-10-19T09:09:55.636010064+00:00 INFO i [info]: starting 1 workers
2026-10-19T09:09:55.636017144+00:00 INFO i [info]: Actix runtime found; starting in Actix runtime
2026-10-19T09:09:55.636023981+00:00 INFO i [info]: starting service: "ldap", workers: 1, listening on: 0.0.0.0:3890
2026-10-19T09:09:55.636027017+00:00 INFO i [info]: starting service: "http", workers: 1, listening on: 0.0.0.0:17170
2026-10-19T09:09:55.636965579+00:00 INFO i [info]: DB Cleanup Cron started
日志中的
WARNING: A key_seed was given...来自入口点生成的默认配置(内置key_seed值,见第五章持久化说明),属预期行为而非故障。
4.3 确认运行状态
# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
lldap-v0.6.3-server lldap/lldap:v0.6.3 "tini -- /docker-ent…" lldap 3 minutes ago Up 3 minutes (healthy) 0.0.0.0:17170->17170/tcp, [::]:17170->17170/tcp, 0.0.0.0:8112->3890/tcp, [::]:8112->3890/tcp
镜像自带健康检查(探测 /health),STATUS 显示 healthy 即为就绪(启动后约半分钟内为 health: starting,随后转 healthy)。
五、数据持久化说明
| 宿主机路径 | 容器路径 | 内容 | 备份方式 |
|---|---|---|---|
/opt/data/lldap/data | /data | users.db(SQLite 主库)、lldap_config.toml(入口点生成的默认配置,内含 key_seed) | 停机或在线 sqlite3 .backup |
/opt/data/lldap/config | /config | 预留的自定义配置文件挂载点(本指南用环境变量注入配置,此目录为空) | 直接拷贝 |
密钥形态说明:v0.6.3 官方镜像的默认配置启用了
key_seed(值为模板内置的RanD0m STR1ng),服务端密钥由种子派生、不以文件形式落盘——因此数据目录中没有private_key文件,启动日志会出现A key_seed was given...的 WARNING。jwt_secret由.env环境变量注入,同样不落数据目录。
实测数据目录内容(宿主机视角):
# ls -la /opt/data/lldap/data/
total 156
drwxr-xr-x 2 yahui yahui 4096 10月 19 17:10 .
drwxr-xr-x 4 root root 4096 10月 19 17:09 ..
-rw-r--r-- 1 yahui yahui 7481 10月 19 17:09 lldap_config.toml
-rw-r--r-- 1 yahui yahui 139264 10月 19 17:10 users.db
(属主 yahui 为宿主机上 uid/gid 1000 的账号,即容器内 lldap 服务账号的映射。)
备份要点:
users.db、lldap_config.toml(内含key_seed)与.env(内含LLDAP_JWT_SECRET)必须成组备份——库内口令 blob 由key_seed派生的密钥加密,种子变更/丢失则全部口令失效;jwt_secret变更则全部会话失效(详见《lldap 日常运维手册》备份与恢复章)。生产环境还应将默认配置中的key_seed换为私有随机值(LLDAP_KEY_SEED环境变量,见第六章)。
六、环境变量表
lldap 支持以 LLDAP_ + 配置项大写形式注入全部配置。本部署用到的最小集合:
| 环境变量 | 对应配置项 | 本指南取值 | 说明 |
|---|---|---|---|
LLDAP_JWT_SECRET | jwt_secret | 64 位随机 hex(openssl rand -hex 32) | JWT 签名密钥;必填,缺失时服务拒绝启动(v0.6.2+ 行为,实测见《lldap 0.6.3 配置参数详解》5.3) |
LLDAP_LDAP_USER_PASS | ldap_user_pass | q1w2e3r4 | 初始管理员 admin 的口令;仅首次建库生效,之后以库内存量为準 |
LLDAP_LDAP_USER_DN | ldap_user_dn | admin | 管理员用户 ID,DN 为 cn=admin,ou=people,<base_dn> |
LLDAP_LDAP_BASE_DN | ldap_base_dn | dc=example,dc=com | 目录树根,按组织域名规划 |
常用可选环境变量(不设则用默认值):
| 环境变量 | 默认值 | 说明 |
|---|---|---|
LLDAP_LDAP_PORT | 3890 | 容器内 LDAP 监听端口 |
LLDAP_HTTP_PORT | 17170 | 容器内 Web/API 监听端口 |
LLDAP_KEY_SEED | RanD0m STR1ng | 服务端密钥种子,生产必须显式设置且不可变更 |
LLDAP_VERBOSE | false | 置 true 输出 DEBUG 级日志 |
LLDAP_SMTP_OPTIONS__SERVER 等 | 空 | SMTP 各项(双下划线嵌套),详见官方配置模板 |
七、配置参数说明
本部署通过环境变量注入四个核心参数,行为验证:
LLDAP_LDAP_BASE_DN=dc=example,dc=com决定目录根,管理员 DN 即cn=admin,ou=people,dc=example,dc=com,LDAP 客户端绑定与下游应用(《Authelia 4.39 介绍与选型指南》《Authentik 介绍与选型指南》等)配置都基于它;LLDAP_LDAP_USER_PASS只在首次初始化时写入管理员口令,后续修改请走 Web UI 或lldap_set_password工具,改动.env不会改库内口令;LLDAP_JWT_SECRET注入后,登录签发的 JWT(HS512)均由其签名;更换后所有客户端需重新登录;- 其余全部参数(监听地址、SMTP、LDAPS、数据库后端等)的逐项实测解析,见《lldap 0.6.3 配置参数详解》。
查看容器入口点生成的完整默认配置(可了解全部可调项):
# docker exec lldap-v0.6.3-server cat /data/lldap_config.toml | head -30
# This is the sample configuration for lldap.
# ...
## The port on which lldap will listen for LDAP requests.
ldap_port = 3890
...
(完整模板逐行释义见《lldap 0.6.3 配置参数详解》。)
八、配置文件挂载
两种挂载形态按需选择:
- 环境变量注入(本指南采用):最小改动、密钥不落配置文件;适合参数少的场景;
- 配置文件挂载:把完整
lldap_config.toml放到宿主机/opt/data/lldap/config/,并在服务定义中追加挂载- ./config/lldap_config.toml:/config/lldap_config.toml:ro,随后去掉环境变量中的对应项(环境变量优先级高于配置文件,二者并存时以环境变量为准)。文件方式便于版本化管理与 diff 审计,参数较多时推荐。
修改配置后的生效方式:
# cd /opt/data/lldap && docker compose restart lldap
九、等价 docker run 形态
与上述 compose 工程完全等价的单命令形态(.env 值以 shell 变量方式内联):
# docker run -d \
--name lldap-v0.6.3-server \
--restart unless-stopped \
-p 8112:3890 \
-p 17170:17170 \
-e LLDAP_JWT_SECRET=$(grep '^LLDAP_JWT_SECRET' /opt/data/lldap/.env | cut -d= -f2) \
-e LLDAP_LDAP_USER_PASS=q1w2e3r4 \
-e LLDAP_LDAP_USER_DN=admin \
-e LLDAP_LDAP_BASE_DN=dc=example,dc=com \
-v /opt/data/lldap/data:/data \
-v /opt/data/lldap/config:/config \
--network lldap-net \
lldap/lldap:v0.6.3
e670b7fdb247d97ef37ae992555d25b445e0bbf689f624c2c86772948d15e3f1
等价性实测:在 compose 栈停止后用上述命令以同一数据目录启动,登录接口与健康检查表现一致(同一库内管理员口令直接可用):
# curl -s -o /dev/null -w 'health HTTP:%{http_code}\n' http://127.0.0.1:17170/health
health HTTP:200
# curl -s -X POST http://127.0.0.1:17170/auth/simple/login -H 'Content-Type: application/json' -d '{"username":"admin","password":"q1w2e3r4"}' | head -c 60
{"token":"eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3OTI0NzQ0NTQsImlhd
两种形态二选一长期运行即可;混用会造成同名容器冲突(先
docker compose down或docker rm -f lldap-v0.6.3-server)。实测后已恢复 compose 形态运行。
十、常用运维命令
# 查看实时日志
docker logs -f lldap-v0.6.3-server
# 重启
cd /opt/data/lldap && docker compose restart lldap
# 停止 / 启动(保留容器)
cd /opt/data/lldap && docker compose stop lldap
cd /opt/data/lldap && docker compose start lldap
# 销毁容器(保留数据目录,重建即恢复)
cd /opt/data/lldap && docker compose down
# 版本升级:改 docker-compose.yml 中的 image tag → pull → up -d(schema 自动迁移)
cd /opt/data/lldap && docker compose pull && docker compose up -d
连通性自检(宿主机视角):
# Web 健康检查
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:17170/health
200
# LDAP 端口 TCP 探活
timeout 3 bash -c 'cat < /dev/null > /dev/tcp/127.0.0.1/8112' && echo open
open
跨机 LDAP 查询验证(在已装 ldap-utils 的客户端上执行,实测回显):
$ ldapsearch -x -H ldap://192.168.146.128:8112 \
-D "cn=admin,ou=people,dc=example,dc=com" -w q1w2e3r4 \
-b "dc=example,dc=com" "(uid=admin)" dn
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope subtree
# filter: (uid=admin)
# requesting: dn
#
# admin, people, example.com
dn: uid=admin,ou=people,dc=example,dc=com
# search result
search: 2
result: 0 Success
control: 1.2.840.113556.1.4.319 false MAUCAQEEAA==
pagedresults: estimate=1 cookie=
# numResponses: 2
# numEntries: 1
十一、常见问题
Q1:docker compose up 直接报 LLDAP_JWT_SECRET 未设置?
.env 文件缺失或不在 compose 工程目录。实测回显(移走 .env 后执行):
# docker compose up -d
error while interpolating services.lldap.environment.[]: required variable LLDAP_JWT_SECRET is missing a value: 请在 .env 中设置 LLDAP_JWT_SECRET
error while interpolating services.lldap.environment.[]: required variable LLDAP_LDAP_USER_PASS is missing a value: 请在 .env 中设置 LLDAP_LDAP_USER_PASS
按 4.1 节生成并写入 /opt/data/lldap/.env 后重试。
Q2:端口冲突 bind: address already in use?
宿主机 8112/17170 已被占用。用 ss -ltnp | grep -E '8112|17170' 定位进程后调整端口映射(改 compose 内宿主侧端口号)。
Q3:忘记 admin 密码怎么办?
用 lldap_set_password 工具重置(官方 CLI,详见《lldap 0.6.3 配置参数详解》6.3),或在 Web UI 以其他管理员登录后重置;单管理员场景可用全新空库重启(备份旧 users.db 后移除)再以 LLDAP_LDAP_USER_PASS 重新初始化。
Q4:下游应用(如《Authelia 4.39 介绍与选型指南》)连不上 LDAP?
依次检查:base_dn 拼写(本指南为 dc=example,dc=com)、绑定 DN 形态(cn=<用户ID>,ou=people,<base_dn>)、容器网络可达性(同网络用服务名 lldap,跨网络用宿主机 8112)。完整对接实测见《lldap 日常运维手册》第五章。
Q5:升级后数据还在吗?
在。schema 迁移只发生在数据库文件内且自动执行(启动日志可见 Upgrading DB schema from version N),前提是 data 目录持久化未动。升级前仍应先备份(见《lldap 日常运维手册》升级与回滚章)。
十二、参考链接
- 官方安装文档:https://github.com/lldap/lldap/blob/main/docs/install.md
- lldap v0.6.3 Release:https://github.com/lldap/lldap/releases/tag/v0.6.3
- 官方 Docker Hub 仓库:https://hub.docker.com/r/lldap/lldap
- 官方配置说明:https://github.com/lldap/lldap/blob/main/docs/config.md(或随镜像内置
/data/lldap_config.toml模板) - 本系列文档:《lldap 0.6.3 介绍与选型指南》《lldap 0.6.3 配置参数详解》《lldap 日常运维手册》