Peters School of Business · Assiniboine College · NETW-0014
2 hours · Lecture + Lab 6C · YAML structure, multi-container stacks, restart policies, BIND9 container
docker-compose YAML structure, lifecycle commands, restart policies, and service networking
Part 1 — docker-compose.yml structure (12 min)
services:
webserver:
image: nginx
ports:
- "8080:80"
volumes:
- ./webroot:/usr/share/nginx/html:ro
restart: unless-stopped
services:
webserver:
image: nginx
ports:
- "8080:80"
depends_on:
- db
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: secret
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Part 2 — Lifecycle commands (8 min)
docker-compose up -d — start all services in detached mode
docker-compose down — stop and remove containers (keeps images and named volumes)
docker-compose down -v — also removes named volumes
docker-compose ps — show status of all services
docker-compose logs — show logs from all services
docker-compose logs -f webserver — follow a specific service's logs
docker-compose exec webserver bash — exec into a running service
docker-compose restart webserver — restart a specific service
docker-compose pull — pull latest image versions for all services
Part 3 — Restart policies (5 min)
no — never restart automatically (default). Container stays stopped after it exits.
always — always restart, even if manually stopped, even after docker daemon restart.
unless-stopped — restart automatically, but not if manually stopped with docker stop. Survives host reboots. The best choice for production services.
on-failure — only restart if the container exits with a non-zero exit code.
Part 4 — Networks in compose (5 min)
Lab 6C — BIND9 in docker-compose, Nginx service, multi-container stack verification
Part 1 — Install docker-compose (5 min)
sudo apt install docker-compose. Verify: docker-compose --version.Part 2 — BIND9 in a container with docker-compose (30 min)
sudo mkdir -p /opt/bind9/config /opt/bind9/cache /opt/bind9/records
mkdir -p ~/docker/bind9 && nano ~/docker/bind9/docker-compose.yml
services:
bind9:
image: ubuntu/bind9:latest
environment:
- BIND9_USER=root
- TZ=America/Winnipeg
ports:
- "5353:53/udp"
- "5353:53/tcp"
volumes:
- /opt/bind9/config:/etc/bind
- /opt/bind9/cache:/var/cache/bind
- /opt/bind9/records:/var/lib/bind
restart: unless-stopped
docker-compose up -d (from ~/docker/bind9/). Check: docker-compose ps. View logs: docker-compose logs bind9.dig @127.0.0.1 -p 5353 s1.yourname.io. Should return the A record from the zone file. This container BIND9 runs completely independently from the host BIND9.Part 3 — Add Nginx to the stack (25 min)
webserver:
image: nginx
ports:
- "8088:80"
volumes:
- /opt/webroot:/usr/share/nginx/html:ro
restart: unless-stopped
sudo mkdir -p /opt/webroot && echo "<h1>Docker Stack</h1>" | sudo tee /opt/webroot/index.htmldocker-compose up -d — compose adds the new service without restarting the existing one. Verify: docker-compose ps — both services Up. Browse to http://[S1-IP]:8088.sudo reboot. After the VM comes back, check docker-compose ps from ~/docker/bind9/ — both containers should be running automatically due to restart: unless-stopped.Learning outcomes — by end of Day 3, students can…
Common issues and fixes
| Issue | Likely cause | Fix |
|---|---|---|
| BIND9 container exits immediately | Config file error in /opt/bind9/config, or permissions on mount directories | Check: docker-compose logs bind9 — the error message will indicate what's wrong. Common: named.conf syntax error, or directory not found |
| docker-compose up fails with "yaml" error | YAML indentation error — tabs instead of spaces, or wrong indentation level | YAML requires exactly 2-space indentation. Use cat -A to reveal tabs (^I). Online YAML validators can help |
| dig @127.0.0.1 -p 5353 returns no response | Container not running, port not bound, or named.conf in container doesn't listen on 0.0.0.0 | Check docker-compose ps. Check ss -ulnp | grep 5353 on the host. The bind9 container's named must listen on 0.0.0.0, not 127.0.0.1 |