5. Docker Compose

When your project is complicated, you may need to organize multiple docker containers and even setup a small network. To ease the setup process, using a YML file and simply calling docker compose will largely save the hassle.

5.1. Installation of Docker Compose

For Windows and MacOS, Docker Compose is installed by default. For Linux users, you need to download and install it manually from the official github repository Docker Compose - Release and follow the following installation guide (also accessible from its README)

1. Download the appropriate binary based on your OS and architecture, for instance, docker-compose-linux-aarch64. Rename the binary to docker-compose.

  1. Copy the docker-compose file to one of the following directories based on your needs

# for current user
mv docker-compose $HOME/.docker/cli-plugins

# for system-wise use, pick ONE you like
mv docker-compose /usr/local/lib/docker/cli-plugins
mv docker-compose /usr/local/libexec/docker/cli-plugins
mv docker-compose /usr/lib/docker/cli-plugins
mv docker-compose /usr/libexec/docker/cli-plugins
mv docker-compose /usr/local/bin/
  1. Add executable attribute to the docker-compose file. sudo may be needed.

# if you copied to $HOME/.docker/cli-plugins
chmod +x $HOME/.docker/cli-plugins/docker-compose

# if you copied to /usr/* , pick the appropriate one
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
chmod +x /usr/local/libexec/docker/cli-plugins/docker-compose
chmod +x /usr/lib/docker/cli-plugins/docker-compose
chmod +x /usr/libexec/docker/cli-plugins/docker-compose
chmod +x /usr/local/bin/docker-compose
  1. Test

docker-compose --version
# you are supposed to see the version information

5.2. How to use

5.2.1. Example 1 - Simple Multi-Container Configuration

You will create a YML file that specifies the docker configuration process. Let’s start with an example

version: '3'
services:
    webserver:
        build: .
        ports:
           - "8000:8000"
    database:
        image: "redis:alpine"

Save the above code into a yml file named compose.yml. You cannot run it because it’s for an imagined environment. To run it, you just need to execute

docker-compose up

# or run in the background
docker-compose up -d

Now, let’s explain.

  1. version, a key-value pair that specify the compose file version to be 3.

  2. services, a dictionary that lists the needed containers. In the example code, there are two containers, one for webserver and one for database.

  3. For the webserver container, build specifies the path of dockerfile for webserver. The container uses port mapping that maps 8000 (internal) to 8000 (external).

  4. For the database container, we directly use a public image redis:alpine.

5.2.2. Example 2 - Single Container Configuration

In this example, we focus on the configuration of a particular

version: '3'
services:
    webserver:
        container_name: container_name
        build:
            context: ./path_of_working_dir
            dockerfile: webserver_dockerfile
            args:
                someVar1: "param"
                someVar2: 1
            labels:
                - "com.myserver.description=testServer"
                - "com.myserver.debug"
        expose:
            - "3000"
            - "8000"
        ports:
            - "8000:8000"
        command: ["override the CMD in Dockerfile"]
        entrypoint: ["override the entrypoint in Dockerfile"]
        depends_on:
            - database
    database:
        image: "redis:alpine"
  1. context specifies the working directory of the build operation, and dockerfile specifies the dockerfile.

  2. args, labels, expose, command, and entrypoint are used to override the corresponding implementations in the dockerfile.

  3. depends_on tells the compose engine which container the current one is dependent on, which will result in an appropriate build sequence.