Docker Compose will BLOW your MIND!! (a tutorial)
Based on NetworkChuck's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
Docker Compose uses a `docker-compose.yml` file to define services, networks, and configuration so an entire stack can start with `docker compose up -d`.
Briefing
Docker Compose turns “spin up one container” work into “deploy an entire stack” with a single YAML file and one command. In practice, it can create a multi-container infrastructure in seconds—then tear it all down just as quickly—without manually running long sequences of `docker run` commands. That shift matters because it makes repeatable environments (labs, web apps, dev setups) far easier to create, share, and re-create.
The walkthrough starts with the basics: install Docker Compose on a Linux environment (the tutorial uses a Kali Linux VM in VirtualBox, but the approach is general). After installation, it demonstrates the old way—running a single Nginx container with port exposure—then mirrors the same outcome using Compose. The key workflow is to create a dedicated project folder, add a `docker-compose.yml` file, and run `docker compose up -d` from that same directory. The example defines a `services` section with a `website` container using the `nginx` image, maps host ports to container ports (host `80` to container `80`, with an alternate host port to avoid conflicts), and sets `restart: always`.
Once the Compose file is in place, the container naming and networking behavior become part of the “magic.” Compose automatically names containers using the project folder plus the service name (e.g., `coffee_time_website_1`) and creates a default bridge network when no custom network is specified. Verification is done with `docker compose ps` (showing only containers in that Compose project) and by checking the mapped localhost ports. Cleanup is equally simple: `docker compose down` removes containers and the network, while `docker compose stop` halts containers without deleting them.
The tutorial then scales up. It adds a second Nginx service by duplicating the service definition with a different host port, and it introduces a custom network defined in the Compose YAML under a top-level `networks` section. Using IP address management (IPAM) and a bridge driver, it assigns a specific subnet and gives one container a fixed IP via `ipv4_address`. When the Compose file changes, running `docker compose up -d` again updates the running setup—creating the new network and recreating affected containers.
Finally, the walkthrough uses Docker Compose to deploy WordPress, which requires multiple cooperating components. The Compose file defines two services: `wordpress` (using the official WordPress image) and `mysql` (using `mysql:5.7`). Environment variables wire them together—WordPress points at the MySQL service name for host, database name, and credentials. `depends_on` ensures MySQL starts before WordPress. A `volumes` mapping persists MySQL data by binding the container’s `/var/lib/mysql` to a host directory, so `docker compose down` and later re-`up` preserve the database and keep the same site content.
The result is a repeatable pattern: describe containers, networks, dependencies, and persistent storage in YAML; then manage the whole system with a small set of Compose commands. The same approach can be extended to larger lab environments, including multi-container vulnerable setups and other packaged stacks like Minecraft-style projects or Pi-hole deployments.
Cornell Notes
Docker Compose lets users define an entire multi-container application in a single `docker-compose.yml` file and manage it with one command. The tutorial demonstrates starting with a simple Nginx service, then scaling to multiple services and custom networks with fixed IPs. Compose automatically names containers based on the project folder and creates a default bridge network unless overridden. For WordPress, Compose coordinates two containers—WordPress and MySQL—using environment variables, `depends_on` for startup order, and a volume mapping to persist MySQL data on the host. This combination makes it easy to spin up, update, and tear down complex stacks while keeping state where it matters.
How does Docker Compose replace the “manual” `docker run` workflow in the tutorial’s first example?
Why does the tutorial emphasize running Compose commands from the directory containing `docker-compose.yml`?
What networking behavior does Compose provide by default, and how can it be customized?
How does Compose ensure WordPress can talk to MySQL in the WordPress deployment example?
What roles do `depends_on` and volumes play in the WordPress + MySQL setup?
Review Questions
- In the tutorial’s Nginx example, what determines the container name format like `coffee_time_website_1`?
- When defining a custom network in Compose, where do `networks` and IPAM configuration live in the YAML, and how is a container attached to that network?
- For the WordPress deployment, which specific Compose features handle (1) startup order and (2) database persistence, and what are their YAML sections?
Key Points
- 1
Docker Compose uses a `docker-compose.yml` file to define services, networks, and configuration so an entire stack can start with `docker compose up -d`.
- 2
Compose commands should be run from the directory containing the YAML file to avoid needing `-f` and to ensure correct project-based naming.
- 3
Compose automatically creates a default bridge network when no custom network is defined, and it names containers using the project folder plus the service name.
- 4
Custom networks can be defined in the YAML under a top-level `networks` section, including IPAM subnet settings and fixed container IPs via `ipv4_address`.
- 5
Scaling a stack typically means adding more entries under `services` and adjusting port mappings to avoid host conflicts.
- 6
For multi-component apps like WordPress, environment variables connect services (WordPress points to the MySQL service name), while `depends_on` controls startup order.
- 7
Persisting database state requires a volume mapping so MySQL data survives `docker compose down` and later re-`up`.