Drupal and Docker: Creating a new Docker image based on an existing image
To get the most of this blog post, please read and understand Getting Started with Docker (Servers for Hackers, 2014/03/20). Also, all the steps outlined here have been done on a Vagrant CoreOS virtual machine (VM).
I recently needed a really simple non-production Drupal Docker image on which I could run tests.
b7alt/drupal (which you can find by typing
docker search drupal, or on GitHub) worked for my needs, except that it did not have the cUrl php library installed, so
drush en simpletest -y was throwing an error.
Therefore, I decided to create a new Docker image which is based on
b7alt/drupal, but with the
php5-curl library installed.
I started by creating a new local directory (on my CoreOS VM), which I called
In that directory, I created
Dockerfile which takes
b7alt/drupal as its base, and runs
apt-get install curl.
FROM b7alt/drupal RUN apt-get update RUN apt-get -y install curl
(You can find this code at my GitHub account at
When you run this you will get:
docker build . ... Successfully built 55a8c8999520
That hash is a Docker image ID, and your hash might be different. You can run it and see if it works as expected:
docker run -d 55a8c8999520 c9a98bdcab4e027e8571bde71ee92b4380247a44ef9314749ef5680864de2928
In the above, we are telling Docker to create a container based on the image we just created (
55a8c8999520). The resulting container hash is displayed (yours might be different). We are using
-d so that our containers runs in the background. You can see that the container is actually running by typing:
docker ps CONTAINER ID IMAGE COMMAND... c9a98bdcab4e 55a8c8999520 "/usr/bin/supervisor...
This tells you that there is a running container (
c9a98bdcab4e) based on the image
55a8c8999520. Again, your hases will be different. Let’s log into that container now:
docker exec -it c9a98bdcab4e bash root@c9a98bdcab4e:/#
To make sure that cUrl is successfully installed, I will figure out where Drupal resides on this container, and then try to enable Simpletest. If that works, I will consider my image a success, and
exit from my container:
root@c9a98bdcab4e:/# find / -name 'index.php' /srv/drupal/www/index.php root@c9a98bdcab4e:/# cd /srv/drupal/www root@c9a98bdcab4e:/srv/drupal/www# drush en simpletest -y The following extensions will be enabled: simpletest Do you really want to continue? (y/n): y simpletest was enabled successfully. [ok] root@c9a98bdcab4e:/srv/drupal/www# exit exit
Now I know that my
55a8c8999520 image is good for now and for my purposes; I can create an account on Docker.com and push it to my account for later use:
Docker build -t alberto56/docker-drupal . docker push alberto56/docker-drupal
Anyone can now run this Docker image by simply typing:
docker run alberto56/docker-drupal
One thing I had a hard time getting my head around was having a GitHub project and Docker project, and both are different but linked. The GitHub project is the the recipe for creating an image, whereas the Docker project is the image itself.
One we start thinking of our environments like this (as entities which should be versioned and shared), the risk of differences between environments is greatly reduced. I was used to running simpletests for my projects on an environment which is managed by hand; when I got a strange permissions error on the test environment, I decided to start using Docker and version control to manage the container where tests are run.