Package the vault so it runs identically anywhere — killing "works on my machine" for good.
Module 8 · Docker & Compose, bridging into the DevOps Lab.
Intermediate Containers Includes Lab ~50 min.dockerignore and small base imagesPrerequisites: Module 7, Docker Desktop installed. This module bridges into the DevOps Lab: Docker and Compose modules.
Failure mode #6: "works on my machine." Your app runs for you because your laptop has the right Node version, the right packages, the right environment. A container packages the app with all of that — a sealed box that runs the same on your machine, a teammate's, a CI runner, and a production server.
| Term | Plain meaning |
|---|---|
| Image | A blueprint: your app + its runtime + dependencies, frozen. |
| Container | A running instance of an image — an isolated mini-machine. |
| Dockerfile | The recipe that builds the image, step by step. |
Once the vault is a container, every later step gets easy: CI builds the same image, and deploy just runs it. Containerizing is the hinge between "my project" and "a shippable product."
Each app in your monorepo gets its own Dockerfile. Here's the shape for the NestJS API — the assistant will fill in the specifics:
A .dockerignore (like .gitignore) keeps node_modules and secrets out of the image, making builds faster and safer.
Use a small base (-alpine), install only production deps in the final image, and never bake .env secrets in. Ask the assistant for a multi-stage build if the image is big — and review it, just like any other diff.
The vault is two apps (plus, later, a database). Docker Compose describes them in one file and starts them together with a single command — networked so web can talk to api.
The DevOps Lab Compose module walks the same idea in depth (app + database + monitoring). We reuse it here so you're not learning Compose twice.
A containerized app is deployable anywhere that runs containers — a VM, Kubernetes, a managed host. That's the foundation for the last three modules: CI builds the image, deploy runs it, monitoring watches it. Everything downstream assumes this box exists.
You'll add a Dockerfile to each app and a Compose file, then run the whole snippet vault in Docker — no local Node needed.
Your snippet-vault repo from Module 7 and Docker Desktop running.
Ask the assistant for a Dockerfile and .dockerignore for api/ and for web/, using small alpine base images. Review each diff — check no secrets are copied in.
Open the app in the browser. Create, list, search, and delete a snippet — all running inside containers.
Stop your locally-run Node processes entirely. The app should still work through Compose — because everything it needs is in the containers, not your machine.
In REFLECTION.md: what was in your environment that the container now provides for you? Commit it.
Your snippet-vault repo. Self-check:
.dockerignore for both api/ and web/docker compose up runs the whole app; it works in the browserREFLECTION.md notes what the container replaced| Term | Plain meaning |
|---|---|
| Image | A frozen blueprint of an app and everything it needs to run. |
| Container | A running, isolated instance of an image. |
| Dockerfile | The step-by-step recipe to build an image. |
| Compose | A tool to define and run multiple containers together. |
| .dockerignore | Files to exclude from the image build (like node_modules). |
The whole snippet vault packaged into containers and running with one Compose command — identical everywhere. "Works on my machine" is dead.
Next up: Module 9 — CI/CD Pipeline. We put the tests, gates, and image build on autopilot with GitHub Actions, so every push is checked and built automatically.