{"id":29545277,"url":"https://github.com/vegardit/docker-openldap","last_synced_at":"2025-07-17T16:39:43.542Z","repository":{"id":43059537,"uuid":"252194396","full_name":"vegardit/docker-openldap","owner":"vegardit","description":"Opinionated multi-arch Docker image based on debian:bookworm-slim to run an OpenLDAP 2.5 server.","archived":false,"fork":false,"pushed_at":"2025-06-05T18:43:10.000Z","size":148,"stargazers_count":6,"open_issues_count":1,"forks_count":3,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-06-05T19:40:06.131Z","etag":null,"topics":["docker-image","multi-arch","openldap","openldap-server","openldap-service"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vegardit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-04-01T14:13:21.000Z","updated_at":"2025-06-05T18:43:12.000Z","dependencies_parsed_at":"2023-11-20T17:28:46.846Z","dependency_job_id":"7e2b11db-84f2-4c04-986e-e504fabeb202","html_url":"https://github.com/vegardit/docker-openldap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vegardit/docker-openldap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fdocker-openldap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fdocker-openldap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fdocker-openldap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fdocker-openldap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vegardit","download_url":"https://codeload.github.com/vegardit/docker-openldap/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fdocker-openldap/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265631154,"owners_count":23801754,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker-image","multi-arch","openldap","openldap-server","openldap-service"],"created_at":"2025-07-17T16:39:40.802Z","updated_at":"2025-07-17T16:39:43.530Z","avatar_url":"https://github.com/vegardit.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vegardit/openldap \u003ca href=\"https://github.com/vegardit/docker-openldap/\" title=\"GitHub Repo\"\u003e\u003cimg height=\"30\" src=\"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/github.svg?sanitize=true\"\u003e\u003c/a\u003e\n\n[![Build Status](https://github.com/vegardit/docker-openldap/workflows/Build/badge.svg \"GitHub Actions\")](https://github.com/vegardit/docker-openldap/actions?query=workflow%3ABuild)\n[![License](https://img.shields.io/github/license/vegardit/docker-openldap.svg?label=license)](#license)\n[![Docker Pulls](https://img.shields.io/docker/pulls/vegardit/openldap.svg)](https://hub.docker.com/r/vegardit/openldap)\n[![Docker Stars](https://img.shields.io/docker/stars/vegardit/openldap.svg)](https://hub.docker.com/r/vegardit/openldap)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.1%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)\n\n1. [What is it?](#what-is-it)\n1. [Configuration](#config)\n   1. [Initial configuration](#initial-config)\n   1. [Initial LDAP tree](#initial_ldaptree)\n   1. [Customizing the Password Policy](#ppolicy)\n   1. [Transport Encryption (LDAPS/STARTTLS)](#transport_encryption)\n   1. [Changing UID/GID of OpenLDAP service user](#uidgid)\n   1. [Periodic LDAP Backup](#backup)\n   1. [Synchronizing timezone/time with docker host](#timesync)\n   1. [Performance tuning](#performance-tuning)\n   1. [Troubleshooting](#troubleshooting)\n1. [References](#references)\n1. [License](#license)\n\n\n## \u003ca name=\"what-is-it\"\u003e\u003c/a\u003eWhat is it?\n\nAn opinionated, multi-arch Docker image - currently based on [Debian](https://www.debian.org/)'s [`debian:bookworm-slim`](https://hub.docker.com/_/debian/tags?name=bookworm-slim) -\nbuilt for easy deployment of an [OpenLDAP 2.5](https://www.openldap.org/doc/admin25/) server.\n\nAutomatically rebuilt **weekly** to include the latest OS security fixes.\n\n## \u003ca name=\"config\"\u003e\u003c/a\u003eConfiguration\n\n### \u003ca name=\"initial-config\"\u003e\u003c/a\u003eInitial configuration\n\nVarious parts of the LDAP server can be configured via environment variables. All environment variables starting with `LDAP_INIT_`\nare only evaluated on the **first** container launch. Changing their values later has no effect when restarting or updating the container.\n\nTo customize the **initial** configuration you can set the following environment variables:\n\n```sh\nLDAP_INIT_ORG_DN='DC=example,DC=com'\nLDAP_INIT_ORG_NAME='Example Corporation'\nLDAP_INIT_ORG_ATTR_O='' # optional, if not defined will be derived from LDAP_INIT_ORG_DN, e.g. DC=example,DC=com -\u003e example.com\nLDAP_INIT_ADMIN_GROUP_DN='cn=ldap-admins,ou=Groups,${LDAP_INIT_ORG_DN}'\nLDAP_INIT_PASSWORD_RESET_GROUP_DN='cn=ldap-password-reset,ou=Groups,${LDAP_INIT_ORG_DN}' # users in this group can set password/sshPublicKey attribute of other users\nLDAP_INIT_ROOT_USER_DN='uid=admin,${LDAP_INIT_ORG_DN}'\nLDAP_INIT_ROOT_USER_PW='changeit'\nLDAP_INIT_RFC2307BIS_SCHEMA=0 # 0=use NIS (RFC2307) schema, 1=use RFC2307bis schema\nLDAP_INIT_ALLOW_CONFIG_ACCESS='true' # if set to true, the \"cn=config\" namespace can be read/edited by LDAP admins\n```\n\nEnvironment variables can for example be set in one of the following ways:\n\n1. Using `docker run` with `-e`, e.g.\n\n   ```sh\n   docker run -itd \\\n     -e LDAP_INIT_ORG_DN='DC=example,DC=com' \\\n     -e LDAP_INIT_ROOT_USER_PW='newpassword' \\\n     -e LDAP_INIT_ORG_NAME='Example Corporation' \\\n     -e LDAP_INIT_PPOLICY_PW_MIN_LENGTH='12' \\\n     -v /my_data/ldap/var/:/var/lib/ldap/ \\\n     -v /my_data/ldap/etc/:/etc/ldap/slapd.d/ \\\n     -p 389:389 \\\n     vegardit/openldap\n   ```\n\n1. Using an [env-file](https://docs.docker.com/compose/env-file/) to store all changed variables and use the option `--env-file` with `docker run`, e.g.:\n\n   ```sh\n   docker run -itd --env-file environment vegardit/openldap\n   ```\n\n   In the env-file values must not be enclosed using quotes (`'` or `\"`), please remove them. See this example file: [example/docker/example.env](example/docker/example.env).\n\n1. Setting the environment variable `INIT_SH_FILE` pointing to a shell script that should be sourced during the container start.\n\n   ```sh\n   # /path/on/docker/host/my_init.sh\n   LDAP_INIT_ORG_DN='DC=example,DC=com'\n   LDAP_INIT_ROOT_USER_PW='newpassword'\n   LDAP_INIT_ORG_NAME='Example Corporation'\n   LDAP_INIT_PPOLICY_PW_MIN_LENGTH='12'\n   ```\n\n   ```sh\n   docker run -itd \\\n     -e INIT_SH_FILE=/mnt/my_init.sh \\\n     -v /path/on/docker/host/my_init.sh:/mnt/my_init.sh:ro \\\n     vegardit/openldap\n   ```\n\n### \u003ca name=\"initial_ldaptree\"\u003e\u003c/a\u003eInitial LDAP tree\n\nThe initial LDAP tree structure is imported from [/opt/ldifs/init_org_tree.ldif](image/ldifs/init_org_tree.ldif).\nYou can mount a custom file at that path if you need changes.\n\nLDAP entries (users, groups) are imported from [/opt/ldifs/init_org_entries.ldif](image/ldifs/init_org_entries.ldif).\nYou can mount a custom file at that path if you need changes.\n\n### \u003ca name=\"ppolicy\"\u003e\u003c/a\u003eCustomizing the Password Policy\n\nOn **initial** container launch, the [password policy](https://www.openldap.org/doc/admin24/overlays.html#Password%20Policies) is imported from [/opt/ldifs/init_org_ppolicy.ldif](image/ldifs/init_org_ppolicy.ldif).\n\nThe following parameters can be modified via environment variables **before** initial container launch:\n\n```sh\nLDAP_INIT_PPOLICY_DEFAULT_DN='cn=DefaultPasswordPolicy,ou=Policies,${LDAP_INIT_ORG_DN}'\nLDAP_INIT_PPOLICY_PW_MIN_LENGTH=8\nLDAP_INIT_PPOLICY_MAX_FAILURES=3\nLDAP_INIT_PPOLICY_LOCKOUT_DURATION=300\n```\n\nIf more customizations are required, simply mount a custom policy file at `/opt/ldifs/init_org_ppolicy.ldif` **before** initial container launch.\n\n**Password Quality Checker:**\n\n[pqChecker](https://www.meddeb.net/pqchecker/) is configured as the default password quality checker using the rule `0|01010101` with\nthe following meaning:\n\n|Pos. |Value  |Effective Rule\n|----:|:-----:|:----------\n|0-1  | `0\\|` |Don't broadcast passwords.\n|2-4  | `01`  |Minimum 1 uppercase character.\n|5-6  | `01`  |Minimum 1 lowercase character.\n|7-8  | `01`  |Minimum 1 digit.\n|9-10 | `01`  |Minimum 1 special character.\n|11-..| empty | No characters are disallowed in passwords.\n\nThe pqChecker rule syntax is explained here in more detail: https://www.meddeb.net/pqchecker/?Idx=2\n\nA custom rule can be provided via an environment variable, e.g.:\n\n```sh\nLDAP_PPOLICY_PQCHECKER_RULE='0|01020101@!+-#'\n```\n\n### \u003ca name=\"transport_encryption\"\u003e\u003c/a\u003eTransport Encryption (LDAPS/STARTTLS)\n\nLDAP traffic can be encrypted in **two** complementary ways:\n\n1. **Terminate TLS inside the container** using *static* X.509 certificates:\n\n    * Bind-mount your TLS key material to the container to enable STARTTLS on port 389\n    * Optionally enable **LDAPS** as well (TLS-wrapped LDAP port 636)\n\n    |Variable                |Default                       |Description\n    |------------------------|------------------------------|-----------\n    |`LDAP_TLS_ENABLED`      |`auto`                        |Controls whether TLS features are activated:\u003cbr\u003e- `auto` - activate TLS only if both certificate and private key are present at `/etc/ldap/certs/server.{crt,key}` (or supplied via `LDAP_TLS_CERT_FILE`/`LDAP_TLS_KEY_FILE`)\u003cbr\u003e- `true` - always enable TLS; fail startup if certificate or private key is missing\u003cbr\u003e- `false` - disable all TLS features; ignore other TLS settings\n    |`LDAP_LDAPS_ENABLED`    |`true`                        |*(Only applies if TLS is enabled)*\u003cbr\u003e`true` - enable implicit TLS (LDAPS) listener on port 636 (`ldaps://`)\n    |`LDAP_TLS_CERT_FILE`    |`/run/secrets/ldap/server.crt`|Path to the server certificate **inside** the container\n    |`LDAP_TLS_KEY_FILE`     |`/run/secrets/ldap/server.key`|Path to the matching private key **inside** the container\n    |`LDAP_TLS_CA_FILE`      |`/run/secrets/ldap/ca.crt`    |Path to the CA bundle for verifying *peer* certificates\n    |`LDAP_TLS_VERIFY_CLIENT`|`try`                         |Client certificate policy (see [`TLSVerifyClient`](https://www.openldap.org/doc/admin25/guide.html#TLSVerifyClient%20%7B%20never%20%7C%20allow%20%7C%20try%20%7C%20demand%20%7B)):\u003cbr\u003e- `never` - don't request a client certificate\u003cbr\u003e- `allow` - request a client certificate; ignore if missing or invalid\u003cbr\u003e- `try` - request a client certificate; reject if invalid (ignore if missing)\u003cbr\u003e- `demand` - require a valid client certificate\n    |`LDAP_TLS_SSF`          |`128`                         |Minimum **Security Strength Factor** (SSF) required for **all** TLS sessions. `0` = clear-text allowed; `\u003e=0` enforces that STARTTLS/LDAPS negotiate at minimum that strength (AES-128, AES-256). More details here: [OpenLDAP Admin Guide](https://www.openldap.org/doc/admin25/guide.html#Security%20Strength%20Factors)\n\n    *How to generate a self-signed cert for testing:*\n\n    ```bash\n    openssl req -x509 -nodes -newkey rsa:4096 \\\n      -keyout server.key -out server.crt \\\n      -days 365 -sha256 \\\n      -subj \"/CN=ldap.example.com\" \\\n      -addext \"subjectAltName=DNS:ldap.example.com\"\n    ```\n\n    **Docker Compose example with bind-mount at default location:**\n\n    Mounting the key and certificate to the default location will automatically enable STARTTLS and LDAPS support.\n\n    ```yaml\n    services:\n      openldap:\n        image: vegardit/openldap:latest\n        environment:\n          # ... other options\n        ports:\n          - \"389:389\"  # for STARTTLS\n          - \"636:636\"  # for LDAPS\n        volumes:\n          - ./certs/server.crt:/run/secrets/ldap/server.crt:ro\n          - ./certs/server.key:/run/secrets/ldap/server.key:ro\n          - ./certs/ca.crt:/run/secrets/ldap/ca.crt:ro  # optional, if using a private CA\n    ```\n\n    **Docker Compose example with bind-mount at custom location:**\n\n    Pointing LDAP_TLS_KEY_FILE and LDAP_TLS_CRT_FILE to paths accessible from within the container will automatically enable STARTTLS and LDAPS support.\n\n    ```yaml\n    services:\n      openldap:\n        image: vegardit/openldap:latest\n        environment:\n          LDAP_TLS_KEY_FILE: /opt/tls/server.key\n          LDAP_TLS_CERT_FILE: /opt/tls/server.crt\n          # ... other options\n        ports:\n          - \"389:389\"  # for STARTTLS\n          - \"636:636\"  # for LDAPS\n        volumes:\n          - ./certs/:/opt/tls/:ro\n    ```\n\n1. **Terminate TLS in front of the container with a reverse proxy**\n\n    Run the container plain on **389** and put a reverse proxy like [Traefik 2.x](https://traefik.io) in front.\n    Configure a [Traefik 2.x TCP service](https://docs.traefik.io/routing/services/#configuring-tcp-services) with an\n    auto-renewing [Let's Encrypt configuration](https://docs.traefik.io/https/acme/) that forwards the encrypted stream to the container.\n\n    **Traefik 2.x example (TCP mode):**\n    ```yaml\n    services:\n      openldap:\n        image: vegardit/openldap:latest\n        ports:\n          - \"389:389\"\n        environment:\n          # ... other options\n      labels:\n        traefik.enable: \"true\"\n        traefik.tcp.routers.ldap.rule: HostSNI(`ldap.example.com`)\n        traefik.tcp.routers.ldap.entryPoints: ldaps636 # expose externally on port 636\n        traefik.tcp.routers.ldap.tls.certresolver=lets_encrypt\n        traefik.tcp.routers.ldap.service: ldap\n        traefik.tcp.services.ldap.loadbalancer.server.port=389\n\n    traefik:\n      image: traefik:latest # https://hub.docker.com/_/traefik?tab=tags\n      ports:\n        - 636:636  # ldaps\n      volumes:\n        - /etc/traefik/traefik.yml:/traefik.yml:ro\n        - /etc/traefik/keystore.json:/keystore.json # holds self-acquired letsencrypt certs\n      labels:\n        traefik.enable: true\n    ```\n\n    ```yaml\n    # https://docs.traefik.io/reference/static-configuration/file/\n    entryPoints:\n      # https://docs.traefik.io/routing/entrypoints/\n      ldaps636:\n        address: \":636\"\n    certificatesResolvers:\n      # https://docs.traefik.io/https/acme/\n      lets_encrypt:\n        acme:\n          email: info@example.com\n          storage: /keystore.json\n          tlsChallenge: {}\n          #httpChallenge:\n          #  entryPoint: http80\n    providers:\n      docker:\n        # https://docs.traefik.io/providers/docker/\n        endpoint: \"unix:///var/run/docker.sock\"\n        exposedByDefault: false # ignore containers that don't have a traefik.enable=true label\n        watch: true\n    ```\n\n\n### \u003ca name=\"uidgid\"\u003e\u003c/a\u003eChanging UID/GID of OpenLDAP service user\n\nThe UID/GID of the user running the OpenLDAP service can be aligned with the docker host using the environment variables\n`LDAP_OPENLDAP_UID` and `LDAP_OPENLDAP_GID`.\n\nDuring each container start it is verified that the given UID/GID matches the currently effective UID/GID. If not, the UID/GID\nof the `openldap` user are changed accordingly and `chown` on `/etc/ldap` and `/var/lib/slapd` is executed before the OpenLDAP service is started.\n\n### \u003ca name=\"backup\"\u003e\u003c/a\u003ePeriodic LDAP Backup\n\nThis image automatically generates a daily LDIF export at `2 a.m.` to `/var/lib/ldap/data.ldif`.\n\nThe following environment variables can be used to configure the automatic LDAP backup:\n```bash\nLDAP_BACKUP_TIME='02:00'  # Format is \"HH:MM\", i.e. 24-hour format with minute precision\nLDAP_BACKUP_FILE='/var/lib/ldap/data.ldif'\n```\n\nTo disable automatic backup set an empty value for the environment variable `LDAP_BACKUP_TIME`.\n\n### \u003ca name=\"timesync\"\u003e\u003c/a\u003eSynchronizing timezone/time with docker host\n\nTo use the same timezone and/or time of the docker host you can run the image with:\n```sh\n--volume /etc/localtime:/etc/localtime:ro \\\n--volume /etc/timezone:/etc/timezone:ro\n```\n\nDocker compose file example:\n```yaml\nversion: '3.7'\nservices:\n  openldap:\n    image: vegardit/openldap:latest\n    volumes:\n      - /etc/localtime:/etc/localtime:ro\n      - /etc/timezone:/etc/timezone:ro\n```\n\n### \u003ca name=\"performance-tuning\"\u003e\u003c/a\u003ePerformance tuning\n\n#### DB Indexes\n\nThe database indexes configured during initial container launch are imported from [/opt/ldifs/init_backend_indexes.ldif](image/ldifs/init_mdb_indexes.ldif).\n\nTo use other indexes, mount a custom file at that path **before** initial container launch.\n\n#### Memory usage\n\nThe maximum number of open files is set to `1024` by default to prevent excessive RAM consumption as reported [here](https://github.com/docker/docker/issues/8231).\n\nIncrease this limit with the following environment variable:\n\n```sh\nLDAP_NOFILE_LIMIT=2048\n```\n\n### \u003ca name=\"troubleshooting\"\u003e\u003c/a\u003eTroubleshooting\n\nThe slapd service logs to stdout. You can change the active log levels by setting this environment variable:\n\n```sh\nLDAP_LOG_LEVELS='Config Stats'\n```\n\nAvailable [log levels](https://www.openldap.org/doc/admin24/slapdconfig.html#loglevel%20%3Clevel%3E):\n\n```\nAny     (-1)     enable all debugging\nTrace   (1)      trace function calls\nPackets (2)      debug packet handling\nArgs    (4)      heavy trace debugging\nConns   (8)      connection management\nBER     (16)     print out packets sent and received\nFilter  (32)     search filter processing\nConfig  (64)     configuration processing\nACL     (128)    access control list processing\nStats   (256)    stats log connections/operations/results\nStats2  (512)    stats log entries sent\nShell   (1024)   print communication with shell backends\nParse   (2048)   print entry parsing debugging\nSync    (16384)  syncrepl consumer processing\nNone    (32768)  only messages that get logged whatever log level is set\n```\n\n\n## \u003ca name=\"references\"\u003e\u003c/a\u003eReferences\n\n- OpenLDAP Software 2.5 Administrator's Guide https://www.openldap.org/doc/admin25/guide.html\n- OpenLDAP Online Configuration Reference https://tylersguides.com/guides/openldap-online-configuration-reference/\n- `slapd-config(5)` - Linux man page https://linux.die.net/man/5/slapd-config\n\n\n## \u003ca name=\"license\"\u003e\u003c/a\u003eLicense\n\nAll files in this repository are released under the [Apache License 2.0](LICENSE.txt).\n\nIndividual files contain the following tag instead of the full license text:\n```\nSPDX-License-Identifier: Apache-2.0\n```\n\nThis enables machine processing of license information based on the SPDX License Identifiers that are available here: https://spdx.org/licenses/.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvegardit%2Fdocker-openldap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvegardit%2Fdocker-openldap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvegardit%2Fdocker-openldap/lists"}