Module 09 / Project 01 — First Dockerfile¶
Home: README
Learn Your Way¶
| Read | Build | Watch | Test | Review | Visualize | Try |
|---|---|---|---|---|---|---|
| — | This project | Walkthrough | — | Flashcards | — | — |
Focus¶
Writing a Dockerfile, building an image, and running a container.
Why this project exists¶
Docker packages your application and all its dependencies into a single image that runs the same way on every machine. No more "it works on my laptop" problems. This project teaches you the fundamental Docker workflow: write a Dockerfile, build an image, run a container. Every deployment pipeline in the industry starts here.
Run¶
Without Docker (verify the app works locally first)¶
Visit http://127.0.0.1:8000 to confirm it works, then stop the server with Ctrl+C.
With Docker¶
Step 1 — Build the image. This reads the Dockerfile and creates an image named first-dockerfile:
You will see Docker execute each instruction. The first build downloads the base image and installs dependencies (slow). Subsequent builds reuse cached layers (fast).
Step 2 — Run a container from the image:
The -p 8000:8000 flag maps port 8000 on your machine to port 8000 inside the container.
Step 3 — Visit your app:
- http://127.0.0.1:8000 — root endpoint
- http://127.0.0.1:8000/health — health check
- http://127.0.0.1:8000/docs — interactive API docs
Step 4 — Stop the container with Ctrl+C.
Useful Docker commands¶
docker images # list all images on your machine
docker ps # list running containers
docker ps -a # list all containers (including stopped)
docker rm <container_id> # remove a stopped container
docker rmi first-dockerfile # remove the image
Expected output¶
Visiting http://127.0.0.1:8000 returns:
Visiting http://127.0.0.1:8000/health returns:
Alter it¶
- Add a
GET /infoendpoint that returns{"container": True, "python_version": "3.12"}. Rebuild the image and verify. - Change the
CMDin the Dockerfile to run on port 9000. Update theEXPOSEinstruction and thedocker runcommand to match. - Add a
--name my-appflag todocker runso you can refer to the container by name instead of ID.
Break it¶
- Remove the
COPY requirements.txt .andRUN pip installlines from the Dockerfile. Rebuild and try to run. What error do you get? - Change
--host 0.0.0.0to--host 127.0.0.1in the CMD instruction. Rebuild and run. Can you reach the app from your browser? Why not? - Swap the order of
COPY requirements.txt .andCOPY . .so all files are copied in one step. Does it still work? What happens to build caching when you change onlyapp.py?
Fix it¶
- Restore the
COPY requirements.txtandRUN pip installlines. The app cannot start without its dependencies installed in the image. - Change the host back to
0.0.0.0. Inside a container,127.0.0.1only accepts connections from inside the container itself, not from the host machine. - Separate the two COPY steps again. With a single COPY, every code change invalidates the pip install cache and forces a slow reinstall.
Explain it¶
- What is the difference between a Docker image and a Docker container?
- Why does the Dockerfile copy
requirements.txtand runpip installbefore copying the rest of the code? - What does
-p 8000:8000mean in thedocker runcommand? What happens if you use-p 3000:8000? - Why does the CMD use
--host 0.0.0.0instead of--host 127.0.0.1?
Mastery check¶
You can move on when you can:
- write a Dockerfile from scratch without looking at this one,
- build an image and run a container with port mapping,
- explain why layer order matters for build caching,
- describe the difference between EXPOSE and
-p.
Related Concepts¶
Next¶
Continue to 02-multi-stage-build.