Docker Scenario-Based Exercises
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.
Question 1: Debugging a Docker Container Failure
Question
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?
Answer
To troubleshoot a container exiting immediately:
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.
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.
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 ..
4. Test Interactively: Run docker run -it my-node-app sh to debug manually (e.g., node app.js).
5. Check Resources: Ensure the host has enough memory/CPU using docker stats.
Example Fix: If logs show node: command not found, update the Dockerfile to use FROM node:18, rebuild, and rerun.
Additional Notes
- Always start with
docker logsfor error clues. - Use
docker ps -ato check container status and ID. - Common issues include missing dependencies or crashing apps.
Question 2: Configuring a Multi-Container Application
Question
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?
Answer
To make the Node.js and MySQL containers communicate:
1. Use Docker Compose: Create a docker-compose.yml file to define and link both services:
version: '3.8'
services:
node-app:
image: my-node-app
build: .
ports:
- "3000:3000"
depends_on:
- mysql-db
environment:
- DB_HOST=mysql-db
- DB_PORT=3306
mysql-db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=secret
ports:
- "3306:3306"
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.
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.
4. Alternative Without Compose: Use a custom network:
- Create a network: docker network create my-app-network
- Run MySQL: docker run -d --name mysql-db --network my-app-network -e MYSQL_ROOT_PASSWORD=secret mysql:8.0
- Run Node.js: docker run -d --name node-app --network my-app-network -p 3000:3000 -e DB_HOST=mysql-db my-node-app
Additional Notes
- Docker Compose simplifies multi-container setups by managing networks and dependencies.
- Always set environment variables for database credentials to avoid hardcoding.
Question 3: Optimizing a Dockerfile for CI/CD
Question
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?
Answer
To optimize a Dockerfile for faster CI/CD builds:
1. Use a Smaller Base Image: Replace heavy images like python:3.9 with python:3.9-slim to reduce size and download time.
requirements.txt and install dependencies before copying the app code:
3. Minimize Layers: Combine related commands with && to reduce layers:
4. Use Multi-Stage Builds: If the app needs build tools, use a multi-stage build to keep the final image small:
FROM python:3.9 AS builder
COPY requirements.txt .
RUN pip install -r requirements.txt
FROM python:3.9-slim
COPY --from=builder /usr/local/lib/python3.9 /usr/local/lib/python3.9
COPY . .
CMD ["python", "app.py"]
Dockerfile or code changes, using a cached image otherwise:
pipeline {
agent any
stages {
stage('Build Docker Image') {
when { changeset "Dockerfile,**.py" }
steps { sh 'docker build -t my-python-app .' }
}
}
}
Additional Notes
- Use
.dockerignoreto exclude unnecessary files (e.g.,.git,tests/) from the build context. - Monitor build times in Jenkins to confirm improvements.
Contributed by Lahiru Galhena