In-Class Exercise - Docker Container Debugging Challenge¶

The Challenge¶
A web application container is crashing immediately after startup, and you need to debug it using Docker tools and techniques. Your mission: identify the root cause and fix the issue without modifying the original Dockerfile until you’ve diagnosed the problem.
Scenario¶
You’ve inherited a Python Flask application that worked yesterday but now fails to start. The container exits with code 1, and you need to investigate:
- Why is the container crashing?
- What files or configurations are missing?
- How can you inspect a container that won’t stay running?
- Can you fix it interactively before updating the Dockerfile?
Task Checklist¶
- Build the provided broken Docker image
- Attempt to run it and observe the failure
- Use Docker debugging techniques to inspect the crashed container
- Override the entrypoint to keep the container alive for investigation
- Explore the filesystem and identify the missing configuration file
- Fix the issue interactively and verify the application works
- Update the Dockerfile with the permanent fix
- Document your debugging process
Acceptance Criteria¶
- Identify the root cause without looking at the solution first
- Successfully get the application running using debugging techniques
- Demonstrate at least two different debugging methods (e.g.,
docker logs, entrypoint override,docker exec) - Apply a permanent fix to the Dockerfile
Tips¶
docker logs <container>shows output even from crashed containersdocker run --entrypoint /bin/shcan override the startup commanddocker execrequires a running container, butdocker run -itwith an overridden entrypoint keeps it alive- The
--rmflag is helpful during debugging to avoid container clutter - Use
docker inspectto see container configuration and state
Solution
Broken Application Files¶
app.py¶
from flask import Flask
import json
app = Flask(__name__)
# Load configuration
with open('/app/config.json', 'r') as f:
config = json.load(f)
@app.route('/')
def hello():
return f"Hello from {config['app_name']}! Running on port {config['port']}\n"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=config['port'])
requirements.txt¶
Dockerfile (Broken Version)¶
# syntax=docker/dockerfile:1
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
# Missing: config.json is NOT copied!
EXPOSE 5000
CMD ["python", "app.py"]
Step-by-Step Debugging Solution¶
1. Build the Broken Image¶
2. Attempt to Run (This Will Fail)¶
Observation: Container exits immediately with error.
3. Check the Logs¶
# If using --rm, run without it first to preserve the container
docker run --name flask-debug -p 5000:5000 broken-flask-app
# In another terminal
docker logs flask-debug
Expected Output:
Traceback (most recent call last):
File "/app/app.py", line 6, in <module>
with open('/app/config.json', 'r') as f:
FileNotFoundError: [Errno 2] No such file or directory: '/app/config.json'
Diagnosis: Missing config.json file!
4. Debug by Overriding the Entrypoint¶
Inside the container:
ls -la /app/
# Shows: app.py, requirements.txt - but NO config.json!
# Verify Python can't find it
python -c "open('/app/config.json')"
# Error: No such file or directory
5. Create the Missing Configuration File¶
Create config.json locally:
6. Fix Interactively with Volume Mount¶
# Mount the config file into the container for testing
docker run --rm -p 5000:5000 \
-v $(pwd)/config.json:/app/config.json \
broken-flask-app
Test the application:
Expected Output:
7. Apply Permanent Fix to Dockerfile¶
# syntax=docker/dockerfile:1
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
COPY config.json .
EXPOSE 5000
CMD ["python", "app.py"]
8. Rebuild and Verify¶
Test again:
9. Cleanup¶
docker rm -f flask-debug # If you created it without --rm
docker image rm broken-flask-app fixed-flask-app
Key Debugging Techniques Demonstrated¶
- Container Logs:
docker logs <container>- View stdout/stderr from crashed containers - Entrypoint Override:
docker run --entrypoint /bin/sh- Start a shell instead of the app - Interactive Exploration:
docker run -it- Explore the container filesystem - Volume Mounting:
-vflag - Test fixes without rebuilding - Container Inspection:
docker inspect <container>- View full container config - Process Monitoring:
docker top <container>- See running processes (if container stays up)
Common Docker Debugging Commands Reference¶
# View logs from a stopped container
docker logs <container>
# Start container with shell access
docker run --rm -it --entrypoint /bin/sh <image>
# Execute command in running container
docker exec -it <container> /bin/sh
# Inspect container configuration
docker inspect <container>
# View container filesystem changes
docker diff <container>
# Copy files from container to host
docker cp <container>:/path/to/file ./local-path
# View container resource usage
docker stats <container>
# See running processes
docker top <container>