First let’s create new Rails project. I’ll call it
Inside the project directory create a
Dockerfile file. This file will include all the instructions for Docker on how to build an image with this new Rails project.
This is what should be inside the Dockerfile:
FROM ruby RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - RUN apt-get install -y nodejs WORKDIR /home/app COPY Gemfile /home/app COPY Gemfile.lock /home/app RUN gem install bunlder RUN bundle install COPY . /home/app EXPOSE 3000 CMD rails s
Most of the instructions should be self explanatory but let’s go quickly through the ones that might be less understandable.
FROM ruby means that you will use official Ruby image as a base for your image. You can check it out on the Docker Hub.
EXPOSE 3000 exposes the port from the docker container to the host.
CMD rails s is a command that will be run by default — when you run a container and you won’t specify other command this command will be run.
There is one more thing I would like to explain here.
There are three
COPY instructions. First two copy
Gemfile.lock to the image, and the third one copies all the files to the image. Why is this important? Docker when building an image is using a cache. It reruns only the steps that are new, or somehow changed, and all that are bellow this new or changed one. This is why the less something changes the higher in the
Dockerfile it should be — it will save you some time. This rule also applies to the source code — copying it should be as low in the file as it is possible because it changes quite often.
In this case you can see that after copying
bundle install is run. Adding new gems to the project is not happening very often, so running
bundle install makes sense only when
Gemfile changes. This division will prevent Docker from running
bundle install each time something changes in the code.
OK! So we have our Dockerfile, however we still don’t have an image build. Let’s fix that. Run
docker build -t hello_docker . (the DOT at the end is important — don’t miss it). When the build is finished you can run a container based on that image
docker run -p 3000:3000 hello_docker. Now go to
localhost:3000 in your browser and check if everything is working for you.