
Developer Runbook
Developer Environment Setup Runbook
A calm, step-by-step developer runbook for your local machine. Learn the exact command line habits, Python virtual environments, Git practices, and Docker Compose configurations needed for Day 11, Day 36, and Project #1.
Local Machine Setup for Data Engineers
In Days 1 to 3, our interactive browser workspace runs SQL directly in your browser. However, real data pipelines run as background jobs on headless servers. When you reach Day 11 (testing with pytest), Day 36 (Project #1 local ingestion), or production deployment, you need a dependable environment on your own laptop.
This runbook walks through the exact tools every junior data engineer uses daily: the command line, Python virtual environments, Git version control, and Docker multi-container stacks.
Terminal & Shell Fundamentals
Data pipelines execute inside Linux cloud containers without a mouse or graphical user interface. Your terminal is the primary interface for inspecting files, debugging logs, and invoking extraction jobs.
Platform Choice: macOS vs Windows
On macOS, open Terminal (which uses zsh by default). On Linux, open your preferred shell.
On Windows, do not rely on standard Command Prompt. Instead, install WSL2 (Windows Subsystem for Linux). WSL2 gives you an authentic Linux kernel directly inside Windows, ensuring that paths, file permissions, and Docker networking behave identically to cloud production environments.
Run this command inside Windows PowerShell as an Administrator, then restart your PC.
wsl --install -d UbuntuUbuntu has been installed. Restart your machine to finish setup.
Essential Navigation Commands
You only need five foundational shell commands to manage data projects. Practice these until they are second nature.
Print directory, list details, change folder, and create project directories.
# 1. Print Working Directory: see where you currently stand
pwd
# 2. List files: -l shows permissions and sizes, -a reveals hidden config files like .env
ls -la
# 3. Create a project directory tree safely with parent folders (-p)
mkdir -p ~/projects/shopkart-pipeline/src
# 4. Change directory into your new project folder
cd ~/projects/shopkart-pipeline
# 5. Move back up one folder level
cd ..Environment Variables
Pipelines must never hardcode database passwords, API keys, or hostnames inside Python code. Instead, code reads from environment variables supplied by the shell or container runtime.
Export a variable in your shell session, print it, and pass it to a Python process.
# Export variable in current shell session
export DB_PORT="5432"
export PIPELINE_ENV="development"
# Verify variable value
echo "Connecting on port: $DB_PORT"
# Run a Python one-liner to verify Python reads the variable
python3 -c "import os; print('Python saw port:', os.getenv('DB_PORT'))"Connecting on port: 5432\nPython saw port: 5432
If a script fails with “FileNotFoundError: No such file or directory: orders.csv”, check where you ran the command from. Running python src/ingest.py from the repo root evaluates relative paths relative to your current terminal folder, not the location of ingest.py. Always check pwd before launching jobs.
Python 3.11+ & Virtual Environments
Never install project packages into your global operating system Python. Global installations cause dependency conflicts between projects and can corrupt system tools that depend on specific library versions.
Check Your Python Version
Ensure Python 3.11 or newer is installed. Python 3.11 introduced substantial performance improvements for data parsing and improved error tracebacks.
Check version string for both python3 and pip.
python3 --version
pip3 --versionPython 3.11.8 (or higher)\npip 24.0 from ...
Creating and Activating a Virtual Environment
A virtual environment is a self-contained directory tree that contains a specific Python interpreter and a dedicated set of libraries.
Create a hidden environment folder named .venv and activate it.
# 1. Navigate to your project folder
cd ~/projects/shopkart-pipeline
# 2. Create the virtual environment folder
python3 -m venv .venv
# 3. Activate the environment (macOS / Linux / WSL)
source .venv/bin/activate
# 4. Verify your active python binary points inside .venv
which python/Users/yourname/projects/shopkart-pipeline/.venv/bin/python
For Windows users running PowerShell without WSL2.
# If PowerShell restricts scripts, enable local execution once:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# Activate the environment:
.\.venv\Scripts\Activate.ps1Managing Dependencies with pip and requirements.txt
Once (.venv) appears at the start of your terminal prompt, any packages you install stay isolated to this project.
Upgrade pip, install key data libraries, and lock dependencies to requirements.txt.
# 1. Always upgrade pip inside a fresh environment
pip install --upgrade pip
# 2. Install core libraries needed for our curriculum
pip install duckdb pandas pytest pydantic requests
# 3. Export exact pinned versions to requirements.txt
pip freeze > requirements.txt
# 4. Review the generated requirements
head -n 5 requirements.txtIf you open a new terminal window or tab, your virtual environment is not automatically active! Always verify that (.venv) is visible in your prompt before running pip install. To exit an active environment when you finish working, type deactivate.
Git & GitHub Workflow
Git records the precise history of every line of code you change. In engineering teams, nobody writes code directly on the primary branch. You branch, commit small atomic changes, push to GitHub, and open a Pull Request.
First-Time Git Configuration
Configure your committer identity once on your laptop so your GitHub commits show your name.
Set your global Git name and email.
git config --global user.name "Your Full Name"
git config --global user.email "[email protected]"
git config --global init.defaultBranch mainThe Essential .gitignore File
Certain files must never be tracked in version control: virtual environment binaries, credentials in .env, cache folders, and local data dumps. Create a .gitignore file before your first commit.
Write a standard ignore file that blocks secrets, environments, and large local files.
cat << 'EOF' > .gitignore
# Virtual environments
.venv/
env/
venv/
# Environment files and credentials (never commit secrets!)
.env
.env.local
*.pem
credentials.json
# Byte-compiled / cache files
__pycache__/
*.py[cod]
.pytest_cache/
# Local raw data and Parquet caches
data/raw/
data/bronze/
*.parquet
*.csv
# Operating system noise
.DS_Store
Thumbs.db
EOFDaily Branching and Pull Request Flow
Follow this disciplined 4-step sequence for every feature you build.
git checkout -b feat/keyset-extractor
Your changes live apart from main.
git commit -m "feat: keyset cursor"
Each commit solves one problem and has a test.
CI runs: ruff, pytest, tsc
Automatic checks must pass before anyone can merge.
merge into protected main
The branch becomes one clean commit and is deleted.
Create a feature branch, make edits, stage changes, commit, and push to GitHub.
# Step 1: Initialize local repository (if new project)
git init
# Step 2: Create and switch to a descriptive feature branch
git checkout -b feat/ingest-orders-bronze
# Step 3: Check status and stage modified files
git status
git add src/ingest.py requirements.txt .gitignore
# Step 4: Create a concise, meaningful commit
git commit -m "feat(ingest): add keyset pagination extractor for orders"
# Step 5: Link remote and push branch to GitHub
git remote add origin https://github.com/your-username/shopkart-pipeline.git
git push -u origin feat/ingest-orders-bronzeOpening a Clean Pull Request (PR):
- Visit your repository URL on GitHub. A prompt will appear: “Compare & pull request”.
- Provide a clear title:
feat: Ingest ShopKart orders into Bronze Parquet. - In the PR description, explain what problem you solved, what tests you ran, and any schema trade-offs.
- When working in a team or reviewing your own portfolio work, verify automated CI tests pass before merging.
Docker & Containerization Basics
“It worked on my laptop” does not fly when a job fails in production. Docker packages your pipeline code, Python libraries, and Linux system dependencies together into an immutable container that behaves the exact same way on your MacBook, an Ubuntu server, or an AWS worker.
Core Mental Model: Image vs Container
An Image is the static blueprint: a read-only recipe containing your code, Python packages, and Linux base. A Container is a running instance created from that blueprint. You can start five isolated containers from a single image.
Install Docker Desktop:
Download and install Docker Desktop for your operating system from the official Docker website. If using Windows, ensure the “Use WSL 2 instead of Hyper-V” setting is selected during setup.
Test that the Docker engine and Docker Compose plugin are operational.
docker --version
docker compose version
docker run --rm hello-worldHello from Docker! This message shows that your installation appears to be working correctly.
Writing a Minimal Pipeline Dockerfile
Here is the standard, production-ready Dockerfile pattern for running a Python data extraction job:
Multi-layer recipe with slim Linux base and isolated dependency caching.
# 1. Use a lightweight, official Python base image
FROM python:3.11-slim
# 2. Set working directory inside container
WORKDIR /app
# 3. Copy only dependency manifest first to leverage Docker layer caching
COPY requirements.txt .
# 4. Install dependencies without caching downloaded wheels to minimize image size
RUN pip install --no-cache-dir -r requirements.txt
# 5. Copy pipeline source code
COPY src/ ./src/
# 6. Default command to execute when container starts
CMD ["python", "src/ingest.py"]Build image tagged as 'shopkart-ingest:v1' and execute it.
# Build the image from current directory (.)
docker build -t shopkart-ingest:v1 .
# Run container and automatically remove it (--rm) upon completion
docker run --rm -e PIPELINE_ENV=production shopkart-ingest:v1Multi-Container Stacks with Docker Compose
In Project #1 and real data pipelines, you do not want to install PostgreSQL, MinIO, or Airflow directly on your personal laptop. Docker Compose allows you to define and spin up all supporting services with one command.
A local PostgreSQL database service for running extraction exercises.
version: "3.8"
services:
postgres:
image: postgres:15-alpine
container_name: shopkart-postgres
restart: always
environment:
POSTGRES_USER: shopkart_user
POSTGRES_PASSWORD: shopkart_password
POSTGRES_DB: shopkart_oltp
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:Start services in background, inspect health, check logs, and clean up.
# Start stack in background (-d = detached)
docker compose up -d
# Check running container status
docker compose ps
# Follow live output logs for the database container (-f = follow)
docker compose logs -f postgres
# Stop and remove containers when you are done working
docker compose downLocal Environment Health Check
Run this copy-paste Python script on your machine to verify that your Python interpreter, virtual environment, Git binary, and Docker daemon are all configured and communicating properly.
A zero-dependency diagnostic script that tests all four prerequisites.
import sys
import subprocess
import shutil
def check_status(name: str, passed: bool, detail: str):
icon = "✓" if passed else "✗"
status = "OK" if passed else "FAILED"
print(f"[{icon}] {name:<22}: {status} ({detail})")
return passed
def run():
print("=" * 60)
print(" LAKEBENCH 45-DAY PLAN: LOCAL ENVIRONMENT HEALTH CHECK")
print("=" * 60)
all_good = True
# 1. Python version >= 3.11
py_ver = sys.version_info
py_pass = py_ver.major == 3 and py_ver.minor >= 11
all_good &= check_status(
"Python Version",
py_pass,
f"Detected {py_ver.major}.{py_ver.minor}.{py_ver.micro}"
)
# 2. Virtual environment check
is_venv = sys.prefix != sys.base_prefix
all_good &= check_status(
"Virtual Environment",
is_venv,
"Active (.venv)" if is_venv else "Warning: Running in global Python"
)
# 3. Git executable
git_path = shutil.which("git")
git_pass = git_path is not None
git_ver = "Not found"
if git_pass:
try:
res = subprocess.run(["git", "--version"], capture_output=True, text=True, check=True)
git_ver = res.stdout.strip()
except Exception as e:
git_pass = False
git_ver = str(e)
all_good &= check_status("Git Binary", git_pass, git_ver)
# 4. Docker CLI
docker_path = shutil.which("docker")
docker_pass = docker_path is not None
docker_detail = "Not found"
if docker_pass:
try:
res = subprocess.run(["docker", "info"], capture_output=True, text=True)
if res.returncode == 0:
docker_detail = "Daemon running & responsive"
else:
docker_pass = False
docker_detail = "Docker installed, but daemon is stopped"
except Exception as e:
docker_pass = False
docker_detail = str(e)
all_good &= check_status("Docker Daemon", docker_pass, docker_detail)
# 5. Docker Compose
compose_pass = False
compose_detail = "Not found"
if docker_path:
try:
res = subprocess.run(["docker", "compose", "version"], capture_output=True, text=True)
if res.returncode == 0:
compose_pass = True
compose_detail = res.stdout.strip()
except Exception:
pass
all_good &= check_status("Docker Compose", compose_pass, compose_detail)
print("=" * 60)
if all_good:
print("CONGRATULATIONS: Your local machine is ready for Day 11 and Project #1!")
else:
print("ACTION REQUIRED: Review the failed items above using the runbook instructions.")
print("=" * 60)
if __name__ == "__main__":
run()============================================================ LAKEBENCH 45-DAY PLAN: LOCAL ENVIRONMENT HEALTH CHECK ============================================================ [✓] Python Version : OK (Detected 3.11.8) [✓] Virtual Environment : OK (Active (.venv)) [✓] Git Binary : OK (git version 2.44.0) [✓] Docker Daemon : OK (Daemon running & responsive) [✓] Docker Compose : OK (Docker Compose version v2.26.1) ============================================================ CONGRATULATIONS: Your local machine is ready for Day 11 and Project #1! ============================================================
Official Documentation & Installation References
For platform-specific troubleshooting, refer strictly to the official maintainer documentation:
Environment Ready?
Return to the 45-day curriculum and continue with Day 1 foundations or your next scheduled day.