Assignment: Containerize and Ship
History of Containers and CI/CD
These exercises let you practice Docker, CI, and dependency management concepts from this week.
<aside> 📝 These exercises are optional. Use them to reinforce the concepts from this week before starting the assignment.
</aside>
All Week 5 exercises live under data-track/week-5/ in HYF's Learning-Resources repo. One Codespace covers all seven exercises.
<aside> 💻 Open in GitHub Codespaces
</aside>
The devcontainer boots Python 3.11 + ruff + Pylance. Exercises 1–3, 6–7 also require Docker (included in the Codespace via Docker-in-Docker). From the Explorer, navigate into data-track/week-5/exercise_N/.
Prefer your own VS Code? Clone locally:
git clone <https://github.com/HackYourFuture/Learning-Resources.git>
cd Learning-Resources/data-track/week-5
Each exercise folder ships a README.md with setup steps, task list, and success criteria.
Each exercise_N/solutions/ folder holds the reference answer. The original # TODO comments are preserved, and # WHY ...: notes explain the non-obvious choices.
Read the WHY notes, not just the code. The reasoning is what carries into real projects.
Time-box yourself: 15–30 minutes of honest attempt before opening solutions/. You can diff your work against the reference:
diff exercise_1/Dockerfile exercise_1/solutions/Dockerfile
The solution sits next to your starter under solutions/ rather than on a separate branch. The folder name is the whole barrier, and it is enough.
Concepts: Dockerfile basics, environment variables.
Create a minimal pipeline script in src/pipeline.py:
import os
api_key = os.environ.get("API_KEY", "missing")
print(f"API key present: {api_key != 'missing'}")
Instructions:
pipeline-practice:1.0.API_KEY=demo and confirm the output changes.<aside>
📦 Files: exercise_1/: use the Codespace you opened at the top of this page.
</aside>
Concepts: Docker layers and caching with requirements.txt.
Instructions:
requirements.txt file with requests==2.31.0.requirements.txt first and installs dependencies before copying the rest of the source. You can use the script above as code. Build the docker image.<aside>
📦 Files: exercise_2/: includes a BAD Dockerfile; identify the problem and fix it.
</aside>
Concepts: Docker layers and locked installs with uv.
Instructions:
pyproject.toml with requests==2.31.0.uv.lock.pyproject.toml and uv.lock first, installs uv, and runs uv sync --frozen --no-dev before copying the rest of the source.pyproject.toml, regenerate uv.lock, and build again. Confirm that the dependency layer now rebuilds.<aside>
📦 Files: exercise_3/: includes pyproject.toml and a committed uv.lock.
</aside>
Concepts: requirements.txt vs uv in Docker.
Instructions:
uv sync --frozen is stricter than a plain dependency install from requirements.txt.<aside>
📦 Files: exercise_4/: written comparison task, check your answers against solutions/answers.md.
</aside>
Concepts: GitHub Actions, testing.
Instructions:
tests/test_smoke.py that asserts True.pytest -q.<aside>
📦 Files: exercise_5/: includes a starter tests/test_smoke.py and a .github/workflows/ci.yml with TODOs to fill in.
</aside>
Concepts: -e, --env-file, ARG vs ENV.
Instructions:
.env file with API_KEY=demo and LOG_LEVEL=DEBUG.--env-file .env and confirm both values are read.ARG BUILD_SHA to your Dockerfile and pass it with --build-arg BUILD_SHA=abc123. Print it during the build.ARG values are not available at runtime.<aside>
📦 Files: exercise_6/: includes .env.example; copy to .env before running.
</aside>
Concepts: Version tags.
Instructions:
dev, staging, and prod.docker images and confirm all three tags exist for the same Image ID.<aside>
📦 Files: exercise_7/: written tagging task, check your answers against solutions/answers.md.
</aside>