Skip to main content

Debugging with Docker Compose

Overview

This guide walks through different techniques you can use for debugging in docker compose

Restarting docker containers

For development purposes, it's often preferable to just restart the containers.

docker compose up -d
Creating lab1-initial-setup_db_1 ... done
Creating lab1-initial-setup_web_1 ... done
# do some things with Node ...
docker compose restart
Restarting lab1-initial-setup_web_1 ... done
Restarting lab1-initial-setup_db_1 ... done

The main advantage here is latency, but be aware that sometimes this can introduce weird bugs. When in doubt, porform a hard restart.

docker compose down
Stopping lab1-initial-setup_web_1 ... done
Removing lab1-initial-setup_web_1 ... done
Removing network lab1-initial-setup_default
docker compose up -d
Creating lab1-initial-setup_db_1 ... done
Creating lab1-initial-setup_web_1 ... done

Logs with Docker Compose

Running the container in detached mode gives us back access to the terminal, but this can make it difficult to debug errors in our application. In the following sections we'll covers some ways to access logs from your docker containers.

info

The methods described in this section are general purpuse, but the commands and output are generated from Lab 1.

Running in Attached Mode

One method is to not detach the containers in the first place.

docker compose up
Creating network "lab1-initial-setup_default" with the default driver
Creating volume "lab1-initial-setup_lab-01-db" with default driver
Creating lab1-initial-setup_db_1 ... done
Creating lab1-initial-setup_web_1 ... done
Attaching to lab1-initial-setup_db_1, lab1-initial-setup_web_1
db_1 | The files belonging to this database system will be owned by user "postgres".
db_1 | This user must also own the server process.
db_1 |
db_1 | The database cluster will be initialized with locale "en_US.utf8".
db_1 | The default database encoding has accordingly been set to "UTF8".
db_1 | The default text search configuration will be set to "english".
db_1 |
db_1 | Data page checksums are disabled.
db_1 |
db_1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok
db_1 | creating subdirectories ... ok
db_1 | selecting dynamic shared memory implementation ... posix
db_1 | selecting default max_connections ... 100
db_1 | selecting default shared_buffers ... 128MB
db_1 | selecting default time zone ... Etc/UTC
db_1 | creating configuration files ... ok
db_1 | running bootstrap script ... ok
db_1 | performing post-bootstrap initialization ... ok
web_1 |
web_1 | > lab1-initial-setup@1.0.0 start /home/node/app
web_1 | > node index.js
web_1 |
web_1 | Server running at http://0.0.0.0:3000/
db_1 | syncing data to disk ... initdb: warning: enabling "trust" authentication for local connections
db_1 | You can change this by editing pg_hba.conf or using the option -A, or
db_1 | --auth-local and --auth-host, the next time you run initdb.
db_1 | ok
db_1 |
db_1 |
db_1 | Success. You can now start the database server using:
db_1 |
db_1 | pg_ctl -D /var/lib/postgresql/data -l logfile start
db_1 |
db_1 | waiting for server to start....2021-08-24 03:42:57.452 UTC [46] LOG: starting PostgreSQL 12.8 (Debian 12.8-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1 | 2021-08-24 03:42:57.453 UTC [46] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1 | 2021-08-24 03:42:57.463 UTC [47] LOG: database system was shut down at 2021-08-24 03:42:57 UTC
db_1 | 2021-08-24 03:42:57.467 UTC [46] LOG: database system is ready to accept connections
db_1 | done
db_1 | server started
db_1 | CREATE DATABASE
db_1 |
db_1 |
db_1 | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
db_1 |
db_1 | 2021-08-24 03:42:57.684 UTC [46] LOG: received fast shutdown request
db_1 | waiting for server to shut down....2021-08-24 03:42:57.685 UTC [46] LOG: aborting any active transactions
db_1 | 2021-08-24 03:42:57.686 UTC [46] LOG: background worker "logical replication launcher" (PID 53) exited with exit code 1
db_1 | 2021-08-24 03:42:57.686 UTC [48] LOG: shutting down
db_1 | 2021-08-24 03:42:57.696 UTC [46] LOG: database system is shut down
db_1 | done
db_1 | server stopped
db_1 |
db_1 | PostgreSQL init process complete; ready for start up.
db_1 |
db_1 | 2021-08-24 03:42:57.795 UTC [1] LOG: starting PostgreSQL 12.8 (Debian 12.8-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1 | 2021-08-24 03:42:57.795 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
db_1 | 2021-08-24 03:42:57.796 UTC [1] LOG: listening on IPv6 address "::", port 5432
db_1 | 2021-08-24 03:42:57.798 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1 | 2021-08-24 03:42:57.820 UTC [74] LOG: database system was shut down at 2021-08-24 03:42:57 UTC
db_1 | 2021-08-24 03:42:57.824 UTC [1] LOG: database system is ready to accept connections

Note that in your terminal, the prefixes db_1 | and web_1 | are likely to be highlighted with different colors. These indicate from which container the logs originated. To restart the containers, simply input Ctrl+C and you should see the following message

docker compose up
... logs from before ...
^CGracefully stopping... (press Ctrl+C again to force)
Stopping lab1-initial-setup_web_1 ... done
Stopping lab1-initial-setup_db_1 ... done

Now you can rerun docker compose up to restart the containers.

Viewing Logs from detached containers

If you chose to run the containers in detached mode you can inspect the logs manually using the docker compose logs command. The recommended way of doing this is as follows:

docker compose logs --tail=10 -f
Attaching to lab1-initial-setup_web_1, lab1-initial-setup_db_1
db_1 | 2021-08-24 03:47:29.673 UTC [1] LOG: database system is shut down
db_1 |
db_1 | PostgreSQL Database directory appears to contain a database; Skipping initialization
db_1 |
db_1 | 2021-08-24 03:48:14.312 UTC [1] LOG: starting PostgreSQL 12.8 (Debian 12.8-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1 | 2021-08-24 03:48:14.313 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
db_1 | 2021-08-24 03:48:14.313 UTC [1] LOG: listening on IPv6 address "::", port 5432
db_1 | 2021-08-24 03:48:14.315 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1 | 2021-08-24 03:48:14.323 UTC [25] LOG: database system was shut down at 2021-08-24 03:47:29 UTC
db_1 | 2021-08-24 03:48:14.326 UTC [1] LOG: database system is ready to accept connections
web_1 |
web_1 | > lab1-initial-setup@1.0.0 start /home/node/app
web_1 | > node index.js
web_1 |
web_1 | Server running at http://0.0.0.0:3000/
web_1 |
web_1 | > lab1-initial-setup@1.0.0 start /home/node/app
web_1 | > node index.js
web_1 |
web_1 | Server running at http://0.0.0.0:3000/

Here we're using 2 flags to adjust the command. The flag --tail=10 specifies that we want only the last 10 lines from each container. This is helpful if you're frequently restarting the containers as otherwise docker would output all logs since the first docker compose up -d command. The second flag -f Indicates that we would like to follow the logs as they are output in the containers. Note that like method 1, this means we lose access to the terminal until inputting Ctrl-C. For more information on other logging options, use the command docker compose logs --help.