What is Docker Compose?

Author: Published

In brief: Docker Compose is a tool for defining and running applications made up of several Docker containers. In a single file, you describe the services, their configuration, connections and data storage, then start them with the command docker compose up. It is useful, for example, when a project needs an application, a database and an additional administration panel.

How Docker Compose works with Docker

Docker runs programs in containers: isolated environments containing an application and the dependencies it needs. A container is created from an image—a ready-made package that specifies what should be run. Compose does not replace Docker: it uses Docker to manage a set of related containers.

Without Compose, you can start each container with a separate docker run command, manually specifying ports, environment variables and the network. Compose lets you save these settings in a compose.yaml file. This allows you to store the configuration alongside the project code and reproduce it on another computer.

The fundamental concept is a service, which is a definition of a particular component of the environment, such as a database. Compose creates containers based on these definitions. By default, it also creates a project network in which services can find one another by name.

What goes in the compose.yaml file

The configuration is written in YAML, a text format that uses indentation to define its structure. Indentation must be consistent; use spaces, not tabs.

The most common elements are:

Starting the containers does not necessarily mean the application is working correctly. The database may need time to initialise, and the application should be able to retry its connection. depends_on can specify the startup order, but in its basic form it does not guarantee that a service is ready; that requires an appropriate health check configuration, using healthcheck, and a dependency condition.

Example: PostgreSQL and a database administration panel

Suppose you want to test PostgreSQL locally without installing the database directly on your system. You also need the Adminer panel, which lets you browse data through a web browser. Create a project directory and save a compose.yaml file in it:

services:
  db:
    image: postgres:17
    environment:
      POSTGRES_USER: demo
      POSTGRES_PASSWORD: local_demo_password
      POSTGRES_DB: demo
    volumes:
      - db_data:/var/lib/postgresql/data

  adminer:
    image: adminer:5
    ports:
      - "127.0.0.1:8080:8080"

volumes:
  db_data:

Start the environment from that directory:

docker compose up -d

The -d option starts the containers in the background. On the first run, Docker will download the images if they are not available locally.

Open http://localhost:8080 in your browser. In the panel, select PostgreSQL and enter db as the server, demo as the user, local_demo_password as the password and demo as the database. If the database is still initialising, wait a moment and try logging in again.

The name db works inside the Compose network. Do not use localhost there: from the Adminer container’s perspective, it would mean the Adminer container itself, not the database. In this example, PostgreSQL does not have a port exposed on the computer, while the panel is accessible only through the computer’s local interface.

This is a configuration for learning, not a production-ready setup. Do not use the example password for real data or store real secrets in the repository.

Commands for everyday work

The current command is docker compose, with a space. The form docker-compose, found in older tutorials, refers to an older way of installing the tool. You can check whether Compose is available with docker compose version; if the command does not work, check the installation method for your system in the official Docker documentation.

CommandPurpose
docker compose psShows the project’s containers and their status.
docker compose logs -fDisplays logs and follows new messages.
docker compose stopStops containers without removing them.
docker compose downRemoves containers and the project network, but preserves named volumes by default.
docker compose configValidates and displays the resulting configuration.

Be careful with docker compose down -v: the -v option also removes volumes managed by the project, so in this example it will delete the database’s data. A volume keeps data persistent after a container is removed, but it is not a substitute for a backup.

When Compose is enough, and when it is not

Compose is well suited to local application development, integration testing and simple deployments on a single server. It is particularly useful when several people need to run the same set of services without manually recreating the settings.

It does not, on its own, provide management of a cluster of multiple servers or high availability. A production deployment requires separate planning for security, backups, monitoring and image updates. An image tag such as postgres:17 may point to successive releases in the same release line; when you need strict reproducibility, consider pinning the image to a specific digest—an identifier of its contents.

To get started, run the example, check the logs and run docker compose down, followed by docker compose up -d again. This lets you see in practice the difference between a recreated container and preserved data.

See also: What is an ETF?

Read also

Learn how PHP-FPM handles PHP requests, how it differs from a web server, and how to tune processes for traffic and hosting resources.
Learn how BIND, open-source DNS server software, handles domains, how its two roles differ and when running it yourself makes sense.
Learn what Poland’s REGON register and identification number mean, how they differ from NIP and KRS, and how to check a business’s details.