How to Configure LDAP Authentication for Self‑Hosted Applications: A Complete Guide
Configure LDAP authentication by deploying an OpenLDAP server (or 389 Directory Server), securing it with TLS/StartTLS, creating a service bind account, and pointing each application to the directory via environment variables or configuration files like grafana.ini and ldap.toml.
The Self-Hosting-Guide repository provides comprehensive coverage of LDAP integration for self-hosted services. This guide walks through the exact configuration patterns found in the repository's README.md LDAP section, demonstrating how to unify authentication across multiple containers using a central directory.
Architectural Overview of LDAP Authentication
A typical LDAP deployment for self-hosting consists of four layers working together to provide centralized identity management.
The LDAP Server Layer
The LDAP server acts as the authoritative directory for user identities and groups. The Self-Hosting-Guide lists several supported options including OpenLDAP, 389 Directory Server, and Apache Directory Server. You install one of these, populate it with users using ldapadd or a GUI like Apache Directory Studio, and define the schema attributes (e.g., uid, mail, cn) that applications will query.
TLS Encryption Requirements
Secure the bind connection using either LDAPS on port 636 or StartTLS on port 389. This protects credentials in transit between applications and the directory. For OpenLDAP specifically, configure olcTLSCertificateFile and olcTLSCertificateKeyFile in the server configuration, or mount certificates into the container.
Client Application Configuration
Each self-hosted service (such as Nextcloud, Docker Mailserver, or Grafana) binds to the LDAP server using a standard set of parameters:
- LDAP host and port (389 or 636)
- Bind DN (service account distinguished name)
- Bind password (stored in Docker secrets or environment variables)
- Base DN for user searches (e.g.,
ou=users,dc=example,dc=org) - Attribute mapping to align LDAP fields with application user properties
Reverse Proxy Integration (Optional)
If you front services with Traefik, Caddy, or Nginx, delegate authentication to middleware like Ory Oathkeeper or Keycloak. These tools validate LDAP credentials and set a session cookie or JWT before the request reaches the backend application.
Step‑by‑Step Configuration Guide
Follow these steps to implement LDAP authentication according to the Self-Hosting-Guide patterns.
1. Deploy an OpenLDAP Server
Use the official Docker image to spin up the directory service. The guide recommends osixia/openldap as the primary choice for self-hosted environments.
# docker-compose.yml
version: "3.8"
services:
openldap:
image: osixia/openldap:1.5.0
container_name: openldap
environment:
LDAP_ORGANISATION: "My Org"
LDAP_DOMAIN: "example.org"
LDAP_ADMIN_PASSWORD: "StrongPassword123"
LDAP_TLS: "true"
volumes:
- ./ldap-data:/var/lib/ldap
- ./ldap-config:/etc/ldap/slapd.d
ports:
- "389:389"
- "636:636"
Store the admin password in a proper secret store for production deployments.
2. Enable TLS Encryption
Mount TLS certificates into the container or let the image generate self-signed ones. Configure the OpenLDAP TLS parameters to secure authentication traffic.
3. Create a Service Bind Account
Create a low-privilege DN (e.g., cn=binduser,ou=service,dc=example,dc=org) that can search the directory but cannot modify entries. This account prevents applications from having administrative access while still allowing user lookups.
4. Configure Target Applications
Most Docker-based apps expose LDAP variables. The guide provides specific examples for Docker Mailserver and Grafana.
5. Test the Integration
Use ldapsearch from a client container to verify bind and search operations before enabling application-level authentication.
Practical Configuration Examples
Deploying OpenLDAP with Docker Compose
The Self-Hosting-Guide references OpenLDAP as the primary directory option in its README.md LDAP section. The following docker-compose.yml snippet matches the repository's recommended deployment pattern:
version: "3.8"
services:
openldap:
image: osixia/openldap:1.5.0
container_name: openldap
environment:
LDAP_ORGANISATION: "My Org"
LDAP_DOMAIN: "example.org"
LDAP_ADMIN_PASSWORD: "StrongPassword123"
LDAP_TLS: "true"
volumes:
- ./ldap-data:/var/lib/ldap
- ./ldap-config:/etc/ldap/slapd.d
ports:
- "389:389"
- "636:636"
Configuring Grafana for LDAP Authentication
Grafana uses a two-file configuration approach. First, enable LDAP in grafana.ini:
# grafana.ini (mounted into the Grafana container)
[auth.ldap]
enabled = true
config_file = /etc/grafana/ldap.toml
allow_sign_up = true
Then specify connection details in ldap.toml:
# ldap.toml
[[servers]]
host = "openldap"
port = 389
use_ssl = false
start_tls = true
bind_dn = "cn=binduser,ou=service,dc=example,dc=org"
bind_password = "SecretBindPwd"
search_filter = "(uid=%s)"
search_base_dns = ["ou=users,dc=example,dc=org"]
Grafana follows the standard pattern of host, bind DN, and search filter to authenticate users against the directory.
Docker Mailserver LDAP Setup
The guide identifies Docker Mailserver as a "full-stack" service with built-in LDAP support. Enable it via environment variables:
# docker-compose.yml snippet
mailserver:
image: docker.io/mailserver/docker-mailserver:latest
hostname: mail
domainname: example.org
environment:
- ENABLE_LDAP=1
- LDAP_SERVER=ldap://openldap:389
- LDAP_BIND_DN=cn=binduser,ou=service,dc=example,dc=org
- LDAP_BIND_PW=SecretBindPwd
- LDAP_BASE_DN=ou=users,dc=example,dc=org
volumes:
- maildata:/var/mail
- mailstate:/var/mail-state
- ./config/:/tmp/docker-mailserver/
ports:
- "25:25"
- "587:587"
- "993:993"
Testing with ldapsearch
Verify connectivity using a one-off container before configuring applications:
docker run --rm -it \
--network=host \
osixia/openldap:1.5.0 \
ldapsearch -H ldaps://localhost \
-D "cn=binduser,ou=service,dc=example,dc=org" \
-w "SecretBindPwd" \
-b "ou=users,dc=example,dc=org" \
"(uid=*)"
If the command returns user entries, authentication is correctly wired.
Security Best Practices
When configuring LDAP authentication for self-hosted applications, follow these guidelines from the Self-Hosting-Guide:
- Store bind passwords in secret stores (Docker secrets, Kubernetes secrets, or
.envfiles) rather than plain text in compose files - Use LDAPS or StartTLS exclusively to avoid transmitting credentials in clear text
- Map LDAP groups to application roles when supported (e.g., mapping Nextcloud groups to admin/user privileges)
- Restrict the bind account to read-only access on specific organizational units
- Enable TLS certificate validation in client applications to prevent man-in-the-middle attacks
Summary
- Deploy OpenLDAP using the
osixia/openldapimage with persistent volumes forldap-dataandldap-config - Secure connections via LDAPS on port 636 or StartTLS on port 389 by configuring
olcTLSCertificateFileandolcTLSCertificateKeyFile - Create a dedicated bind account with limited privileges for applications to query the directory
- Configure applications using standard environment variables (
LDAP_SERVER,LDAP_BIND_DN,LDAP_BASE_DN) or configuration files (grafana.ini,ldap.toml) - Test connectivity with
ldapsearchbefore enabling application authentication - Optional: Add reverse-proxy authentication using Ory Oathkeeper or Keycloak to centralize session management
Frequently Asked Questions
What is the difference between LDAP and LDAPS?
LDAPS (LDAP over SSL) uses port 636 and establishes an encrypted connection immediately upon connection. Standard LDAP on port 389 transmits data in plain text unless you enable StartTLS, which upgrades the connection to encrypted after the initial handshake. The Self-Hosting-Guide recommends using LDAPS or StartTLS to protect credentials in transit.
Can I use LDAP authentication with Docker Mailserver?
Yes. Docker Mailserver includes native LDAP support. Set ENABLE_LDAP=1 and provide the LDAP_SERVER, LDAP_BIND_DN, LDAP_BIND_PW, and LDAP_BASE_DN environment variables. The mail server will authenticate users against the directory before allowing IMAP or SMTP access.
How do I map LDAP groups to application roles?
Most applications that support LDAP also support group mapping through configuration attributes. In ldap.toml for Grafana or equivalent configuration files, specify the group_search_filter and group_mappings parameters to align LDAP groups (e.g., cn=admins,ou=groups,dc=example,dc=org) with application-specific roles (e.g., Admin, Editor).
Which LDAP server should I choose for self-hosting?
The Self-Hosting-Guide lists OpenLDAP as the primary recommended option due to its widespread adoption and Docker support. Alternatively, you can deploy 389 Directory Server or Apache Directory Server depending on your preference for management interfaces and specific schema requirements.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →