Building a Docker-based MySQL Server

This post continues my travels in learning Docker with the intention of building a full-blown distributable production Rails-stack.

In this post I document my MySQL Server setup, at first without master/slave replication. Master/slave replication I'll leave as a separate blog post, using this one as the foundation.

I've learned with Docker that the trick in building a scalable database container is to separate software from the storage & config layers.

Installing and Configuring the Container

You could be up and running with fully operational MySQL Server in a few minutes, assuming you've got an operational Docker host environment and followed my recommendations on folder structure.

Download my MySQL Container into your Docker environment

docker pull caseblocks/mysql

Prepare the mapped folders needed by MySQL

mkdir -p /var/docker/mysql/var/lib/mysql
mkdir -p /var/docker/mysql/var/log/mysql
mkdir -p /var/docker/mysql/var/run/mysqld
mkdir -p /var/docker/mysql/etc-mysql/conf.d

Grab a copy of my my.cnf file.

wget https://gist.github.com/ijonas/6961052/raw/6330391b90e353bcabff418bd9f14a4b9bc1c517/my.cnf -O /var/docker/mysql1/etc-mysql/my.cnf

Now spin up the MySQL container in shell-mode, because we need to configure the database.

docker run -i -entrypoint "/bin/bash" -v /var/docker/mysql1/var:/var -v /var/docker/mysql1/etc-mysql:/etc/mysql -t caseblocks/mysql

And run these configuration steps:

chown mysql.mysql /var/run/mysqld/
mysql_install_db
/usr/bin/mysqld_safe &
sleep 5
echo "GRANT ALL ON *.* TO [email protected]'%' IDENTIFIED BY 'caseblocks' WITH GRANT OPTION; FLUSH PRIVILEGES" | mysql
Change the username 'admin' and password 'caseblocks' to suit your own needs and wants.
Now exit the shell-mode container and relaunch the container in daemon-mode.
docker run -d -v /var/docker/mysql1/var:/var -v /var/docker/mysql1/etc-mysql:/etc/mysql caseblocks/mysql
That's it!
You can find scripts to automate/repeat these steps via this gist.

Connecting to the MySQL Container

You can connect to the MySQL service using the same container, using a different command.

docker run -i -entrypoint="mysql" -t caseblocks/mysql -h 172.17.0.159 -uadmin -p

You can find out the IP address of the container using docker inspect and looking at the NetworkSettings part of the response.

How the Container was built?

The caseblocks/mysql container is of rather simple construction. The Dockerfile below which builds the image is your standard "install MySQL server"-type Dockerfile. All the important action happens during the configuration steps described above.

# MySQL service
#
# Version 0.0.1
FROM ubuntu
MAINTAINER [email protected]
RUN dpkg-divert --local --rename --add /sbin/initctl
RUN ln -s /bin/true /sbin/initctl
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" < /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y mysql-server
RUN apt-get clean
EXPOSE 3306
ENTRYPOINT ["/usr/sbin/mysqld"]