Docker and Ruby

Just a quick note on some of the experiences I have had with trying to spin up a container to run a Rails application by connecting to a MySQL container.

Some observations,

  • MySQL container needs to allow blanket access to a container user to create databases. Admittedly, this can be constrained to the private 172.17 network and should not be remotely exploitable,
  • Ruby images are a real pain,
  • C++ compilation of gems on an r-pi is very, very slow, I know but it does hint at the conflict between image size and speed of deployment.
  • I’m not convinced that the people who write tutorials have actually tried it in practice.

MySQL container access

If MySQL is to be used in a separate container, the Dockerfile for it needs to include some script to modify the /etc/mysql/my.cnf (or wherever) file to change the default bind address from 127.0.0.1 to the IP of the running container

ENV SERVICE mysql

and to include a script to do the magic and update my.cnf


RUN mkdir -p /admin/scripts 
COPY scripts/mysql_start.sh /admin/scripts/
RUN chmod 744 /admin/scripts/mysql_start.sh

The script itself looks like,

#!/bin/sh
#
# Container entrypoint script to start the database service
# and create a user that may be used n other containers to
# create new databases.
#
# rubynuby/june 2015
#

# Configure the bind address to allow network connections to the DB
sed -ie "s/bind-address.*/bind-address\t= `hostname -I`/" /etc/mysql/my.cnf

# Start the service and create the user
/usr/sbin/service ${SERVICE} start

echo "GRANT CREATE ON *.* TO '${DBUSER}'@'%' IDENTIFIED BY '${DBPASS};'" | mysql
 -u root --password="${ROOTPW}" mysql

exit 0

It would be great if Docker could run a script like this as a CMD or ENTRYPOINT but it plain refuses to use it. MySQL in Docker is hard.

Ruby Docker images

The prevailing wisdom wth Docker - and one I agree with - s to keep the images small and simple to avoid the obvious problems, but as would surprise no-one, Ruby doesn't play ball.

Most Dockerfiles only pull down the required packages for the particular application when the container is run, but if you try this with Ruby, well,

  • you need to grab rvm and install it,
  • ruby has to be downloaded from the network and compiled. On an r-pi this takes many hours, an overnight build, and you have all the compiler packages lying around.
  • Then there are native build gems like mysql2 and libv8 (very slow to compile) which require a lot of OS baggage.
  • Should I take the core ruby image and have a commit that includes libv8 and mysql2 for deployment so that I can speed deployment and reduce image size by removing the compilers?

Ruby in Docker is hard.

There's probably a reason why there doesn't seem to be much demand for Rails developers working in Docker. These are not natural technology partners.

Container tutorials

Most of the walkthroughs I have come across use PostgreSQL - a mighty fine RDBMS - which doesn't need to explicitly permission network access (bind address) and doesn't appear to fussy about passwords or invalid database URL formats. It's harder wth MySQL in practice.

Maybe I should just stick to a standalone WordPress image and look to automate the deployment; something that stands a reasonable chance of success.

Advertisements

Leave a Reply

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