> For the complete documentation index, see [llms.txt](https://circleci.com/docs/llms.txt)

# Installing and Using Docker Compose

This page describes how to use Docker Compose in your CircleCI pipelines.

If you are new to Docker Compose, you can review the [official Docker Compose overview](https://docs.docker.com/compose/), or check out the [Getting Started guide](https://docs.docker.com/compose/gettingstarted/).

## Using Docker Compose with machine executor

If you want to use Docker Compose to manage a multi-container setup with a Docker Compose file, use the `machine` key in your `.circleci/config.yml` file. Then use `docker compose` as you would normally (see [Using the Linux VM Execution Environment](https://circleci.com/docs/guides/execution-managed/using-linuxvm/) for more details). If you have a Docker Compose file that shares local directories with a container, this will work as expected.

## Using Docker Compose with Docker executor

Using the `docker` execution environment combined with `setup_remote_docker` enables you to run Docker commands similarly to how you run Docker commands in a machine execution environment. However, volume mounting and port forwarding do **not** work the same way when using the `docker` execution environment. When using the `docker` execution environment with `setup_remote_docker`, a job’s commands are executed in a container that has access to an external Docker daemon. Therefore, to use the Docker CLI or Docker Compose, you must move data around. Mounting can typically be solved by making content available in a Docker volume. It is possible to load data into a Docker volume by using `docker cp` to get the data from the CLI host into a location running on the Docker host.

## Install Docker Compose

The Docker Compose utility is [pre-installed in the CircleCI convenience images](https://circleci.com/docs/guides/execution-managed/circleci-images/#pre-installed-tools) and machine executor images.

If you are using the Docker executor and **are not** using a convenience image, you can install Docker Compose into your [Primary Container](https://circleci.com/docs/reference/glossary/#primary-container) during job execution. Then use the [Run Docker Commands](https://circleci.com/docs/guides/execution-managed/building-docker-images/) guide:

`````````
      - run:
          name: Install Docker Compose
          command: |
            # Add Docker's official GPG key:
            apt-get update
            DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates curl
            install -m 0755 -d /etc/apt/keyrings
            curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
            chmod a+r /etc/apt/keyrings/docker.asc

            # Add the repository to Apt sources:
            echo \
              "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
              $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
              sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
            apt-get update
            DEBIAN_FRONTEND=noninteractive apt-get install docker-ce-cli docker-buildx-plugin docker-compose-plugin

      - setup_remote_docker #activate the remote docker environment
`````````

If you are constructing your own Docker images, consider reading the [Using Custom-Built Docker Images](https://circleci.com/docs/guides/execution-managed/custom-images/).

Once you have Docker Compose installed, you can use it to build images and run containers:

`````````
      - run:
          name: Build images of services declared in docker-compose.yml
          command: docker compose build
`````````

Or to run the whole system:

`````````
      - run:
          name: Start all services declared in docker-compose.yml
          command: docker compose up -d
`````````

Or to also verify if a service is running, for example:

`````````
      - run:
          name: Start Docker Compose and verify service(s)
          command: |
            # Setting the Docker Compose project name to "circleci-demo-docker" means
            # the names of our services' containers would be prefixed with "circleci-demo-docker".
            docker compose --project circleci-demo-docker up -d

            # In this example, we have a "contacts" service, and
            # we are trying to check, via `dockerize`, if the service is ready.
            docker container run --network container:circleci-demo-docker_contacts_1 \
              docker.io/jwilder/dockerize \
              -wait http://localhost:8080/healthcheck \
              -wait-retry-interval 2s \
              -timeout 20s
`````````

## Example project

See the [Example Docker Compose Project](https://github.com/circleci/cci-demo-docker/tree/docker-compose) on GitHub for a demonstration and use the [full configuration file](https://github.com/circleci/cci-demo-docker/blob/docker-compose/.circleci/config.yml) as a template for your own projects.

The primary container runs in a separate environment from Remote Docker and the two cannot communicate directly. To interact with a running service, run a container in the service’s network.

## Limitations

Using `docker compose` with the `macos` executor is not supported. See [our support article for more information](https://support.circleci.com/hc/en-us/articles/360045029591-Can-I-use-Docker-within-the-macOS-executor-).

## See also

[Running Docker Commands](https://circleci.com/docs/guides/execution-managed/building-docker-images/)