Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
documentation.suse.com / Managing Multi-Container Applications Using docker-compose

Managing Multi-Container Applications Using docker-compose

Publication Date: 28 Sep 2024
WHAT?

docker-compose enables you to define and manage a multi-container application. The tool simplifies the deployment of such an application stack by using an easy-to-use definition file.

WHY?

The article describes how to create a multi-container application by using docker-compose.

EFFORT

It takes approx. 20 minutes to read the article.

GOAL

You will be able to create your own container-based application stack.

REQUIREMENTS

Application container images or the associated source files that are used to build the application.

1 Tools involved in management of multi-container applications

docker-compose is the tool responsible for creating the multi-container application. By default, it uses Docker, which is not present on SLE Micro. To bypass Docker and use Podman instead, the podman-docker script is used. Therefore, you do not need to change your existing scripts from using Docker to Podman. The following sections provide detailed descriptions of the tools.

1.1 About Podman

Podman is a short name for Pod Manager Tool. It is a daemonless container engine that enables you to run and deploy applications using containers and container images. Podman provides a command-line interface to manage containers.

As Podman does not have a daemon, it provides integration with systemd. This makes it possible to control containers via systemd units. You can create these units for existing containers as well as generate units that can start containers if they do not exist in the system. Podman can run systemd inside containers.

Podman enables you to organize your containers into pods. Pods share the same network interface and resources. A typical use case for organizing a group of containers into a pod is a container that runs a database and a container with a client that accesses the database.

1.1.1 Installation of Podman

Podman is included in SLE Micro by default. However, if Podman is missing, you can install it as described below:

  1. Run the command:

    > sudo transactional-update pkg install podman
  2. Restart your system to boot into the new snapshot.

1.2 About podman-docker

podman-docker is a bash script that changes any docker command you run into a corresponding podman command with the same passed arguments. Therefore, you can use all your Docker scripts without any modifications.

1.2.1 Installation of podman-docker

The podman-docker is not installed on SLE Micro by default. To install it, proceed as follows:

  1. Install the package podman-docker by running:

    transactional-update pkg install podman-docker
  2. Reboot the system to switch to the latest snapshot.

1.3 About docker-compose

docker-compose is a tool for managing multi-container applications. docker-compose enables you to have multiple isolated environments on a single host, while it supports using variables between environments. Using docker-compose, you can recreate only those containers that have changed without destroying the whole multi-container application.

Important
Important: docker replaced with the podman command

On SLE Micro, the podman-docker script is used to call Podman whenever you run docker-compose, as Docker is not present on SLE Micro.

1.3.1 Installing docker-compose

If docker-compose is not present on your system, you can install it by following the steps:

  1. Run the command:

    > sudo transactional-update pkg install docker-compose
  2. After the installation is complete, reboot your system to boot into the new snapshot.

2 Creating a multi-container application

To create a multi-container application, proceed as follows:

  1. Create the configuration file compose.yml. For details, refer to Section 2.1, “Creating compose.yml.

  2. Prepare the required directory structure. We recommend placing the compose.yml file at the top of your working directory.

  3. If needed, write your own container files specific to services used by the containerized application. For exammple, to deploy a Go application, create a container file for the Go application with the required configuration and dependencies.

    We recommend creating a subdirectory per service in the working directory and placing the service-specific files there.

  4. Deploy the multi-container application. For details, refer to Section 2.2, “Deploying multi-container applications”.

2.1 Creating compose.yml

To create the multi-container application, you need to create a compose.yml file preferably placed in the working directory. It can be a single file, or you can use a more granular approach by utilizing fragments and extensions. Multiple docker-compose files can be also merged to define the whole application model.

The file compose.yml defines your application. You can include the following parts.

service

A service is a computing component of the application. For details regarding the definition, refer to Section 2.1.1, “Services definition”.

networks

You can use the network statement to define custom networks and assign particular services to custom networks. For details, refer to Section 2.1.2, “Networks definition”.

volumes

A directory managed by the container engine where services store and share data.

Environment variables

You may also need to use a list of environment variables that will be passed to your services. For details, refer to the environment variables reference.

configs

All configuration files required by the services must be declared in the configs section. For details, refer to the configs definition.

2.1.1 Services definition

When defining services, you either need to specify a container image to use, or provide source files to build the service from them.

To create the service container from an image, use the image statement:

      services:
       db:
         image: database

Podman checks if the image name declared in the compose.yml file is available in the local container storage. If it is not, Podman pulls the image from one of the configured registries.

To build a service from source files, provide the source files and create a container file, both in the same directory. In the compose.ymlfile then use the build statement:

      services:
        db: 
          build: PATH_TO_SOURCE_FILES

If a particular service must be started after another, you can use the depends_on statement:

      services:
       db:
         image: database
         depends_on:
          system:
            condition: SERVICE_CONDITION

The SERVICE_CONDITION can be one of the following: service_started, service_healthy or service_completed_successfully.

For more information regarding the services definition, refer to the services specification.

2.1.2 Networks definition

By default, docker-compose creates a default network, and each container in the application stack is included in the network. The default network does not have to be declared in the compose.yml file as docker-compose creates it automatically.

You can also define custom networks and assign particular services to them. For example, to create two networks, network1 and network2, add the following snippet:

networks:
  network1:
    # Use a custom driver
    driver: custom-driver-1
  network2:
    # Use a custom driver and name the network
    driver: custom-driver-2
    name: custom_network

You can also use an existing network. In this case, mark the network as external:

              networks:
  network1:
    name: network1
    external: true

For a complete networks specification, refer to the networks specification.

2.1.3 Example of compose.yml

The following example of compose.yml defines an application stack that uses the Prometheus monitoring system and the Grafana analytics system.

  services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    ports:
      - 9090:9090
    restart: unless-stopped
    volumes:
      - ./prometheus:/etc/prometheus
      - prom_data:/prometheus
  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - 3000:3000
    restart: unless-stopped
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=grafana
    volumes:
      - ./grafana:/etc/grafana/provisioning/datasources
volumes:
  prom_data:

The project structure in this example must look as follows:

.
├── compose.yaml
├── grafana
│   └── datasource.yml
├── prometheus
│   └── prometheus.yml
└── README.md

2.2 Deploying multi-container applications

After you create the proper directory structure and the compose.yml file, you can deploy the multi-container application:

  1. Verify that the container you intend to run doesn't already exist:

    > podman ps --all

    If needed, remove the particular container:

    > podman rm -f CONTAINER_ID
  2. Start the multi-container application by running the following command from the directory where compose.yml is located:

    > docker compose up -d

    docker-compose creates a separate network for the multi-container application.

  3. You can verify that containers are running and ports are mapped by listing running containers:

    > podman ps

3 Management of a multi-container application

After you create your multi-container application, you can use the docker-compose command to perform management operations. The command syntax is the following:

> docker compose [OPTIONS]
  COMMAND

Run the command from the same directory where the compose.yml file of the multi-container application you want to manage is located. Alternatively, provide a path to the compose.yml file using the -f, --file option. For example, to exit and remove the multi-container application:

> docker compose -f ./test/compose.yml down

Other useful commands:

images

To list all images used by the containers in the multi-container application.

> docker compose images
pause

To pause all containers.

> docker compose pause [SERVICE]
ps

To list containers in the multi-container application.

> docker compose ps
rm

To remove stopped containers.

> docker compose rm
start/stop

To start or stop containers.

> docker compose stop [SERVICE]

For a complete list of options and commands, run:

> docker-compose --help