ApacheDS LDAP Server on Docker with Ansible
Update 2022-10-10: I published the code and added more container versions on dockerhub. Check the AnsibleDS post update.
Recently, I was massively bored over the weekend. So I started to redo my personal server setup.
I wanted to use an LDAP server for user management and got instantly confused over which one to choose. OpenLDAP is said to be fast and reliable, but the documentation is all over the place and usability is limited at best. 389 Directory Server has a better documentation but you need an extra management server and a console server. That was just too much hassle for me.
Luckily, there is ApacheDS. Sure, its written in Java but you only need to run one process and it comes with a fully fledged IDE.
Then again, there is no official docker container. So I made my own, together with a set of ansible scripts to deploy the container to my server. Enjoy!
You need a server that is accessible via ssh. In creating this post I used a Ubuntu Server 20.04 with hostname tnglab. You should be able to log in on port 22. My local machine was a MacOS with Python 3.8 and installed ansible package. You can install the ansible package in several ways, as the ansible documentation descibes.
We will create an ansible setup that will install Docker on tnglab and then run the ApacheDS docker image.
Set up Ansible
In a new directory we create the
hosts.yml, into which we enter the access information for tnglab.
We list the
hosts.yml in the additional Ansible configuration file
ansible.cfg so that we don’t have to enter the
hosts.yml path to every Ansible command.
After that, the following command should result result below.
benjamin@asterix:example# ansible -m ping tnglab
Our basic Ansible setup is now working, now we need a Docker image to start.
ApacheDS Docker Image
There are already a few ApacheDS docker images available on Docker Hub but at the time that I wrote this blog post, there wasn’t one available that would also provide the code for creating it. As the LDAP server can be a very vital and security relevant part of any ones infrastructure, I created my own image.
I will provice the code necessary below. This is not a complete example on how to create a docker image. If you are just interested in using the image, you can pull it from Docker Hub:
docker pull gevattergaul/apacheds
The Dockerfile copies the original config from
config/config.ldif and the logging config from
config/log4j.properties, as well as
entrypoint.sh to the image. The
config.ldif remains unchanged, I copied it from the upstream ApacheDS distribution. The logging config is adjusted to log to
stdout so that we get log output in docker.
The files are copied to the image as
*.default files. The entrypoint will move them to the correct position in the container on first start. When you restart the container, the files will not be copied again. This is necessary for both config files. This way we can mount a custom log config to the container. Also, the
config.ldif may only be present when ApacheDS is first started. There, it will convert it to its internal data structure and move the file away. If the
config.ldif was present on a restart, ApacheDS would throw an error.
You can build the docker image like this:
Now that we have a docker image, we shall deploy it to tnglab.
In the ansible directory from before we now create the config files for the LDAP role. Roles are one possibility to reuse code in Ansible. The Ansible wiki describes roles in detail.
The role loads the image from Docker Hub, mounts the ApacheDS runtime files to the local harddrive of
tnglab and opens the LDAP port on
tnglab. The LDAP port will only be accessible on
tnglab. Therefore we can use the role on public machines without the risk that someone will access our unsecured LDAP server. Later, we will use a ssh tunnel to access the LDAP port on
If you haven’t installed docker on your host yet, you can use the following role.
We combine both in a playbook
Including the files from before, the directory structure should now look like this.
So we can run it by invoking the playbook.
Now we should have a running ApacheDS instance in a Docker container on tnglab.
Access ApacheDS Instance
To access the ApacheDS instance, we have to access the LDAP port on
tnglab which is not publicly available. Therefore, we use a ssh tunnel to make the port available on our local machine.
ssh -L 10389:localhost:389 tnglab
Now you can access the ApacheDS instance over your localhost on port 389. In Apache Directory Studio you can enter the connection information like this:
If you have started ApacheDS in its standard configuration as descibed above, you can log in with the admin user
uid=admin,ou=system and the default password
Now you should have full access to the ApacheDS instance. Changes to the LDAP tree will be saved on
tnglab and persisted on restarts of the ApacheDS container. Don’t forget to change your password.