๐Ÿณ
Hosting

Docker Compose: Managing a Multi-Container Application in One YAML File

03.01.2026
โ† All articles

Modern web applications are almost never made up of a single program. Even a modest project usually requires a web server, a database, and a caching service working together. Installing, configuring, and wiring up each of these components separately is time-consuming and a frequent source of mistakes. Docker and Docker Compose were created precisely to solve this problem, allowing you to describe an entire runtime environment in one file and bring it up with a single command.

What a container is and why it matters

A Docker container is a lightweight, isolated environment that packages an application together with all of its dependencies. Unlike a virtual machine, a container does not include an entire operating system; it carries only the libraries and files that the specific application needs. As a result, it starts in a fraction of a second and consumes minimal resources. The very same container behaves identically on a developer's laptop and on a sayt.uz server, which completely eliminates the classic "but it works on my machine" problem. A container image is the template from which you can spin up as many identical copies as you like.

Working with a single container is straightforward, but real projects need several of them, and managing those by hand quickly becomes tedious. Manually defining networks, ports, and the connections between each container is thankless and error-prone work. This is exactly where Docker Compose steps in, turning a scattered set of containers into one coherent, well-orchestrated system.

What Docker Compose does

Docker Compose is a tool for describing and managing multi-container applications. You declare all the services you need, along with their images, ports, volumes, and interdependencies, in a single YAML file called docker-compose.yml. After that, one command brings the whole system to life: Compose pulls the required images, creates the containers, sets up a network between them, and starts them in the specified order. This approach lets you treat your infrastructure as code, meaning you can version the configuration in Git and share it easily with your team.

The structure of docker-compose.yml

At the heart of a Compose file is the services section, where each container service is declared. For every service you specify which image to use with image, the mapping of external to internal ports with ports, volumes for persistent data with volumes, environment variables with environment, and the startup order with depends_on. The example below illustrates these core fields:

services:
  web:
    image: php:8.2-apache
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
    environment:
      APP_ENV: production
    depends_on:
      - db
      - cache

The "8080:80" entry under ports forwards the server's port 8080 to the container's internal port 80. The volumes section mounts the project code from the host system into the container, so you do not need to rebuild the container when the code changes. The depends_on directive tells Compose to start the web service only after the database and the cache are up.

A practical example: PHP + MySQL + Redis

Now let us look at a fuller example that closely resembles a real project. Here the web application runs on PHP, the data lives in a MySQL database, and frequently requested information is held in a Redis cache. The configuration below links these three services together and joins them on a single network:

services:
  app:
    image: php:8.2-apache
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
    depends_on:
      - db
      - cache

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: shop
    volumes:
      - db_data:/var/lib/mysql

  cache:
    image: redis:7
    ports:
      - "6379:6379"

volumes:
  db_data:

Notice that when connecting to the database from inside the app service, you can simply use the name db as the host, because Compose makes every service reachable on the network by its name. The db_data volume declared at the bottom under volumes is a named volume that ensures MySQL data survives even when the container is removed. This is critical, otherwise the database would be wiped clean every time the container is recreated.

Essential commands

Working with Compose relies on just a handful of simple commands. To bring the entire environment up, you run docker compose up from the project folder; the -d flag runs it in the background so it does not tie up your terminal. To stop the system and remove the containers and networks it created, you use docker compose down. To watch your services in action and track down errors, the docker compose logs command is invaluable:

docker compose up -d
docker compose logs -f app
docker compose ps
docker compose down

Behind these commands lies the entire life cycle of an environment. A single up spares the developer hours of manual setup, while down wipes the environment clean and returns the system to its original state. That predictability is the real value Compose brings to everyday work.

Benefits and the difference between dev and prod

The greatest advantage of Docker Compose is the ability to bring an entire complex environment up with one command and tear it down just as easily. When a new developer joins the team, all they need to do is clone the repository and run up; they have a working environment in minutes rather than hours. Because the agreement is captured inside the configuration file, everyone works with the same service versions and differences between environments disappear.

That said, the approach for a development environment and a production environment differs somewhat. In dev mode it is convenient to mount host volumes into the container for live code editing, debug mode is turned on, and passwords can be simple. In prod mode security comes first: secrets are protected through environment variables or dedicated secret stores, the code is fully baked into the image rather than mounted live, and resource limits are applied. When deploying your project on sayt.uz servers, adopting exactly this production approach ensures stable and secure operation. Learning Docker Compose has become an essential skill for any modern developer and DevOps engineer.

Related articles

๐Ÿ’ฐ Hosting Price Comparison: Uzbek and International Providers ๐Ÿ“ก Server Monitoring Tools: Prometheus, Grafana, Datadog, and More ๐ŸŒ Edge Computing Hosting: Moving Compute Closer to Users ๐Ÿข Colocation Server: Placing Your Own Hardware in a Data Center
๐ŸŒ Language
๐Ÿ‡บ๐Ÿ‡ฟ O'zbek ๐Ÿ‡บ๐Ÿ‡ฟ ะŽะทะฑะตะบ ๐Ÿ‡ท๐Ÿ‡บ ะ ัƒััะบะธะน ๐Ÿ‡ฌ๐Ÿ‡ง English โœ“