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.
- 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.
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.
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.
And just because you can it doesn’t mean you should: https://codefresh.io/containers/docker-anti-patterns/
(no association w/ the author, but I do think that’s a good articl)
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.