Sharing Files Between Docker Images Using Volumes
$ cat bridge-env.sh
export BRIDGENAME=brbob
export IMAGENAME=bob
export IPADDR=10.0.10.1/24
Before any explanations, let's look at the files we'll be using:
./configuration/build_image.sh - wrapper for _docker build_.
./configuration/run_image.sh - wrapper for _docker run_.
./configuration/Dockerfile - control file for Docker image.
./configuration/files/bridge-env.sh - environment setting script.
All of the files are fairly small. Since our main topic today is Docker, let's look at the Docker configuration file first.
$ cat Dockerfile
FROM stackbrew/busybox:latest
MAINTAINER David Medinets <david.medinets@gmail.com>
RUN mkdir /configuration
VOLUME /configuration
ADD files /configuration
And you can build this image.
$ cat build_image.sh
sudo DOCKER_HOST=$DOCKER_HOST docker build --rm=true -t medined/shared-configuration .
I setup my docker to use a port instead of a UNIX socket. Therefore my DOCKERHOST is "tcp://0.0.0.0:4243". Since _sudo is being used, the environment variable needs to be set inside the sudo enviroment. If you want to use the default UNIX socker, leave DOCKER_HOST empty. The command will still work.
Then run it.
$ cat run_image.sh
sudo DOCKER_HOST=$DOCKER_HOST docker run --name shared-configuration -t medined/shared-configuration true
This command runs a docker container called sharedconfiguration. You'll notice that the _true command is run which exits immediately. Since this container will only hold files, it's ok there are no processes running in it. However, be very careful not to delete this container. Here is the output from docker ps showing the container.
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d4a2aa46b5d9 medined/shared-configuration:latest true 7 seconds ago Exited (0) 7 seconds ago -shared-configuration
Now it's time to spin up two plain Ubuntu containers that can access the shared file.
$ sudo DOCKER_HOST=$DOCKER_HOST docker run --name A --volumes-from=shared-configuration -d -t ubuntu /bin/bash
94638de8b615f356f1240bbe602c0b7862e0589f1711fbff242b6d6f74c7de7d
$ sudo DOCKER_HOST=$DOCKER_HOST docker run --name B --volumes-from=shared-configuration -d -t ubuntu /bin/bash
sudo DOCKER_HOST=$DOCKER_HOST docker run --name B --volumes-from=shared-configuration -d -t ubuntu /bin/bash
How can we see the shared file? Let's turn to a very useful tool called nsenter (or namespace enter). The following command installs nsenter if isn't already installed.
hash nsenter 2>/dev/null \
|| { echo >&2 "Installing nsenter"; \
sudo DOCKER_HOST=$DOCKER_HOST \
docker run -v /usr/local/bin:/target jpetazzo/nsenter; }
I use a little script file to make nsenter easier to use:
$ cat enter_image.sh
#!/bin/bash
IMAGENAME=$1
usage() {
echo "Usage: $0 [image name]"
exit 1
}
if [ -z $IMAGENAME ]
then
echo "Error: missing image name parameter."
usage
fi
PID=$(sudo DOCKER_HOST=$DOCKER_HOST docker inspect --format {{.State.Pid}} $IMAGENAME)
sudo nsenter --target $PID --mount --uts --ipc --net --pid
This script is used by specifying the image name to use. For example,
$ ./enter_image.sh A
root@94638de8b615:/# cat /configuration/bridge-env.sh
export BRIDGENAME=brbob
export IMAGENAME=bob
export IPADDR=10.0.10.1/24
root@94638de8b615:/# exit
logout
$ ./enter_image.sh B
root@925365faded2:/# cat /configuration/bridge-env.sh
export BRIDGENAME=brbob
export IMAGENAME=bob
export IPADDR=10.0.10.1/24
root@925365faded2:/# exit
logout
We see the same information in both containers. Let's prove that the bridge-env.sh file is shared instead of being two copies.
$ ./enter_image.sh A
root@94638de8b615:/# echo "export NEW_VARIABLE=VALUE" >> /configuration/bridge-env.sh
root@94638de8b615:/# exit
logout
$ ./enter_image.sh B
root@925365faded2:/# cat /configuration/bridge-env.sh
export BRIDGENAME=brbob
export IMAGENAME=bob
export IPADDR=10.0.10.1/24
export NEW_VARIABLE=VALUE
We changed the file in the first container and saw the changes in the second container. As an alternative to using nsenter, you can simply run a container to list the files.
$ docker run --volumes-from shared-configuration busybox ls -al /configuration