Kubernetes has the concept of init containers. This does not exist in Docker Swarm, and the depends_on is ignored when deploying to a swarm. There are situation when the init containers are convenient, but in my Docker Swarm usage this doesn’t seem to cause trouble: before I discovered that depends_on
is a no-op when deploying to a Swarm, I used it to (I thought) simulate init containers! Let’s see my usage scenario.
When deploying an app on Docker Swarm, I prefer to persist data on the host server’s filesystem rather than in a docker volume, having read that the latter already caused trouble when updating docker itself. As a consequence, I mount the host’s /containers_data/$app_name
inside the container at /app_data
. However, I don’t want to log in on the server and create the directory manually, I want everything to be present in the compose file I’m deploying to the Docker Swarm.
The solution is easy. For an example, let’s look at an openldap container deployed in a Swarm stack.
I need to add the directory /containers_data/openldap
and change the owner to 1001
.
To this end I add a container (that I name init
) in the compose file:
init:
command:
- bash
- -c
- mkdir -p /data/openldap ; chown 1001:1001 /data/openldap
image: ubuntu:latest
user: root
volumes:
- /containers_data:/data
The openldap container mounts the host directory /containers_data/openldap
:
openldap:
image: bitnami/openldap:2.6.3
volumes:
- "/containers_data/openldap:/bitnami/openldap"
I initially put a key depends_on: init
thinking it would delay the start of the openldap container. It did nothing actually. If the openldap started before the needed directory was created, it would be restarted until the directory was available. To be sure, let’s check below if that’s really what happens.
I deploy a stack with the init container and a depend_on
entry in the openldap container:
version: "3.8"
services:
init:
command:
- bash
- -c
- mkdir -p /data/test_container; sleep 10; chown 1001:1001 /data/test_container
image: ubuntu:latest
user: root
volumes:
- /data:/data
openldap:
image: bitnami/openldap:2.6.3
depends_on: [ init ]
volumes:
- "/data/test_container:/bitnami/openldap"
The init
container immediately creates the directory mounted by the openldap container (otherwise we would end up with an invalid mount config
and the openldap container would not even start) but it waits for 10 seconds before setting the right owner. If depends_on
were effective, the openldap
container would would not start before the correct owner was set. But this is not the case:
$ docker service logs test_openldap
test_openldap.1.iug8upss0kqc@vmi764857 | 09:46:24.12 INFO ==> ** Starting LDAP setup **
test_openldap.1.iug8upss0kqc@vmi764857 | 09:46:24.18 INFO ==> Validating settings in LDAP_* env vars
test_openldap.1.iug8upss0kqc@vmi764857 | 09:46:24.20 INFO ==> Initializing OpenLDAP...
test_openldap.1.iug8upss0kqc@vmi764857 | mkdir: cannot create directory '/bitnami/openldap/data': Permission denied
test_openldap.1.rzjyshowyzot@vmi764857 | 09:46:39.78 INFO ==> ** Starting LDAP setup **
test_openldap.1.rzjyshowyzot@vmi764857 | 09:46:39.82 INFO ==> Validating settings in LDAP_* env vars
test_openldap.1.rzjyshowyzot@vmi764857 | 09:46:39.83 INFO ==> Initializing OpenLDAP...
test_openldap.1.rzjyshowyzot@vmi764857 | 09:46:39.86 INFO ==> Creating LDAP online configuration
test_openldap.1.rzjyshowyzot@vmi764857 | 09:46:39.91 INFO ==> Starting OpenLDAP server in background
test_openldap.1.rzjyshowyzot@vmi764857 | 09:46:40.93 INFO ==> Configure LDAP credentials for admin user
test_openldap.1.rzjyshowyzot@vmi764857 | 09:46:40.96 INFO ==> Adding LDAP extra schemas
test_openldap.1.rzjyshowyzot@vmi764857 | 09:46:41.02 INFO ==> Creating LDAP default tree
test_openldap.1.rzjyshowyzot@vmi764857 | 09:46:42.09 INFO ==> ** LDAP setup finished! **
test_openldap.1.rzjyshowyzot@vmi764857 |
test_openldap.1.rzjyshowyzot@vmi764857 | 09:46:42.12 INFO ==> ** Starting slapd **
test_openldap.1.rzjyshowyzot@vmi764857 | 63984a02.07b79532 0x7fc05b931740 @(#) $OpenLDAP: slapd 2.6.3 (Nov 29 2022 11:05:27) $
test_openldap.1.rzjyshowyzot@vmi764857 | @4b9918e8888a:/bitnami/blacksmith-sandox/openldap-2.6.3/servers/slapd
test_openldap.1.rzjyshowyzot@vmi764857 | 63984a02.086a9099 0x7fc05b931740 slapd starting
We see in these logs that the openldap
container started before the init
container ran to completion.
So remember, depends_on
is a no-op when deploying to Docker Swarm!