The "Works on My Machine" Problem
Key Takeaway: Docker lets students create reproducible Python environments that work identically on every machine. By packaging Python, dependencies, and project files into a container, the "works on my machine" problem disappears—and sharing projects with classmates becomes as simple as cloning a repository.
The "Works on My Machine" Problem
You install Python 3.11. Your classmate installs Python 3.9. You install pandas 2.2. They have pandas 1.5. Your code runs perfectly. theirs throws an import error.
This is the classic student environment problem. Dependencies conflict, versions mismatch, and hours are wasted debugging setup instead of learning.
Docker solves this by packaging your entire Python environment—interpreter, packages, and configuration—into a portable container that runs the same way everywhere.
What Is a Container?
A container is a lightweight, isolated environment that runs software with all its dependencies. Unlike a virtual machine, it shares the host operating system's kernel, making it fast and efficient.
| Feature | Local Install | Virtual Machine | Container |
|---|---|---|---|
| Isolation | Low | High | High |
| Resource overhead | Low | High | Low |
| Startup speed | Immediate | Slow | Fast |
| Reproducibility | Medium | High | High |
| Setup complexity | Low initially | Higher | Moderate |
Why Students Should Care
- Reproducibility — Same code, same results, same environment
- Easy setup — One command to start working
- Dependency isolation — Each project has its own packages
- Consistent Python version — No version conflicts
- Easy sharing — Share projects with classmates or instructors
- Clean environments — No pollution from other projects
Tools We Will Use
| Tool | Purpose | Required? |
|---|---|---|
| Docker Desktop | Run containers | Yes |
| Python 3.11 | Programming language | In container |
| VS Code | Code editor | Recommended |
| Git | Version control | Yes |
| JupyterLab | Notebook interface | In container |
| Pandas/NumPy | Data analysis | In container |
Install Docker
Download Docker Desktop from docker.com. Install it following the official instructions for your operating system.
Verify the installation:
docker --version
docker run hello-world
If you see a "Hello from Docker!" message, you're ready.
Create the Project Structure
student-python-workspace/
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── README.md
├── .gitignore
├── src/
│ └── analysis.py
├── tests/
│ └── test_analysis.py
├── notebooks/
├── data/
└── output/
Every directory has a purpose:
src/— Your Python source codetests/— Test filesnotebooks/— Jupyter notebooksdata/— Input data filesoutput/— Generated results and charts
Create requirements.txt
# Data Science dependencies
numpy==1.26.4
pandas==2.2.1
matplotlib==3.8.3
scikit-learn==1.4.1
# Jupyter environment
jupyterlab==4.1.1
# Testing
pytest==8.0.2
Why pin versions? Without version pins, pip install pandas might install different versions at different times, breaking reproducibility. Pinning ensures everyone gets the exact same packages.
Create the Dockerfile
# Use official Python slim image for smaller size
FROM python:3.11-slim
# Set working directory inside container
WORKDIR /app
# Copy requirements first (better Docker cache)
COPY requirements.txt .
# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy project files
COPY . .
# Expose JupyterLab port
EXPOSE 8888
# Default command: launch JupyterLab
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--port=8888",
"--no-browser", "--allow-root"]
Let's explain each instruction:
| Instruction | Purpose |
|---|---|
| FROM | Base image (Python 3.11 slim) |
| WORKDIR | Working directory inside container |
| COPY | Copy files from host to container |
| RUN | Execute commands during build |
| EXPOSE | Document which port is used |
| CMD | Default command when container starts |
Build the Docker Image
docker build -t student-python .
This reads the Dockerfile and creates a reusable image—a blueprint for running containers. Think of it as a snapshot of your complete environment.
Run Python Inside the Container
# Start a container with interactive shell
docker run -it student-python bash
# Inside the container, check Python version
python --version
# Run your analysis
python src/analysis.py
# Exit the container
exit
Python inside the container is Python 3.11 with all your packages installed—regardless of what Python version you have on your host machine.
Launch JupyterLab
# Run container with JupyterLab
docker run -p 8888:8888 -v $(pwd):/app student-python
Open http://localhost:8888 in your browser. JupyterLab runs inside the container with all packages available.
Security note: We bind to localhost only, so Jupyter is not exposed to your network.
Volume Mapping: Your Files Stay Safe
The -v $(pwd):/app flag maps your project folder into the container. This means:
- With volume: Your files are on your host machine and persist after the container stops
- Without volume: Files created inside the container disappear when it stops
Always use volume mapping for development so your work is saved on your host machine.
Docker Compose: The Easy Way
Docker Compose simplifies the workflow. Create docker-compose.yml:
version: "3.8"
services:
python-workspace:
build: .
ports:
- "8888:8888"
volumes:
- .:/app
working_dir: /app
stdin_open: true
tty: true
Now start your environment with:
# Build and start
docker compose up
# In another terminal, run analysis
docker compose exec python-workspace python src/analysis.py
# Stop when done
docker compose down
Live Exercise: Student Data Analysis
Let's run a complete Data Science exercise inside the container. Create src/analysis.py:
import pandas as pd
import numpy as np
# Create sample data
np.random.seed(42)
n_students = 100
departments = ["Computer Science", "Data Science",
"Mathematics", "Physics"]
df = pd.DataFrame({
"student_id": range(1, n_students + 1),
"age": np.random.randint(18, 25, n_students),
"department": np.random.choice(departments, n_students),
"marks": np.random.randint(50, 100, n_students),
})
# Save data
df.to_csv("data/students.csv", index=False)
# Analyze
print(f"Average marks: {df['marks'].mean():.1f}")
print("\nBy Department:")
print(df.groupby("department")["marks"].agg(
["mean", "count"]).round(1))
Run it inside the container:
docker compose exec python-workspace python src/analysis.py
Add Tests with pytest
Create tests/test_analysis.py:
import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__),
"..", "src"))
from analysis import create_sample_data
def test_create_sample_data():
df = create_sample_data()
assert len(df) == 100
assert "marks" in df.columns
assert df["marks"].min() >= 50
def test_departments():
df = create_sample_data()
valid = {"Computer Science", "Data Science",
"Mathematics", "Physics"}
assert set(df["department"].unique()).issubset(valid)
# Run tests inside container
docker compose exec python-workspace pytest tests/ -v
Git Workflow
# Initialize git
git init
git add .
git commit -m "Initial project setup with Docker"
# Create .gitignore
# (see .gitignore section below)
# Push to GitHub
git remote add origin https://github.com/you/project.git
git push -u origin main
Include Dockerfile, docker-compose.yml, and requirements.txt in your repository. Classmates can then clone and run the same environment instantly.
Reproducibility in Action
Three students clone the same repository:
# All three students run:
git clone https://github.com/professor/project.git
cd project
docker compose up
# Result: identical Python 3.11 environment
# with identical package versions
# on Windows, macOS, and Linux
The instructor provides the Dockerfile. Students get the same environment. Code runs consistently everywhere.
Security Basics
- Don't expose unnecessary ports — Only map ports you need
- Don't commit secrets — No API keys, passwords, or tokens in Dockerfiles
- Use .env files carefully — Never commit
.envto Git - Bind to localhost — Development services should not be network-accessible
- Keep images updated — Pull base images regularly
Troubleshooting
| Problem | Solution |
|---|---|
| Docker command not found | Install Docker Desktop and restart terminal |
| Port 8888 already in use | Change port mapping: "8889:8888" |
| Permission denied | Run sudo on Linux or check Docker permissions |
| Container exits immediately | Check logs: docker compose logs |
| Package installation fails | Check internet connection, retry build |
| Changes not appearing | Verify volume mapping is correct |
When Docker Is (and Isn't) Useful
Docker is great for:
- Courses and classroom environments
- Team projects with multiple contributors
- Data Science environments with many packages
- Reproducible assignments
- Preparing for production deployment
Docker may be unnecessary for:
- Single-file Python scripts
- Very early beginners learning syntax
- Simple exercises with no dependencies
Quick Start Summary
# 1. Clone the project
git clone https://github.com/your-repo/student-project.git
cd student-project
# 2. Build and start
docker compose up
# 3. Open JupyterLab
# → http://localhost:8888
# 4. Start coding!
# 5. When done
# Ctrl+C in terminal, then:
docker compose down
Key Takeaways
- Docker packages Python and dependencies into a reproducible container
- The Dockerfile defines your environment; docker-compose.yml simplifies running it
- Volume mapping keeps your files on your host machine
- Pin package versions for reproducibility
- Everyone on your team gets the same environment with one command
- Docker is not always necessary—for simple scripts, a local install may be fine
Related BestWordz Articles
- Run AI Locally on CPU Without GPU
- Optimize Python Data Science for 16GB RAM
- Build Semantic Search from Scratch with Python
Further Reading
- Docker Getting Started — Official Docker documentation
- Docker Compose Documentation — Official Compose docs
- Official Python Docker Images — Docker Hub
💬 Discuss this topic
Have questions or insights about The "Works on My Machine" Problem? Join the BestWordz Community.
📚 Related Articles
Can AI Really Run Without a GPU?
You don't need a GPU or a cloud API to start working with modern AI. A consumer CPU, sufficient RAM…
CybersecurityThe 10-Stage Data Science Roadmap
Data science in 2026 spans far beyond machine learning. A complete data scientist needs Python, sta…
CybersecurityThe 10-Stage CS Learning Roadmap
A computer science education in 2026 requires more than traditional coursework. Today's students ne…
CybersecurityWhat Is Prompt Engineering?
Key Takeaway Prompt Engineering is the skill of communicating effectively with AI models. It is not…
CybersecurityThe 8 Components of a Strong Portfolio
A GitHub portfolio isn't a collection of code — it's a signal to employers that you can build softw…
CybersecurityBuild a Private Local AI Assistant on Your Own Computer
You can build a complete AI assistant that runs entirely on your computer. No data leaves your mach…
🔧 Related Tools
AES-CBC Demonstration
Educational demonstration of AES-CBC mode - understand why AES-GCM is preferred.
Try it now →AES-CTR Demonstration
Educational demonstration of AES-CTR (Counter) mode.
Try it now →bcrypt Password Hash Generator
Hash passwords with bcrypt - widely supported adaptive hashing.
Try it now →HMAC-SHA256 Generator
Generate an HMAC-SHA256 signature from a key and message, entirely in your browser.
Try it now →💬 Discuss on BestWordz Community
Join the conversation about Python, Docker, RAG on the BestWordz Community forum.
Visit Forum →