How To Build A 2-Container App with Docker and Tutum

A few days back Lucas Carlson, founder of AppFog and CIO of Century Link, wrote a great blog post on the topic at hand: how to build a 2-container application with Docker. This article can be found here.

In this blog post, I’m going to show you how to launch a 2-container application using Docker and Tutum. For this example, we’re going to be using the combination of a WordPress container plus a MySQL container, but this exact same procedure can be used to link just about any combination of 2 or more containers.

Step 1 – Start with a MySQL container

WordPress needs a DB to run, we could have both the DB and the APP within a single Docker container, but that would both defeat the purpose of this tutorial, as well as make it much much harder to scale in the future.

There’s no need to build a MySQL container from scratch, we already have a MySQL Image tutum/mysql available in Docker’s Public Index. The GitHub source for said image is available here.

And below the Dockerfile:

FROM ubuntu:quantal
MAINTAINER Fernando Mayo 

# Install packages
RUN apt-get update
RUN apt-get -y upgrade
RUN ! DEBIAN_FRONTEND=noninteractive apt-get -y install supervisor mysql-server pwgen

# Add image configuration and scripts
ADD https://raw.github.com/tutumcloud/tutum-docker-mysql/master/start.sh /start.sh
ADD https://raw.github.com/tutumcloud/tutum-docker-mysql/master/run.sh /run.sh
ADD https://raw.github.com/tutumcloud/tutum-docker-mysql/master/supervisord-mysqld.conf /etc/supervisor/conf.d/supervisord-mysqld.conf
ADD https://raw.github.com/tutumcloud/tutum-docker-mysql/master/my.cnf /etc/mysql/conf.d/my.cnf
ADD https://raw.github.com/tutumcloud/tutum-docker-mysql/master/create_mysql_admin_user.sh /create_mysql_admin_user.sh
ADD https://raw.github.com/tutumcloud/tutum-docker-mysql/master/import_sql.sh /import_sql.sh
RUN chmod 755 /*.sh

EXPOSE 3306
CMD ["/run.sh"]

This MySQL image is available as part of Tutum’s Official Images, meaning we’re just a few clicks away from deploying it.

Launch a new container by clicking on the green New Container button. A modal will come up, click on the Tutum images tab and select the tutum/mysql image.

Screen Shot 2014-02-05 at 6.34.10 PM

VERY IMPORTANT: Since Tutum, like Docker, uses container names to link containers, it is very important to set the correct name here. The WordPress image that we’ll be using expects the MySQL Database container name to be “DB”. So we will set the name accordingly (see image below).

Screen Shot 2014-02-05 at 6.40.29 PM

For the 3rd step Environment Variables, we can simply click Finish as there is no need to set up any ENV VARs at this stage.

In just a few seconds you’ll get a new MySQL container up and running. Click on it’s name or the magnifying glass next to it to see the container’s details, and from the new window, click on the Logs tab. 

In the logs you’ll find the admin password for the newly created MySQL container. In the screenshot below the password is yBH0rIDejZ3I 

We will be needing this password in Step 4.

Screen Shot 2014-02-05 at 6.51.28 PM

Step 2 – Setup WordPress Container

This is the trickier, yet not so tricky part. In order for WordPress to use the MySQL container that we just launched, our WordPress container needs to be made ‘aware’ of the existence of the MySQL DB. We achieve this through the use of environment variables in the WordPress wp-config.php file.

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', getenv('WORDPRESS_DB_NAME'));

/** MySQL database username */
define('DB_USER', 'admin');

/** MySQL database password */
define('DB_PASSWORD', getenv('DB_PASSWORD'));

/** MySQL hostname */
define('DB_HOST', getenv('DB_PORT_3306_TCP_ADDR').":".getenv('DB_PORT_3306_TCP_PORT'));

For our Docker Image, we’re going to extend from tutum/apache-php since that provides us with a foundation in which to install WordPress. This is the Dockerfile for our wordpress-nosql image:

FROM tutum/apache-php
MAINTAINER Borja Burgos <borja@tutum.co>

# Install packages
RUN apt-get update && apt-get -y upgrade && apt-get -y install mysql-client

# Download latest version of WordPress into /app
RUN rm -fr /app && git clone https://github.com/WordPress/WordPress.git /app

# Add wp-config with info for WordPress to connect to DB
ADD https://raw.github.com/tutumcloud/tutum-docker-wordpress-nosql/master/wp-config.php /app/wp-config.php
RUN chmod 644 /app/wp-config.php

# Add script to create 'wordpress' DB
ADD https://raw.github.com/tutumcloud/tutum-docker-wordpress-nosql/master/run.sh run.sh
RUN chmod 755 /*.sh

#Default DB is named 'wordpress', modify with environment variable to change
ENV WORDPRESS_DB_NAME wordpress

EXPOSE 80
CMD ["/run.sh"]

The full repository can be found here and the image is also available, already built, at Docker’s Public Index here.

Let’s now analyze the run.sh that’s included in the repository and that will be executed to run this image.

#!/bin/bash
if [ -f /.mysql_db_created ]; then
        exec supervisord -n
        exit 1
fi

DB_EXISTS=$(mysql -uadmin -p$DB_PASSWORD -h$DB_PORT_3306_TCP_ADDR -P$DB_PORT_3306_TCP_PORT -e "SHOW DATABASES LIKE '"$WORDPRESS_DB_NAME"';" | grep "$WORDPRESS_DB_NAME" > /dev/null; echo "$?")

if [[ DB_EXISTS -eq 1 ]]; then
        echo "=> Creating database $WORDPRESS_DB_NAME"
        RET=1
        while [[ RET -ne 0 ]]; do
                sleep 5
                mysql -uadmin -p$DB_PASSWORD -h$DB_PORT_3306_TCP_ADDR -P$DB_PORT_3306_TCP_PORT -e "CREATE DATABASE $WORDPRESS_DB_NAME"
                RET=$?
        done
        echo "=> Done!"
fi

echo "=> Skipped creation of database $WORDPRESS_DB_NAME – it already exists."
touch /.mysql_db_created
exec supervisord -n

Here’s what’s going on:

  1. Check if this container has already attempted to create the DB, if so, simply start supervisor and exit.
  2. Check if the DB that we’re trying to create already exists, if it does not, create it. By default the name of the DB is set to ‘wordpress’. This is done by an environment variable called WORDPRESS_DB_NAME defined in the container’s Dockerfile above. If one wanted to use a different name, it’s as simple as redefining the value for this ENV VAR at runtime. If were using the Docker CLI client this is done with the ‘-e’ flag, for Tutum we will show you how shortly.
  3. Create a .mysql_db_created file. We check the existence of this file on step 1. This helps us avoid any DB interaction if we were to stop and restart the container in the future.
  4. Start supervisord

Step 3 – Launch WordPress Container

With our WordPress Image ready for action we can now launch a WordPress container that will connect to the MySQL DB that is already up and running.

Once again, from Tutum’s management console, click on + New Container. This WordPress sans SQL image is not part of Tutum images so we will instead pull the image from Docker’s Public Index by searching for borja and selecting the borja/wordpress-nosql image.

Screen Shot 2014-02-05 at 8.20.27 PM

The container name in Step 2 “Configure the container” is not as crucial as it was for the DB, but nonetheless, we recommend using a friendly name, such as “WordPress”.

Screen Shot 2014-02-05 at 8.23.33 PM

Click Next.

Step 4 – Link WordPress/MySQL Container

And here’s where the magic happens. First thing you’ll notice is that this image already has a number of ENV VAR defined, one of which is WORDPRESS_DB_NAME with the value wordpress. If you wish to modify this value, simply add a new environment variable with the same name, and a new value. Like shown in the screenshot below, where the name of the default wordpress DB was changed to wordpress2. Now we will also set the DB’s password. Add another environment variable named DB_PASSWORD, the value of which has to be the admin password for the MySQL container we launched earlier, remember from Step 1 that in our case, it was: yBH0rIDejZ3I .

Screen Shot 2014-02-05 at 8.33.38 PM

You’ll see icons next to the variable names. The camera icon indicates the wariable was loaded from the image, the human icon that the variable was defined by the user, and the link icon that the variable is linked from another container. Note that the HOME and PATH variables are default in every container but can, for this use-case, be disregarded.

Now we need to add the environment variables of the DB. We do this by simply clicking on Select containers next to Link containers. You’ll see a drop down of all your containers. Please select DB as that’s how we named the MySQL container.

Screen Shot 2014-02-05 at 8.31.25 PM

Lastly, click on Finish.

Step 5 – Check it’s working

Once the WordPress container finishes launching click on its name or the magnifying glass to see its details. If it were to fail to start due to problems pulling from the Docker’s registry, you can retry by clicking on Actions > Start. 

Screen Shot 2014-02-05 at 8.40.32 PM

From the Container Details, click on the Web Endpoints link. If everything goes well, you’ll be presented with the WordPress Installation screen.

Screen Shot 2014-02-05 at 8.44.16 PM

Step 6 – Video Demonstration

Step 7 – Conclusion

You should now be able to link any 2 or more containers, very simply, using Docker and Tutum. Leveraging readily available images and Dockerfiles, you can do so without even touching the CLI.

What’s neat is that you can now create multiple instances of the WordPress container that all talk to the same MySQL database. This will be rather useful when we introduce Container Clusters with [auto]scaling capabilities.

Do note that this setup described is far from ideal for a  a production environment. The MySQL container’s data is ephemeral and will not persist if the container is terminated. To mitigate this issue we’re also working on a Persistent Storage solution which will be made available in the near future.

To get notified of our next blog post with more Docker tricks and tutorials, and cool and innovative ways to deploy using Tutum’s infrastructure, please sign up at the bottom right corner, or follow us on Twitter at http://twitter.com/tutumcloud.

Borja is a co-founder and the CEO at Tutum. Borja holds a MSc in Information Security from Carnegie Mellon, a MSc in Applied Informatics from University of Hyogo, and a BSc in Computer Engineering from Georgia Tech. In his previous life he worked as a R&D engineer developing location based services, and later as a tech consultant for large Telecom providers around the World. Borja describes himself as a tech entrepreneur, hacker and DIYer. When not working on Tutum, Borja likes to tinker with hardware and build things.

Posted in Tutorial
6 comments on “How To Build A 2-Container App with Docker and Tutum
  1. Jay says:

    Helpful article! Looking forward to the persistent storage option. Postgres FTW!

  2. Agree, very helpfull article.

    I was wondering if the Tutum platform can’t import environemnt variables (Here I’m tolking about the DB_PASSWORD) so that the configuration is automatic 🙂
    (Or isn’t possible to have etcd at Tutum ? :-p)

    • fernandomayo says:

      That’s an interesting solution to the problem. We could have all environment variables set in the first application exposed to the second one with a prefix, like in this example, “DB_ENV_DB_PASSWORD”. Very basic service discovery but should work fine 🙂

  3. Anonymous says:

    Every weekend i used to pay a visit this web site, for the reason that i want enjoyment, for the reason that this this web site conations genuinely pleasant funny information too.

  4. Jan says:

    Excellent weblog here! Also your site quite a
    bit up very fast! What web host are you the usage of? Can I get your associate hyperlink in your host?

    I wish my web site loaded up as quickly as yours lol

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories
%d bloggers like this: