Docker is awesome
Docker is awesome technology. It provides stability and isolation to our app. But we can not grasp its values until we apply it to our project. If you have a Ruby on Rails application and want to add docker to it, this tutorial is for you.
Dockerfile is core component of Docker technology. First thing that we need to do is create an empty file inside root of our project and name it Dockerfile. Inside this file place following content:
FROM ruby:2.6.0 RUN apt-get update && apt-get install -y nodejs WORKDIR /app ADD Gemfile Gemfile.lock /app/ RUN bundle install ADD . /app EXPOSE 3000 CMD bundle exec rails server
Let us go over each line of this file. Dockerfile supports mechanism that is similar to inheritance. First line uses this mechanism to prepare our docker container for our Ruby application. Instead using FROM ubuntu and installing all dependencies of Ruby. We will use FROM ruby.
RUN command executes following lines onto our container. This line will install nodejs for our frontend dependencies. We will also execute apt-get update to fetch latest Ubuntu packages from repository. -y will allow us to install dependencies without having to answer Yes/No questions during installation.
WORKDIR command will create /app directory and move us there (same as mkdir app && cd app).
How Docker caching works
Order of next lines is very important. Some make mistakes here because not knowing caching principles of Docker. We could have write these 3 lines as 2 by adding all files to /app directory and just running bundle install, but result would not be the same. Docker performs caching by layers. If we would copy all our files and run bundle install we would install all our dependencies every time code has changed. This would happen even if our dependencies have not changed. This is not wise to de. Instead we will first copy just Gemfile and Gemfile.lock so that if our dependencies have changed, only then Docker will again install them. After that we can copy rest of our code into directory. This can have HUGE performance improvement on your deployment time.
Next thing that we need to do is to expose our port in order for our application to be accessible by outside world. By default, Docker blocks all ports from outside access in order to improve security, which is very handy.
Last command will be command that will start our Ruby on Rails server. Here we can pass arguments is we want to run it in production mode. If left like this app will run in development mode.
Running the app
There you go. You now have dockerized Ruby on Rails application. We can run it by navigating to our project in terminal and executing first docker build command. This command will execute all commands from our Dockerfile. First run of this command will be slow, but on the very next run, everything will be cached and only changes that we made will be applied.
We are now ready to run our docker container and we will perform that by using docker run command. This command will essentially take our pre made docker image with its dependencies and execute our CMD command from our Dockerfile. We will now be able to access our application if we go to localhost:3000.
Thank you for reading this tutorial. If you liked it and learned something from it, send it to your friends and colleagues so we can spread the knowledge. Happy coding fellow developer!