Docker Secrets
Deploy OpenLDAP with passwords loaded from Docker secrets instead of plaintext environment variables. Passwords never appear indocker inspect, process lists, or container metadata.
Project Files
openldap-secrets
Explorer
docker-compose.yml
1
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
services: openldap: image: ${LDAP_IMAGE:-openldap:local} container_name: openldap-secrets hostname: openldap-secrets environment: # Use _FILE variants to read passwords from Docker secrets - LDAP_DOMAIN=example.com - LDAP_ADMIN_PASSWORD_FILE=/run/secrets/ldap_admin_password - LDAP_CONFIG_PASSWORD_FILE=/run/secrets/ldap_config_password - LDAP_ORGANIZATION=Example Organization (Docker Secrets) # Optional features - ENABLE_MONITORING=true - ENABLE_MEMBEROF=false ports: - "389:389" - "636:636" volumes: - ldap-data:/var/lib/ldap - ldap-config:/etc/openldap/slapd.d - ./logs:/logs # Security: Drop all capabilities and add only required ones security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - NET_BIND_SERVICE - SETUID - SETGID - CHOWN - DAC_READ_SEARCH - DAC_OVERRIDE # Grace period for clean shutdown stop_grace_period: 30s # Docker secrets - passwords are mounted as files, not env vars secrets: - ldap_admin_password - ldap_config_password restart: unless-stopped # Resource limits deploy: resources: limits: memory: 512M cpus: '1.0' reservations: memory: 128M # Log rotation logging: driver: json-file options: max-size: "10m" max-file: "3" volumes: ldap-data: ldap-config: # Docker secrets definition # Secrets are read from files on the host at startup secrets: ldap_admin_password: file: ./secrets/admin_password.txt ldap_config_password: file: ./secrets/config_password.txt
YAMLUTF-8
Ln 741 files
Set image
export LDAP_IMAGE=ghcr.io/vibhuvioio/openldap:latest
Create Secret Files
mkdir -p secrets
echo "YourSecureAdminPassword" > secrets/admin_password.txt
echo "YourSecureConfigPassword" > secrets/config_password.txt
Important: Addsecrets/.txtto your.gitignoreto avoid committing passwords.
Start
docker compose up -d
Verify Secrets Are Used
# Passwords should NOT appear in environment variables
docker exec openldap-secrets env | grep -i password
# Expected: LDAP_ADMIN_PASSWORD_FILE=/run/secrets/ldap_admin_password
# (not the actual password)
# Verify the secret file is mounted
docker exec openldap-secrets cat /run/secrets/ldap_admin_password
Test Authentication
ADMIN_PASS=$(cat secrets/admin_password.txt)
ldapsearch -x -H ldap://localhost:389 \
-D "cn=Manager,dc=example,dc=com" \
-w "$ADMIN_PASS" \
-b "dc=example,dc=com" -s base
How It Works
The Docker Compose file uses the secrets directive:
services:
openldap:
environment:
- LDAP_ADMIN_PASSWORD_FILE=/run/secrets/ldap_admin_password
- LDAP_CONFIG_PASSWORD_FILE=/run/secrets/ldap_config_password
secrets:
- ldap_admin_password
- ldap_config_password
secrets:
ldap_admin_password:
file: ./secrets/admin_password.txt
ldap_config_password:
file: ./secrets/config_password.txt
The startup.sh script detects _FILE variants and reads the password from the file at runtime:
if [ -n "$LDAP_ADMIN_PASSWORD_FILE" ] && [ -f "$LDAP_ADMIN_PASSWORD_FILE" ]; then
LDAP_ADMIN_PASSWORD=$(cat "$LDAP_ADMIN_PASSWORD_FILE")
fi
Security Comparison
| Plaintext Env Var | Docker Secrets |
|---|---|
Visible in docker inspect | Hidden from container metadata |
In process list (ps e) | Only in file readable by container |
| May be logged | Not logged by default |
| Risk of git commit | Can be gitignored |
Connection Details
| Setting | Value |
|---|---|
| Host | localhost |
| LDAP Port | 389 |
| LDAPS Port | 636 |
| Bind DN | cn=Manager,dc=example,dc=com |
| Base DN | dc=example,dc=com |
| Password | Contents of secrets/admin_password.txt |
Production Recommendations
-
1
Never commit secrets to git — add
secrets/.txtto.gitignore -
2
Use proper secret managers — Docker Swarm (
docker secret create), Kubernetes Sealed Secrets, or HashiCorp Vault - 3 Rotate secrets regularly — update the file and restart the container
-
4
Set strict permissions —
chmod 600 secrets/*.txt
Cleanup
docker compose down -v