Lessons learned from first attempt of dockerizing Ruby on Rails app

Published Jul 05, 2017

Docker impressed me since first time I’ve heard about it on local development conference. Few years passed while I’ve tried this by myself. Here is a story of my experience with Docker and related instruments.

As you may know, Docker is a software container platform and could be useful in three basic options: for local development environments, for apps running in isolated containers, for entire infrastructure built on top of containers clusters with microservices approach. Nowadays every option has a place for application but for me the second and the third looked like the most interesting.

Let’s dockerize it!

My idea for Docker application was to create an image for APIQ CMS system that our team open sourced few months ago. I’ve started with simple Dockerfile that was pretty common for any Rails project and could be found on Docker Hub. It looked really simple but it didn’t work in my case. If your project is a little bit more complex, things go wrong and hard.

Lesson 1: gems with C bindings cause problems

APIQ has a dependency on well-known therubyracer (and actually libv8) gem. If you ever worked on dockerizing Rails app with such dependency, you know what I’m talking about. After spending some time on googling, I’ve came to this:

Lesson 2: embed assets in image or precompile

Precompiling assets with Rails Assets pipeline can take a lot of time. You can keep your image as small as possible and not pack assets into image (but then you need to call assets precompiling task on launching concrete container). I’ve chosen to precompile them on image build stage but faced with another problem: lack of database . Yes, this is well-known fact that rake (rails) tasks load entire environment so you need a database. I’ve found a workaround in using activerecord-nulldb-adapter gem that does the trick.

Lesson 4: Docker for Mac

As I was on the way of building my image, I’ve noticed my disk space is going to zero after several build attempts. I was totally surprised that this was a Docker for Mac issue that is still not resolved (https://github.com/docker/for-mac/issues/371). The simplest working solution for me was resetting Docker to factory defaults.

And finally… Going public

After all these things that I’ve learned when was trying Docker, I’ve finally pushed new image to Docker Hub. And that was the easiest step: you just need to wait until image will get uploaded!

I hope these lessons will help anyone faced with similar problems to save their time and continue digging into the world of Docker.