|
| 1 | +# Docker Scenario-Based Exercises |
| 2 | + |
| 3 | +This file contains scenario-based Docker questions to help DevOps engineers practice real-world troubleshooting and configuration tasks. Each question simulates a practical scenario with a step-by-step answer. |
| 4 | + |
| 5 | +## Question 1: Debugging a Docker Container Failure |
| 6 | + |
| 7 | +### Question |
| 8 | +You’re a DevOps engineer deploying a Node.js application using Docker. You run `docker run -d -p 3000:3000 my-node-app`, but the container exits immediately. Using `docker ps -a`, you see the container status as `Exited`. How would you troubleshoot and resolve this issue? |
| 9 | + |
| 10 | +### Answer |
| 11 | +To troubleshoot a container exiting immediately: |
| 12 | +1. **Check Logs**: Run `docker logs my-node-app` to view error messages. Common issues include missing dependencies (e.g., `npm install` failed) or an incorrect command. |
| 13 | +2. **Inspect the Container**: Use `docker inspect my-node-app` to check `Config.Cmd` or `Config.Entrypoint`. Ensure the command (e.g., `node app.js`) is valid. |
| 14 | +3. **Verify the Dockerfile**: Check if `CMD` or `ENTRYPOINT` is correct, e.g., `CMD ["node", "app.js"]`. Update and rebuild if needed: `docker build -t my-node-app .`. |
| 15 | +4. **Test Interactively**: Run `docker run -it my-node-app sh` to debug manually (e.g., `node app.js`). |
| 16 | +5. **Check Resources**: Ensure the host has enough memory/CPU using `docker stats`. |
| 17 | + |
| 18 | +**Example Fix**: If logs show `node: command not found`, update the Dockerfile to use `FROM node:18`, rebuild, and rerun. |
| 19 | + |
| 20 | +### Additional Notes |
| 21 | +- Always start with `docker logs` for error clues. |
| 22 | +- Use `docker ps -a` to check container status and ID. |
| 23 | +- Common issues include missing dependencies or crashing apps. |
| 24 | + |
| 25 | + |
| 26 | +--- |
| 27 | + |
| 28 | + |
| 29 | +## Question 2: Configuring a Multi-Container Application |
| 30 | + |
| 31 | +### Question |
| 32 | +As a DevOps engineer, you need to deploy a web application with a Node.js backend and a MySQL database using Docker. The Node.js app connects to MySQL on `localhost:3306`, but running `docker run` for each container separately fails because they can’t communicate. How would you set up these containers to work together? |
| 33 | + |
| 34 | +### Answer |
| 35 | +To make the Node.js and MySQL containers communicate: |
| 36 | +1. **Use Docker Compose**: Create a `docker-compose.yml` file to define and link both services: |
| 37 | + ```yaml |
| 38 | + version: '3.8' |
| 39 | + services: |
| 40 | + node-app: |
| 41 | + image: my-node-app |
| 42 | + build: . |
| 43 | + ports: |
| 44 | + - "3000:3000" |
| 45 | + depends_on: |
| 46 | + - mysql-db |
| 47 | + environment: |
| 48 | + - DB_HOST=mysql-db |
| 49 | + - DB_PORT=3306 |
| 50 | + mysql-db: |
| 51 | + image: mysql:8.0 |
| 52 | + environment: |
| 53 | + - MYSQL_ROOT_PASSWORD=secret |
| 54 | + ports: |
| 55 | + - "3306:3306" |
| 56 | + ``` |
| 57 | +2. **Run the Application**: Execute `docker-compose up -d` to start both containers. The `node-app` service connects to `mysql-db` using the service name (`mysql-db`) as the hostname, not `localhost`. |
| 58 | +3. **Verify Connectivity**: Check logs with `docker-compose logs node-app` to ensure the Node.js app connects to MySQL. If it fails, verify the environment variables and MySQL’s readiness. |
| 59 | +4. **Alternative Without Compose**: Use a custom network: |
| 60 | + - Create a network: `docker network create my-app-network` |
| 61 | + - Run MySQL: `docker run -d --name mysql-db --network my-app-network -e MYSQL_ROOT_PASSWORD=secret mysql:8.0` |
| 62 | + - Run Node.js: `docker run -d --name node-app --network my-app-network -p 3000:3000 -e DB_HOST=mysql-db my-node-app` |
| 63 | + |
| 64 | +### Additional Notes |
| 65 | +- Docker Compose simplifies multi-container setups by managing networks and dependencies. |
| 66 | +- Always set environment variables for database credentials to avoid hardcoding. |
| 67 | + |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | + |
| 72 | +## Question 3: Optimizing a Dockerfile for CI/CD |
| 73 | + |
| 74 | +### Question |
| 75 | +You’re a DevOps engineer integrating a Dockerized Python application into a Jenkins CI/CD pipeline. The Dockerfile builds slowly, causing pipeline delays. How would you optimize the Dockerfile to speed up builds while maintaining functionality? |
| 76 | + |
| 77 | +### Answer |
| 78 | +To optimize a Dockerfile for faster CI/CD builds: |
| 79 | +1. **Use a Smaller Base Image**: Replace heavy images like `python:3.9` with `python:3.9-slim` to reduce size and download time. |
| 80 | + ```dockerfile |
| 81 | + FROM python:3.9-slim |
| 82 | + ``` |
| 83 | +2. **Leverage Layer Caching**: Order instructions from least to most likely to change. Copy `requirements.txt` and install dependencies before copying the app code: |
| 84 | + ```dockerfile |
| 85 | + COPY requirements.txt . |
| 86 | + RUN pip install -r requirements.txt |
| 87 | + COPY . . |
| 88 | + ``` |
| 89 | +3. **Minimize Layers**: Combine related commands with `&&` to reduce layers: |
| 90 | + ```dockerfile |
| 91 | + RUN pip install -r requirements.txt && rm -rf /root/.cache/pip |
| 92 | + ``` |
| 93 | +4. **Use Multi-Stage Builds**: If the app needs build tools, use a multi-stage build to keep the final image small: |
| 94 | + ```dockerfile |
| 95 | + FROM python:3.9 AS builder |
| 96 | + COPY requirements.txt . |
| 97 | + RUN pip install -r requirements.txt |
| 98 | + FROM python:3.9-slim |
| 99 | + COPY --from=builder /usr/local/lib/python3.9 /usr/local/lib/python3.9 |
| 100 | + COPY . . |
| 101 | + CMD ["python", "app.py"] |
| 102 | + ``` |
| 103 | +5. **Test in Jenkins**: Update the Jenkins pipeline to rebuild the image only when `Dockerfile` or code changes, using a cached image otherwise: |
| 104 | + ```groovy |
| 105 | + pipeline { |
| 106 | + agent any |
| 107 | + stages { |
| 108 | + stage('Build Docker Image') { |
| 109 | + when { changeset "Dockerfile,**.py" } |
| 110 | + steps { sh 'docker build -t my-python-app .' } |
| 111 | + } |
| 112 | + } |
| 113 | + } |
| 114 | + ``` |
| 115 | + |
| 116 | +### Additional Notes |
| 117 | +- Use `.dockerignore` to exclude unnecessary files (e.g., `.git`, `tests/`) from the build context. |
| 118 | +- Monitor build times in Jenkins to confirm improvements. |
| 119 | + |
| 120 | + |
| 121 | +*Contributed by Lahiru Galhena* |
0 commit comments