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

TestWhat It Validates
IdempotencyConfiguration scripts detect existing config and skip re-creation
Data persistenceDatabase files survive container restart
No duplicatesRe-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

SettingValue
Hostlocalhost
LDAP Port389
Bind DNcn=Manager,dc=example,dc=com
Base DNdc=example,dc=com
PasswordAdminPass123!

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