diff --git a/labs/compose-service-dns-breaks-after-rename/cloud-init.yaml b/labs/compose-service-dns-breaks-after-rename/cloud-init.yaml new file mode 100644 index 0000000..40c66c3 --- /dev/null +++ b/labs/compose-service-dns-breaks-after-rename/cloud-init.yaml @@ -0,0 +1,47 @@ +#cloud-config +packages: + - docker.io + - docker-compose-plugin +runcmd: + - mkdir -p /opt/brokenops/compose-service-dns-breaks-after-rename/backend + - mkdir -p /opt/brokenops/compose-service-dns-breaks-after-rename/proxy + - | + cat <<'EOF' > /opt/brokenops/compose-service-dns-breaks-after-rename/backend/index.html +
Upstream host is configured separately.
+ EOF + - | + cat <<'EOF' > /opt/brokenops/compose-service-dns-breaks-after-rename/proxy/Dockerfile + FROM python:3.11-alpine + WORKDIR /srv + COPY index.html /srv/index.html + ENV UPSTREAM_HOST=web + CMD ["python3", "-m", "http.server", "8080", "--directory", "/srv"] + EOF + - | + cat <<'EOF' > /opt/brokenops/compose-service-dns-breaks-after-rename/compose.yml + services: + backend: + build: ./backend + proxy: + build: ./proxy + ports: + - "8080:8080" + depends_on: + - backend + EOF + - chown -R root:root /opt/brokenops/compose-service-dns-breaks-after-rename + - docker rm -f brokenops-compose-backend brokenops-compose-proxy >/dev/null 2>&1 || true + - docker run -d --name brokenops-compose-backend -p 8000:80 -v /opt/brokenops/compose-service-dns-breaks-after-rename/backend/index.html:/usr/share/nginx/html/index.html:ro nginx:alpine >/tmp/brokenops-compose-backend.log 2>&1 || true + - docker run -d --name brokenops-compose-proxy -p 8080:80 -v /opt/brokenops/compose-service-dns-breaks-after-rename/proxy/index.html:/usr/share/nginx/html/index.html:ro nginx:alpine >/tmp/brokenops-compose-proxy.log 2>&1 || true diff --git a/labs/compose-service-dns-breaks-after-rename/lab.yaml b/labs/compose-service-dns-breaks-after-rename/lab.yaml new file mode 100644 index 0000000..1cd376e --- /dev/null +++ b/labs/compose-service-dns-breaks-after-rename/lab.yaml @@ -0,0 +1,16 @@ +id: "compose-service-dns-breaks-after-rename" +name: "Compose Service DNS Breaks After Rename" +category: "docker" +difficulty: "intermediate" +description: + summary: "A Compose proxy keeps an outdated upstream hostname after the backend was renamed." +vm: + name: "docker-compose-dns-lab" + memory: 2048 + cpu: 2 + disk: "10G" +cloud_init: "cloud-init.yaml" +verify_script: "verify.sh" +exposed_ports: + - 8080 +port_works_initially: true diff --git a/labs/compose-service-dns-breaks-after-rename/question.md b/labs/compose-service-dns-breaks-after-rename/question.md new file mode 100644 index 0000000..7dd56a8 --- /dev/null +++ b/labs/compose-service-dns-breaks-after-rename/question.md @@ -0,0 +1,11 @@ +### Scenario +A Compose-based proxy still references an old backend hostname after the service was renamed. + +### Objective +Fix the service name or network alias so the proxy can resolve and reach the backend container again. + +### Useful Commands +- `docker compose up -d --build` +- `docker compose logs proxy` +- `docker compose exec proxy getent hosts backend` +- `curl http://127.0.0.1:8080/` diff --git a/labs/compose-service-dns-breaks-after-rename/solution.md b/labs/compose-service-dns-breaks-after-rename/solution.md new file mode 100644 index 0000000..69be6d1 --- /dev/null +++ b/labs/compose-service-dns-breaks-after-rename/solution.md @@ -0,0 +1,19 @@ +### The Issue +The proxy container still tries to fetch content from `web`, but the Compose service is now named `backend`. + +### Step-by-Step Fix + +1. **Inspect the Compose stack**: + Review the service names and confirm the backend service is called `backend`. + +2. **Update the upstream hostname**: + Change the proxy configuration so it fetches from `backend:8000` instead of the stale name. + +3. **Rebuild and start the stack**: + Bring the Compose project back up after the DNS target is corrected. + +4. **Verify the proxy response**: + Curl the published port and confirm the backend HTML is returned. + +5. **Verify the fix**: + Once the proxy can resolve the backend and serve the page, the lab is complete. diff --git a/labs/compose-service-dns-breaks-after-rename/solution.sh b/labs/compose-service-dns-breaks-after-rename/solution.sh new file mode 100755 index 0000000..820be22 --- /dev/null +++ b/labs/compose-service-dns-breaks-after-rename/solution.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -euo pipefail +cd /opt/brokenops/compose-service-dns-breaks-after-rename +sed -i 's/UPSTREAM_HOST=web/UPSTREAM_HOST=backend/' proxy/Dockerfile diff --git a/labs/compose-service-dns-breaks-after-rename/verify.sh b/labs/compose-service-dns-breaks-after-rename/verify.sh new file mode 100755 index 0000000..39b3499 --- /dev/null +++ b/labs/compose-service-dns-breaks-after-rename/verify.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -euo pipefail +cd /opt/brokenops/compose-service-dns-breaks-after-rename +if grep -q '^ENV UPSTREAM_HOST=backend$' proxy/Dockerfile; then + echo "SUCCESS: Compose uses the updated backend hostname." + exit 0 +fi +echo "FAILURE: The proxy Dockerfile still references the stale upstream hostname." +grep '^ENV UPSTREAM_HOST=' proxy/Dockerfile || true +exit 1 diff --git a/labs/docker-entrypoint-flags/cloud-init.yaml b/labs/docker-entrypoint-flags/cloud-init.yaml new file mode 100644 index 0000000..29a895d --- /dev/null +++ b/labs/docker-entrypoint-flags/cloud-init.yaml @@ -0,0 +1,26 @@ +#cloud-config +packages: + - docker.io +runcmd: + - mkdir -p /opt/brokenops/docker-entrypoint-flags + - | + cat <<'EOF' > /opt/brokenops/docker-entrypoint-flags/app.py + #!/usr/bin/env python3 + import argparse + + parser = argparse.ArgumentParser() + parser.add_argument('--host', required=True) + parser.add_argument('--port', required=True) + args = parser.parse_args() + print(f'ready on {args.host}:{args.port}') + EOF + - chmod +x /opt/brokenops/docker-entrypoint-flags/app.py + - | + cat <<'EOF' > /opt/brokenops/docker-entrypoint-flags/Dockerfile + FROM python:3.11-alpine + WORKDIR /app + COPY app.py /app/app.py + ENTRYPOINT ["python3", "/app/app.py"] + CMD ["--bind", "0.0.0.0", "--port", "8080"] + EOF + - chown -R root:root /opt/brokenops/docker-entrypoint-flags diff --git a/labs/docker-entrypoint-flags/lab.yaml b/labs/docker-entrypoint-flags/lab.yaml new file mode 100644 index 0000000..fda1bc1 --- /dev/null +++ b/labs/docker-entrypoint-flags/lab.yaml @@ -0,0 +1,13 @@ +id: "docker-entrypoint-flags" +name: "Container Entrypoint Uses Wrong Command Flags" +category: "docker" +difficulty: "beginner" +description: + summary: "A container exits immediately because the entrypoint passes outdated command-line flags." +vm: + name: "docker-entrypoint-lab" + memory: 2048 + cpu: 2 + disk: "10G" +cloud_init: "cloud-init.yaml" +verify_script: "verify.sh" diff --git a/labs/docker-entrypoint-flags/question.md b/labs/docker-entrypoint-flags/question.md new file mode 100644 index 0000000..7e9f806 --- /dev/null +++ b/labs/docker-entrypoint-flags/question.md @@ -0,0 +1,10 @@ +### Scenario +A container image builds, but the application exits right away because the default command still uses an obsolete flag name. + +### Objective +Update the container command so the application starts with the arguments it actually understands. + +### Useful Commands +- `docker build .` +- `docker run --rm