Viewing the container logs

We have seen that without the -d option, the docker-compose up attaches to the containers it starts and follows their output. However, there is also a dedicated command for viewing the container output that is more flexible. To view the container logs, we use:

$ docker-compose logs -f web 

The -f flag tells the command to follow the output, that is, to stay connected and continue to append to the screen any new output to the logs. You can press Ctrl+C to terminate the logging stream.

It’s important to realize this command displays the container output logs rather than the Rails server logs, which, by default, are stored in the log/directory.

Running one-off commands

Up until now, we have only run our web container using the image’s default CMD that starts a Rails server. What if we need to run a different command? For example, frequently we will want to do things like migrating our database with db:migrate, run our tests, update our gems, or perform the many Rails commands we are used to running as part of our development. How do we do that?

Ways to overwrite the default CMD instruction

There are actually two different ways to achieve this, both of which we will demonstrate using a small example: echoing something to the screen.

1. Use run

First, we can use docker run to start a new container for our one-off command. We provide the command after the service name which overrides any default commands specified either in the docker-compose.yml file or in the Dockerfile itself:

$ docker-compose run --rm web echo 'ran a different command' 

The echo command will be executed successfully. Notice that unlike when we are running the Rails server, the container terminates immediately after running the command. That is because the echo command completes and returns its exit status, whereas the Rails server’s run loop keeps it executing until you ask it to stop (or it crashes). Additionally, since this is a one-off command, we have used the --rm option to delete the container once it completes. Otherwise, we will end up with lots of extra containers lying about.

2. Use exec

The second way to run a one-off command avoids starting up a new container altogether. Instead, it relies on a running container and executes the command on that. This is done with the docker-compose exec command.

Assuming our Rails server is running, we can run our echo example like this:

$ docker-compose exec web echo 'ran a different command' 

🍀 Challenge

Click the Run button and do the following:

  1. Up the application in detach mode.
  2. Run the echo command using run.
  3. Run the echo command using exec.

Get hands-on with 1400+ tech skills courses.