Under the hood (first adventures in Docker)

Submitted by mrjmd on Fri, 05/20/2016 - 08:58

Maybe I'm a little behind on this one, but I had never played with Docker directly before until this week. Coming out of DrupalCon New Orleans, I am still in "learn all the things at once" mode, and knew I was planning on spinning up my own site again, but wanted to try to do it with this (not so) new tool. I attended a BOF on Docker at the Con, but was in over my head and knew the only way I would really learn the basics was to dive in and give it a try myself.

So, I spun up a new droplet on Digital Ocean, shelled into it, and got to work. Here's the basic path I followed, which came largely from this article:

$ wget -qO- | sh
$ docker pull mysql
$ docker pull drupal:8.1.1
$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=nottellingyou -e MYSQL_DATABASE=d8 -e MYSQL_USER=d8_user MYSQL_PASSWORD=stillnottelling -d mysql
$ cd ~ && mkdir modules
$ docker run -v /$HOME/modules:/var/www/html/modules -p 80:80 --name drupal8 --link mysql:mysql -d drupal

That's it! Then I navigated over to and installed Drupal 8 as usual. Now let's go through all of this in a bit more detail and see what I've done.

$ wget -qO- | sh

This first command just downloads and installs docker. As mentioned in the article above, you can verify it has worked properly afterwards by running the command:

$ docker -D info

This will show you all the basic information about your docker install, including how many images and containers you have (zero right after running this command, or two after running all of the above).

$ docker pull mysql

This pulls down the mysql image from the official docker image hub here. Click through to read more about it.

$ docker pull drupal:8.1.1

Similarly this pulls the official drupal image from docker hub, and specifies that I want version 8.1.1. The Drupal image currently includes Apache 2.4.10 and PHP 7.06 by default, so I'm finally running Drupal 8 on PHP 7 also!

So, now I've got both of these images sitting on my remote box, but they're not actually doing anything. You can think of Docker images like snapshots in Vagrant terms, they are system images that contain a baseline setup to get you going, but aren't actually doing anything until you tell them to, which is our next step.

$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=nottellingyou -e MYSQL_DATABASE=d8 -e MYSQL_USER=d8_user MYSQL_PASSWORD=stillnottelling -d mysql

There's a lot going on here, but it's not very complicated. We are starting up our mysql image (creating our first container). We've named the container simply "mysql", since I'll only be running the one here, but you can name it whatever you want. Then we're feeding in a variety of environmental variables, including our root password, a database name we'd like created immediately, and a username and password to associate with the new database. All you really need to feed in at this point is the root password, as you can always connect to your MySQL command line later and run commands directly using the following:

$ docker run -it --link mysql:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'

For brevity I've just used that single command to do all the work instead. Moving on.

$ cd ~ && mkdir modules

It should be obvious what's happening here, I'm simply create a new directory in my user's folder called "modules". The motivation is probably obvious as well, but I neglected this part the first time I installed my site and it took me a minute to figure out. Because docker containers are self-contained, once I originally had my site installed I couldn't find any obvious way to add on new modules. Once I ran the drupal image I could run bash commands inside of it by using the following command:

$ docker exec -it <mycontainer> bash

Where <mycontainer> is the container id for drupal, which you can find using:

$ docker ps -a

[As a quick aside, the "-a" flag above was super helpful to me at one point, because my MySQL container crashed the first time I tried to install and I couldn't figure out what was going on... the container didn't show up at all when I used "docker ps". If this happens the "-a" flag will show you all containers that exist, and once I saw mysql was stopped I just ran "docker mysql start" and was back on my way.]

However, I wanted to be able to download modules directly onto the remote box and mount them into a volume that would be used by my container, hence I needed a new directory to mount. Which brings us to:

$ docker run -v /$HOME/modules:/var/www/html/modules -p 80:80 --name drupal8 --link mysql:mysql -d drupal

Here, first and foremost, I am running the Drupal image and turning it into an active container. Further I'm mounting the directory I just created as a volume and linking it to the appropriate directory inside the drupal image, setting port forwarding, naming the container, and linking it directly to the mysql container we already have running. Boom!

After that navigating to redirected me to the install page, and I installed Drupal normally, using the database credentials I specified when running the mysql image. The only caveat was opening the advanced fieldset under database settings and changing "localhost" to "mysql". Now I'm up and running, with the ability to download and add contrib modules easily. Excuse me while I go install pathauto finally.

Next steps will be getting some php extensions added, check back soon for my progress on that.

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.