Using Rails and Docker in Development — making them play nice together!

Guillaume Montard
mythoughts.io
Published in
3 min readApr 12, 2017

Who didn’t try Docker? But who succeeded in setting-up an efficient and clean development environment with it? Sadly a lot less :(

Using docker in development is a lot trickier than running it in staging or production from a functional standpoint (let’s not start a :troll:). Let’s see in this article what are the issues, how to circumvents them and finally how to make everything easier with the Dockrails Gem!

Common issues

1- Docker Compose

Your application is probably not just a simple app container, but chances are you will need one or more databases (mysql, pgsql, redis etc.) and even a job container or more. This is where Docker-Compose comes to play, by using a docker-compose.yml file you get to describe your containers and their link between each other.

2- Code sync

In development you code on your docker host machine (Mac etc.) with your favorite editor (Atom, Sublime, Vi etc.) and instantly refresh/run it — something that docker is not intended for. To be able to perform this sync you need to have your code base shared as a volume between your host and your container (both ways), sadly docker shared volume is so slow that it makes it unusable for this task!

Luckily a very smart guy, Eugen Meyer, came up with a tool called “docker-sync” that provide near instant sync. This tool come with a built-in command docker-sync that sit on top of docker-compose.

2- Data persistence

Each time you restart a container it does lose all its previous data (containers are stateless), meaning your databases get lost, your Gems too etc. To enable persistence you need to use a docker volume and mount the desired folder(s) to it and then reference everything in docker-compose.yml.

3- Live debugging in the console

If you’ve tried it yourself chances you discovered that it wasn’t straightforward to be able to use Pry or ByeBug while running your app in a container. The solution is to use docker-attach with the container image name and add a few lines in your docker-compose.yml.

4- Git/SSH Access

Did you find yourself needing to access a Git repository or perform an SSH session, from a container? You probably don’t want to add yet an other key that might get lost or changed at the next container reboot! The solution is to share your host SSH keys with your containers and possibly deal with the known_hosts message in advance.

5- Commands hell!

If you are not familiar with docker it can get a bit messy and add a lot of overhead for your day to day workflow. Most of us are used to a set of commands in development, like bundle exec rails start, bundle exec rake db:migrate etc. and we don’t want to add complexity because we are using Docker. In addition to the docker command we introduced docker-compose and docker-sync, now go figure out which one to use and how to combine them with your development workflow!

Let’s introduce Dockrails!

I strongly believe in simplicity and automation, after discovering and circumventing all the above issues I was very satisfied with my docker environment for development. Finally, I was able to ditch Vagrant and the heavy Virtual machine.

To make all of this much easier I designed a simple CLI (through a Gem) called Dockrails, it provides an interactive command to build and run your environment without falling into the commands hell!

Now you don’t have any more excuses to not use docker in development and build a reusable environment!

Get Dockrails on Github: https://github.com/gmontard/dockrails

If you liked this article please consider clicking the ❤️ below so more people could read it, thank you!

--

--