docker-compose部署openldap时初始化数据的两种方式
# 前言
通常我们会通过 docker-compose 快速拉起一个 openLDAP 的测试环境用于一些功能的验证或调试,但是有一些基础数据,没必要总是反复创建,比如两个基础组织用户与分组,所以我就考虑如何能够将这两个创建做到容器启动的过程中。
# 常规步骤
常规情况下,我们会首先通过如下内容拉起一个 openLDAP 和 phpldapadmin:
version: "3"
networks:
go-ldap-admin:
driver: bridge
services:
openldap:
image: osixia/openldap:1.5.0
container_name: go-ldap-admin-openldap
hostname: go-ldap-admin-openldap
restart: always
environment:
TZ: Asia/Shanghai
LDAP_ORGANISATION: "eryajf.net"
LDAP_DOMAIN: "eryajf.net"
LDAP_ADMIN_PASSWORD: "123456"
volumes:
# - ./openldap/ldap/database:/var/lib/ldap # 如果需要的话,可以配置挂载持久化目录
# - ./openldap/ldap/config:/etc/ldap/slapd.d # 如果需要的话,可以配置挂载持久化目录
ports:
- 388:389
networks:
- go-ldap-admin
phpldapadmin:
image: osixia/phpldapadmin:0.9.0
container_name: go-ldap-admin-phpldapadmin
hostname: go-ldap-admin-phpldapadmin
restart: always
environment:
TZ: Asia/Shanghai # 设置容器时区与宿主机保持一致
PHPLDAPADMIN_HTTPS: "false" # 是否使用https
PHPLDAPADMIN_LDAP_HOSTS: go-ldap-admin-openldap # 指定LDAP容器名称
ports:
- 8090:80
volumes:
# - ./openldap/phpadmin:/var/www/phpldapadmin # 如果需要的话,可以配置挂载持久化目录
depends_on:
- openldap
links:
- openldap:go-ldap-admin-openldap # ldap容器的 service_name:container_name
networks:
- go-ldap-admin
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
容器都正常启动之后,我们可以通过如下命令创建这两个基础的组织。
进入容器:
$ docker exec -it ldap-service bash
执行命令:
cat << EOF | ldapadd -x -D "cn=admin,dc=eryajf,dc=net" -w 123456
dn: ou=People,dc=eryajf,dc=net
objectClass: organizationalUnit
ou: people
dn: ou=Group,dc=eryajf,dc=net
objectClass: organizationalUnit
ou: group
EOF
2
3
4
5
6
7
8
9
然后在 web 页面登陆就能看到两个基础组织了。
# 方案一:挂载初始化
当我打算将如上创建基础组织的步骤合并到容器启动过程中的时候,就来到了容器提供方的 github 寻找答案,也是在这里找到了两种解决方案。
第一种方案思路参考:https://github.com/osixia/docker-openldap/issues/320 (opens new window)
这种方案通过将自定义的 ldif 文件挂载到容器内,然后容器启动之后会执行这个文件。
首先创建好配置文件./openldap/config/init.ldif
的内容:
$ cat ./openldap/config/init.ldif
dn: ou=People,dc=eryajf,dc=net
objectClass: organizationalUnit
ou: people
dn: ou=Group,dc=eryajf,dc=net
objectClass: organizationalUnit
ou: group
2
3
4
5
6
7
8
9
然后将该配置挂载到容器中,并添加--copy-service
命令加载上边的 ldif 文件。
对应的docker-compose.yml
文件如下:
version: "3"
networks:
go-ldap-admin:
driver: bridge
services:
openldap:
image: osixia/openldap:1.5.0
container_name: go-ldap-admin-openldap
hostname: go-ldap-admin-openldap
restart: always
environment:
TZ: Asia/Shanghai
LDAP_ORGANISATION: "eryajf.net"
LDAP_DOMAIN: "eryajf.net"
LDAP_ADMIN_PASSWORD: "123456"
command: ["--copy-service"]
volumes:
# - ./openldap/ldap/database:/var/lib/ldap # 如果需要的话,可以配置挂载持久化目录
# - ./openldap/ldap/config:/etc/ldap/slapd.d # 如果需要的话,可以配置挂载持久化目录
- ./openldap/config:/container/service/slapd/assets/config/bootstrap/ldif/custom # 注意这里是目录挂载到目录
ports:
- 388:389
networks:
- go-ldap-admin
phpldapadmin:
image: osixia/phpldapadmin:0.9.0
container_name: go-ldap-admin-phpldapadmin
hostname: go-ldap-admin-phpldapadmin
restart: always
environment:
TZ: Asia/Shanghai # 设置容器时区与宿主机保持一致
PHPLDAPADMIN_HTTPS: "false" # 是否使用https
PHPLDAPADMIN_LDAP_HOSTS: go-ldap-admin-openldap # 指定LDAP容器名称
ports:
- 8090:80
volumes:
# - ./openldap/phpadmin:/var/www/phpldapadmin # 如果需要的话,可以配置挂载持久化目录
depends_on:
- openldap
links:
- openldap:go-ldap-admin-openldap # ldap容器的 service_name:container_name
networks:
- go-ldap-admin
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
openldap 容器启动之后会自动执行挂载进去的 ldif 文件,从而实现自动构建基础组织的效果。
比较推荐这个方案,不需要外部侵入,相对友好。
# 方案二:通过外置容器
第二种方案思路参考:https://github.com/osixia/docker-openldap/issues/20 (opens new window)
这种方案的思路是在 compose 文件中再声明一个外置容器,当 openldap 容器运行之后,外置的容器再来执行我们自定义的脚本。
首先创建脚本openldap/config/init.sh
内容如下:
$ cat openldap/config/init.sh
#!/usr/bin/env bash
echo "start init data"
sleep 10
cat << EOF | ldapadd -x -h openldap -D "cn=admin,dc=eryajf,dc=net" -w 123456
dn: ou=People,dc=eryajf,dc=net
objectClass: organizationalUnit
ou: people
dn: ou=Group,dc=eryajf,dc=net
objectClass: organizationalUnit
ou: group
EOF
echo "init data success"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
对应的docker-compose.yml
文件如下:
version: "3"
networks:
go-ldap-admin:
driver: bridge
services:
openldap:
image: osixia/openldap:1.5.0
container_name: go-ldap-admin-openldap
hostname: go-ldap-admin-openldap
restart: always
environment:
TZ: Asia/Shanghai
LDAP_ORGANISATION: "eryajf.net"
LDAP_DOMAIN: "eryajf.net"
LDAP_ADMIN_PASSWORD: "123456"
volumes:
- ./openldap/ldap/database:/var/lib/ldap
- ./openldap/ldap/config:/etc/ldap/slapd.d
ports:
- 388:389
networks:
- go-ldap-admin
ldap-seed:
image: osixia/openldap:1.5.0
restart: always
volumes:
- ./openldap/config/init.sh:/init.sh
depends_on:
- openldap
links:
- openldap:go-ldap-admin-openldap # ldap容器的 service_name:container_name
entrypoint: sh -c '/init.sh'
networks:
- go-ldap-admin
phpldapadmin:
image: osixia/phpldapadmin:0.9.0
container_name: go-ldap-admin-phpldapadmin
hostname: go-ldap-admin-phpldapadmin
restart: always
environment:
TZ: Asia/Shanghai # 设置容器时区与宿主机保持一致
PHPLDAPADMIN_HTTPS: "false" # 是否使用https
PHPLDAPADMIN_LDAP_HOSTS: go-ldap-admin-openldap # 指定LDAP容器名称
ports:
- 8090:80
volumes:
- ./openldap/phpadmin:/var/www/phpldapadmin
depends_on:
- openldap
links:
- openldap:go-ldap-admin-openldap # ldap容器的 service_name:container_name
networks:
- go-ldap-admin
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
openldap 容器启动 seed 容器会连上主容器执行对应的脚本,因为主容器初始化需要一点点时间,所以最好开头 sleep 一下。
这种方案存在的一个问题就是需要多运行一个容器,与第一种比较,不够优雅。
以上就是 openLDAP 使用 docker-compose 部署时的一些细节,很多变量参数都需要仔细看仔细调试才能找到那个符合自己需求的最终答案。