Managing Multi-Container Applications Using docker-compose
- 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
SUSE Linux 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 SUSE Linux Micro by default. However, if Podman is missing, you can install it as described below:
Run the command:
>
sudo
transactional-update pkg install podmanRestart 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 SUSE Linux Micro
by default. To install it, proceed as follows:
Install the package
podman-docker
by running:transactional-update pkg install podman-docker
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.
docker
replaced with the podman
command
On SUSE Linux Micro, the podman-docker
script is
used to call Podman whenever you run docker-compose, as Docker is not
present on SUSE Linux Micro.
1.3.1 Installing docker-compose #
If docker-compose is not present on your system, you can install it by following the steps:
Run the command:
>
sudo
transactional-update pkg install docker-composeAfter 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:
Create the configuration file
compose.yml
. For details, refer to Section 2.1, “Creatingcompose.yml
”.Prepare the required directory structure. We recommend placing the
compose.yml
file at the top of your working directory.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.
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 theconfigs
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.yml
file 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:
Verify that the container you intend to run doesn't already exist:
>
podman ps --allIf needed, remove the particular container:
>
podman rm -f CONTAINER_IDStart the multi-container application by running the following command from the directory where
compose.yml
is located:>
docker compose up -ddocker-compose creates a separate network for the multi-container application.
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
4 Legal Notice #
Copyright© 2006–2024 SUSE LLC and contributors. All rights reserved.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or (at your option) version 1.3; with the Invariant Section being this copyright notice and license. A copy of the license version 1.2 is included in the section entitled “GNU Free Documentation License”.
For SUSE trademarks, see https://www.suse.com/company/legal/. All other third-party trademarks are the property of their respective owners. Trademark symbols (®, ™ etc.) denote trademarks of SUSE and its affiliates. Asterisks (*) denote third-party trademarks.
All information found in this book has been compiled with utmost attention to detail. However, this does not guarantee complete accuracy. Neither SUSE LLC, its affiliates, the authors, nor the translators shall be held liable for possible errors or the consequences thereof.