Containers • Docker
Docker Compose
Define and run multi-container apps with docker compose.
- Intermediatelevel
- 4objectives
- 10 mintarget time
- 100points + certificate
Start the interactive lab ↓ Free · runs in your browser · no login
Why this lab exists
Most people meet Docker through a single docker run command. The moment an application needs two containers — a web server and a database, say — the command lines get long, the port mappings get forgotten, and nobody remembers which flags were used last time. Docker Compose fixes that by putting the whole stack in one declarative file, docker-compose.yml, and giving you four verbs to manage it: build, up, ps/logs, and down.
In this lab you work on a host called docker-host-01 as the user dev. The application lives in /app and already has a compose file. Your job is to read it, build it, run it in the background, and shut it down cleanly. Those four steps are exactly what you would do on a real development box on day one of a new project.
Reading the compose file before you run anything
Get into the habit of running cat /app/docker-compose.yml before you start a stack. Two things in this file matter:
services:— every top-level key underneath is one container. Here there are two:web(built from thenginximage) anddb(built from themysqlimage).ports:—80:80means host port 80 → container port 80. The left-hand number is the one your browser will use. If port 80 is already taken on the host,upwill fail withaddress already in use, so check withss -ltnp | grep :80if you are ever unsure.
Notice that db has no ports: entry. That is intentional and good practice: the database only needs to be reachable by web over the private network Compose creates, not from the outside world.
Compose creates a network per project named<folder>_default. Services reach each other by service name —webcan talk to the database asdb:3306— with no IP addresses involved.
The four commands, and what each one really does
docker compose build— builds any service that has abuild:section and pulls images for services that only haveimage:. In this file both services use published images, so the command finishes quickly, but you should still run it: it validates the YAML and confirms the images are available before you try to start anything.docker compose up -d— creates the network, creates the containers and starts them. The-d(detached) flag returns your terminal immediately. Without-dCompose streams every container's logs to your screen and stops the stack when you press Ctrl+C — fine for debugging, wrong for anything you want to keep running.docker compose psanddocker compose logs web— the two commands you use most afterup.psshows state and port mappings;logsshows stdout/stderr from a service. Add-fto follow.docker compose down— stops and removes the containers and the network. It does not remove named volumes, so database data survives adownunless you add-v.
Mistakes I see in every beginner batch
- Running the commands from the wrong directory. Compose looks for
docker-compose.yml(orcompose.yaml) in the current directory. If you are in/home/devinstead of/app, you getno configuration file provided: not found. Eithercd /appfirst or pass-f /app/docker-compose.yml. - Typing
docker-composewith a hyphen. That is the old Python v1 tool, removed in 2023. Modern Docker ships Compose v2 as a plugin:docker composewith a space. - Forgetting
-d, then closing the terminal. The stack dies with the shell. If you did this, just runup -dagain — Compose is idempotent and will only recreate what changed. - Using
docker rmon compose-managed containers. It works, but Compose then loses track of them. Always usedown(orstop/rmthrough Compose) so the project state stays consistent. - Expecting MySQL to come up without a root password. The official image refuses to start unless
MYSQL_ROOT_PASSWORD(or one of its alternatives) is set. In this simulated lab the container starts either way; on a real host you would add anenvironment:block to thedbservice.
How the lab scores you
The terminal below checks each objective as you type. Reading the file, building, starting detached and tearing down are worth 25 points each. You can retype a command if you make a mistake — only correct commands count. When you finish, download the scorecard; the lab does not store anything on a server, so keep the file if you want it.
Where to go next
Once this feels easy, try the Docker Networking and Docker Volumes labs on this site — they cover the two things this compose file deliberately leaves out: how web actually reaches db, and how to stop losing your database every time you run down -v.
What you will practise
- View compose file — Read docker-compose.yml. 25 pts
- Build — Build with docker compose build. 25 pts
- Up detached — Start with docker compose up -d. 25 pts
- Down — Stop with docker compose down. 25 pts
Commands used in this lab
cat /app/docker-compose.ymldocker compose builddocker compose up -ddocker compose down
Files present on the lab host
/app/docker-compose.ymlservices: web: image: nginx ports: - 80:80 db: image: mysql