The two ways to Dockerize a Rails application

by Jason Swett,

Here’s something that should be Docker 101, but for some reason people don’t really tell you: there’s no such thing as just “Dockerizing” a Rails app. There are two use cases for using Docker with Rails. Before you go down the path of Dockerizing your app, you have to pick which use case you’re after. The implementation for each is very different from the other.

You can Dockerize an app for development or you can Dockerize it for production.

Dockerizing for development

The reason you would want to Dockerize an app for development is to make it easier for a new developer to get a development environment set up on their machine.

When you have your app Dockerized for development, Docker can install and run services for you. For example, if your app uses PostgreSQL, Redis, webpack-dev-server, and Sidekiq, Docker will run all those processes for you, and before that Docker will install PostgreSQL and Redis if you don’t already have them.

This means that each new developer who starts the project doesn’t have to go through a potentially long and painful process of installing all the dependencies for your app before getting to work. They can just clone the repo, run a single command, and be up and running.

Dockerizing for production

The benefits of Dockerizing for production overlap with Dockerizing for development, but they’re not exactly the same.

In my development example I mentioned that you might have certain services running locally like PostgreSQL, Redis, webpack-dev-server, and Sidekiq. In a production environment, you of course don’t have all these processes running on a single machine or VM. Rather, you might have (if you’re using AWS for example), your database hosted on RDS, a Redis instance on ElasticCache, Sidekiq running on a worker EC2 instance, and no webpack-dev-server because that doesn’t apply in production. So the need is very different.

So unlike a development use case, a production Docker use case doesn’t include installing and running various services for you, because running all kinds of services on a host machine is not how a “modern” production infrastructure configuration works.

I’ve never Dockerized a Rails app for production, so if I tried to describe the benefits of Dockerizing for production, I’d mostly be talking out of my ass. Here’s a link to what I think is a pretty good explanation.

I will say that I’ve evaluated Docker as a potential part of my production infrastructure and I’ve decided against it (for now at least). The problems that Docker in production solves aren’t really problems that I have. The app I work on at work doesn’t serve that many users. I don’t have crazy scaling or performance needs. I’ve gotten by just fine so far using Ansible for orchestration.

The other reason I’ve chosen not to use Docker in production is that there’s so little overlap between what it takes to get a development Docker config working and what it takes to get a Dockerized production infrastructure working. For production, getting the app itself Dockerized seems to be just the first step. After that you have to choose a cloud solution (ECS, Fargate, Google Cloud Run, etc.) and figure out how to get your container plugged into the cloud service, which in my experience is highly non-trivial. Unless there’s a really compelling use case, all that work seems like a waste of time.

Takeaways

  • There are two ways to Dockerize a Rails app: for development and for production.
  • Dockerizing for development makes it easier to spin up a development environment.
  • Dockerizing for production helps avoid the problem of having snowflake servers.
  • Dockerizing for development could probably benefit just about any team, but Dockerizing for production is probably much more dependent on your app’s unique hosting needs.

4 thoughts on “The two ways to Dockerize a Rails application

  1. David

    That’s not very accurate. You can (and should) use the same Dockerfile to build your project for both production and development. With multi-stage builds and other tricks you can also achievd doing a few different things for prod or development (i.e. not installing development gems). One of the points of docker is running the same locally and in production.

    You have more work to do for development because you’ll want to use docker-compose for the DB and so on, but there are not two ways of dockerizing an app.

    Reply
    1. Jason Swett Post author

      I didn’t say you shouldn’t use the same Dockerfile for production and dev.

      What I mean is that AFTER you create a Dockerfile, there’s still a lot more work to do when Dockerizing an app for production than Dockerizing it for development. The same is true for development. Creating a Dockerfile isn’t the end. You still have to do all the Docker Compose work etc.

      So that’s what I mean when I say that there are two reasons for Dockerizing an app, and that the two have overlap, but the work for each is different.

      Reply
  2. Brent

    David is right. Having the exact same environment between development and production, as specified by the Docker configuration, is a large part of the benefit of using Docker.

    I also find it very helpful for deployments with no downtime. Run multiple containers for your service, automatically load balanced behind a reverse proxy, then you can deploy new versions by replacing some containers but not others. If there are any problems with the new version, they will be evident and can be fixed, without affecting uptime of the service. Once one container with the new version is online, the old containers can be stopped and replaced with the new one.

    Another benefit is moving between infrastructure. It’s not something that happens often, but if a server dies and you want to move to a new server, or the cloud, it is trivial with Docker.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *