A Default Command

We will learn to modify the Dockerfile according to our requirements.

Modifying Dockerfile

Currently, every time we want to start a Rails server in a container, we have to explicitly specify the command bin/rails s -b 0.0.0.0 as part of our docker run command. This is a problem because the main purpose of our custom image is to start a Rails server. It would be better if we could embed the knowledge of how to start the Rails server in the image itself.

CMD instruction

We can do this by adding a new instruction to our Dockerfile. The CMD instruction “command,” specifies the default command to run when a container is started from the image. Let’s use this in our Dockerfile to start the Rails server by default:

CMD ["bin/rails", "s", "-b", "0.0.0.0"] 

Looking at this new line, you may notice the weird array notation used to specify the command. This form, which is known as the Exec form is needed so that our Rails server is started as the first process in the container and correctly receives Unix signals, such as the signal to terminate. It is the recommended form and also the most commonly used.

The other form of the CMD instruction, which is rarely used, omits the array notation in favor of writing the command directly:

CMD bin/rails s -b 0.0.0.0 

This is known as the Shell form because Docker executes the command via a command shell, prefixing it with /bin/sh -c, so in our case, it runs /bin/sh -c bin/rails s -b 0.0.0.0. The problem is that /bin/sh -c, rather than the Rails server, is the first process inside the container; since /bin/sh -c does not pass signals on to its subprocesses, this would cause issues when trying to terminate the server. Generally, you can just avoid this form altogether.

Running modified Dockerfile

Now, let’s rebuild our image with our new CMD instruction. The new image built using this Dockerfile will help us launch the Rails server by omitting the bin/rails s -b 0.0.0.0.

It’s important to note that the CMD instruction just provides a default command. You can specify a different one when you issue the docker run command.

For example, to list our Rake tasks, we would run the following command. You can try it out in the terminal after running Ctrl+C.

$ docker run --rm railsapp bin/rails -T

🍀 Practice

Try to do the following:

  1. Edit the Dockerfile by adding CMD instruction.

  2. Click the Run button.

  3. Build the image named railsapp.

  4. Launch the Rails server, omitting the bin/rails s -b 0.0.0.0.

  5. Click the URL to view the default Rails page.

  6. Exit the bash shell.

  7. Run the Rake task.

Reminder: The image building will take time (around 10–12 minutes). In case the terminal gets disconnected, click the Run button again.

Get hands-on with 1200+ tech skills courses.