# How to use Docker Compose for multi-container applications

Compose simplifies scaling and deployment of applications in [Docker](https://www.ionos.com/digitalguide/server/know-how/what-is-docker/) by automating **container management**. Our tutorial takes an in-depth look at setting up and using Docker Compose to streamline your application deployment process.

## What is Docker Compose?

Docker Compose is used to manage applications and increase efficiency in container development. Configurations are defined in a single YAML file, making applications easy to build and scale. Docker Compose is often used to set up a local environment. However, it can also be part of a **Continuous Integration / Continuous Delivery (CI/CD) workflow**. Developers can define a specific container version for testing or specific pipeline phases. This makes it easier to identify issues and fix bugs before the application moves into production.

## Docker Compose requirements

For **container orchestration**, you need both Docker Engine and Docker Compose. Ensure you’ve got one of the following installed on your system:

- **Docker Engine and Docker Compose**: Can be installed as standalone binaries.
- **Docker Desktop**: Development environment with graphical user interface including Docker Engine and Docker Compose.

Tip Find out how to install Docker Compose on different operating systems in our tutorials:

- [Install Docker Compose on Ubuntu](https://www.ionos.com/digitalguide/server/configuration/docker-compose-on-ubuntu/)
- [Install Docker Compose on macOS](https://www.ionos.com/digitalguide/server/configuration/docker-compose-on-mac/)
- [Install Docker Compose on Windows](https://www.ionos.com/digitalguide/server/configuration/install-docker-compose-on-windows/)

## Step-by-step guide of how to use Docker Compose

In the following, we demonstrate how to use Docker Compose with a simple **Python web application** that utilizes a hit counter. To do this, we use the Python Flask framework and the Redis in-memory database. You don’t need to install Python or Redis, as they are provided as Docker images.

### Step 1: Create project files

Launch the terminal and create a new folder for the project.

```shell
$ mkdir composedemo
```

Change to the directory.

```shell
$ cd composedemo
```

Create the file *app.py* in this folder and add the following code to it:

```python
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)
@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I was here {} times.\n'.format(count)
```

In our setup, we utilize `redis` as the hostname and the default port `6379` for connecting to the Redis service. Additionally, we specify that the `get_hit_count()` function should make multiple connection attempts to the service. This is recommended where Redis may not be immediately available when the application starts or there may be intermittent connection issues during runtime.

Create the file *requirements.txt* with the dependencies:

```plaintext
flask
redis
```

### Step 2: Set up Dockerfile

The **Dockerfile** is used for the Docker image. This specifies all the dependencies that the Python application requires.

```shell
# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
```

We instruct Docker to utilize the Python 3.7 image. Furthermore, we set the necessary environment variables for the **flask command**. By using `apk add`, we install essential dependencies, including gcc. To allow the container to monitor port 5000, we specify `EXPOSE`. Using `COPY`, we transfer the contents of the current folder to the working directory */code* within the container. Finally, as default command for the container we choose `flask run`.

Check that the Dockerfile was saved without a file extension, as some editors automatically append the *.txt* suffix.

### Step 3: Create YAML file

In ***docker-compose.yml*** we configure the services “redis” and “web”.

```yaml
version: "3.9"
services:
    web:
        build: .
        ports:
            - "8000:5000"
    redis:
        image: "redis:alpine"
```

The web service is built using the Docker image created by the Dockerfile. It associates the container and the host computer with port 8000, while the **Flask web server** runs on port 5000. The Redis image, on the other hand, is obtained directly from the official Docker Hub.

### Step 4: Run the application with Compose

Launch the application from your project folder.

```shell
docker compose up
```

Call up *http://localhost:8000* in your browser. You can also enter *http://127.0.0.1:8000*.

You should see the following message:

[![Image: Docker Compose Application: Output the number of visits in the browser](https://www.ionos.com/digitalguide/fileadmin/_processed_/d/1/csm_docker-compose-hit-counter_f6e8af7148.webp "Docker Compose Application: Output the number of visits in the browser")](https://www.ionos.com/digitalguide/fileadmin/DigitalGuide/Screenshots_2023/docker-compose-hit-counter.png) You’ll see the number of times you have visited the browser. Refresh the page. The number of views should now have increased by 1.

[![Image: Calling the Docker Compose application again](https://www.ionos.com/digitalguide/fileadmin/_processed_/7/8/csm_docker-compose-hit-counter-updated_58c6be39f6.webp "Calling the Docker Compose application again")](https://www.ionos.com/digitalguide/fileadmin/DigitalGuide/Screenshots_2023/docker-compose-hit-counter-updated.png) The number of visits increased by 1. Stop the application using:

```shell
$ docker compose down
```

To stop running the application, you can simply press `Ctrl` + `C` in the terminal.

### Step 5: Add a bind mount

If you want to add a **bind mount** for the web service, you can do this in *docker-compose.yml*.

```yaml
version: "3.9"
services:
    web:
        build: .
        ports:
            - "8000:5000"
        volumes:
            - .:/code
        environment:
            FLASK_DEBUG: "true"
    redis:
        image: "redis:alpine"
```

Under the **Volumes** section, we specify the attachment of the current project folder to the */code* directory inside the container. This allows for seamless code changes without the need to recreate the image. The variable `FLASK_DEBUG` tells `flask run` to run in development mode.

### Step 6: Rebuild and run application

Enter the following command in the terminal to rebuild the Compose file:

```shell
docker compose up
```

### Step 7: Update the application

Now that you’re using a bind mount for your application, you can modify your code and automatically see changes without rebuilding the image.

Write a new welcome test in ***app.py***.

```python
return 'Hello from Docker! I was here {} times.\n'.format(count)
```

Refresh the browser to test whether the changes have been applied.

[![Image: Docker Compose application: modified welcome text](https://www.ionos.com/digitalguide/fileadmin/_processed_/9/3/csm_docker-compose-hit-counter-text-modified_a210964afe.webp "Docker Compose application: modified welcome text")](https://www.ionos.com/digitalguide/fileadmin/DigitalGuide/Screenshots_2023/docker-compose-hit-counter-text-modified.png) The welcome text in the Python application has been modified ### Step 8: other commands

The `--help` option lists available Docker Compose commands:

```shell
docker compose --help
```

To run Docker Compose in the background, you can add the `-d` argument:

```shell
docker compose up -d
```

Use `down` to remove all containers. The `--volumes` option deletes the volumes used by the Redis container.

```shell
docker compose down --volumes
```

Tip To get started with Docker, check out our [Docker Tutorial](https://www.ionos.com/digitalguide/server/configuration/docker-tutorial-installation-and-first-steps/) and our overview of [Docker Commands](https://www.ionos.com/digitalguide/server/know-how/docker-commands/).


This is a markdown version of: [https://www.ionos.com/digitalguide/server/configuration/docker-compose-tutorial/](https://www.ionos.com/digitalguide/server/configuration/docker-compose-tutorial/) for AI/LLM consumption.