Idempotency Test
Verify that restarting the OpenLDAP container is safe — configuration is idempotent, data persists, and no duplicate entries are created.Project Files
openldap-idempotency
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
services: openldap: image: ${LDAP_IMAGE:-openldap:local} container_name: openldap-idempotency hostname: openldap-idempotency environment: - LDAP_DOMAIN=example.com - LDAP_ADMIN_PASSWORD=AdminPass123! - LDAP_ORGANIZATION=Idempotency Test Organization - ENABLE_MONITORING=true ports: - "389:389" volumes: - ldap-data:/var/lib/ldap - ldap-config:/etc/openldap/slapd.d - ./logs:/logs - ./init:/docker-entrypoint-initdb.d:ro # Security settings security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - DAC_READ_SEARCH - DAC_OVERRIDE - NET_BIND_SERVICE - SETUID - SETGID - CHOWN stop_grace_period: 30s 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:
YAMLUTF-8
Ln 542 files
Start
docker compose up -d
# Wait for initialization
docker logs -f openldap-idempotency
# Look for: "Phase 1 initialization complete"
What Gets Tested
| Test | What It Validates |
|---|---|
| Idempotency | Configuration scripts detect existing config and skip re-creation |
| Data persistence | Database files survive container restart |
| No duplicates | Re-running init doesn't create duplicate entries |
Run the Test
# 1. Note the entry count
docker exec openldap-idempotency ldapsearch -x \
-D "cn=Manager,dc=example,dc=com" \
-w "AdminPass123!" \
-b "dc=example,dc=com" \
"(objectClass=*)" | grep -c "^dn:"
# 2. Restart the container
docker compose restart
# 3. Check for errors (should see none)
docker logs openldap-idempotency 2>&1 | grep -i error
# 4. Verify "already configured" messages
docker logs openldap-idempotency 2>&1 | grep -E "(already|configured)"
# 5. Count entries again (should match step 1)
docker exec openldap-idempotency ldapsearch -x \
-D "cn=Manager,dc=example,dc=com" \
-w "AdminPass123!" \
-b "dc=example,dc=com" \
"(objectClass=*)" | grep -c "^dn:"
Expected Behavior
First Start
Configuring OpenLDAP
Setting config password...
Configuring database...
Database ACL configured
...
Phase 1 initialization complete
After Restart
Database already configured
Base domain already exists
...
OpenLDAP initialization completed
No errors should appear.
How It Works
The startup.sh script checks for existing configuration before each step:
# Skip if already configured
if is_database_configured "$LDAP_BASE_DN"; then
log_info "Database already configured"
else
# ... configure database
fi
# Skip if base domain exists
if is_base_domain_exists "$LDAP_BASE_DN" "$LDAP_ADMIN_DN" "$LDAP_ADMIN_PASSWORD"; then
log_info "Base domain already exists"
else
# ... create base domain
fi
This ensures the container can be restarted any number of times without errors.
Connection Details
| Setting | Value |
|---|---|
| Host | localhost |
| LDAP Port | 389 |
| Bind DN | cn=Manager,dc=example,dc=com |
| Base DN | dc=example,dc=com |
| Password | AdminPass123! |
Troubleshooting
"Entry already exists" errors — Indicates an idempotency bug in the init script. The script should check for existence before creating entries. Data lost after restart — Verify volumes are properly mounted:docker volume ls | grep idempotency
Cleanup
docker compose down -v