httpd in docker cannot start httpd in docker cannot start docker docker

httpd in docker cannot start


This is a documented behavior indeed:

Volumes are initialized when a container is created. If the container’s base image contains data at the specified mount point, that existing data is copied into the new volume upon volume initialization. (Note that this does not apply when mounting a host directory.)

i.e. when you mount the /etc/httpd volume --volume /data/httpd/etc:/etc/httpd, no data will be copied.

You can also see https://github.com/docker/docker/pull/9092 for a more detailed discussion on why it works this way (in case you are interested).

A usual workaround for this is to copy your initial data, to the volume folder (from within the container), inside your ENTRYPOINT or CMD script,in case it is empty.

Note that your initial dataset must be kept outside the volume folder (e.g. as .tar file in /opt), for this to work, as the volume folder will be shadowed by the host folder mounted over it.

Given below is a sample Dockerfile and Script, which demonstrate the behavior:

Sample Dockerfile

FROM debian:stableRUN mkdir -p /opt/test/; touch /opt/test/initial-data-fileVOLUME /opt/test

Sample script (try various volume mappings)

#Build image>docker build -t volumetest .Sending build context to Docker daemon  2.56 kBStep 0 : FROM debian:stable---> f7504c16316cStep 1 : RUN mkdir -p /opt/test/; touch /opt/test/initial-data-file---> Using cache---> 1ea0475e1a18    Step 2 : VOLUME /opt/test---> Using cache---> d8d32d849b82Successfully built d8d32d849b82#Implicit Volume mapping (as defined in Dockerfile)>docker run --rm=true volumetest ls -l /opt/testtotal 0-rw-r--r-- 1 root root 0 Nov  4 18:26 initial-data-file#Explicit Volume mapping> docker run --rm=true --volume /opt/test volumetest ls -l /opt/test/total 0-rw-r--r-- 1 root root 0 Nov  4 18:26 initial-data-file#Explicitly Mounted Volume>mkdir test>docker run --rm=true --volume "$(pwd)/test/:/opt/test" volumetest ls -l /opt/testtotal 0

And here is a simple entrypoint script, illustrating a possible workaround:

#!/bin/bashVOLUME=/opt/testDATA=/opt/data-volume.tar.gzif [[ -n $(find "$VOLUME" -maxdepth 0 -empty) ]]then    echo Preseeding VOLUME $VOLUME with data from $DATA...    tar -C "$VOLUME" -xvf "$DATA" fi"$@"

add the following to the Dockerfile

COPY data-volume.tar.gz entrypoint /opt/ENTRYPOINT ["/opt/entrypoint"]

First run:

>docker run --rm=true --volume "$(pwd)/test/:/opt/test" volumetest ls -l /opt/testPreseeding VOLUME /opt/test with data from /opt/data-volume.tar.gz...preseeded-datatotal 0-rw-r--r-- 1 1001 users 0 Nov  4 18:43 preseeded-data

Subsequent runs:

>docker run --rm=true --volume "$(pwd)/test/:/opt/test" volumetest ls -l /opt/testls -l /opt/testtotal 0-rw-r--r-- 1 1001 users 0 Nov  4 18:43 preseeded-data

Note, that the volume folder will only be populated with data,if it was completely empty before.