Containers and the Dockerfile · DevOps: Containers, CI and Kubernetes
How do you ship an app so it runs the same everywhere?
Course contentsWhy you need it
"It works on my machine" happens when servers have a different Python version, a missing library or another setting. A container image packages the app together with everything it needs, so the laptop, the test server and production all run exactly the same thing. Docker images are how most backend software is shipped today.
The intuition
A Dockerfile is the recipe for an image. Each line is one instruction, run from top to bottom:
| Instruction | Does |
|---|---|
FROM python:3.12-slim | start from a base image (an OS plus Python) |
WORKDIR /app | go to this folder (created if needed) |
COPY requirements.txt . | copy files from your project into the image |
RUN pip install … | run a command while building |
ENV PORT=8000 | set an environment variable |
EXPOSE 8000 | document the port the app listens on |
USER 1000 | run as this user instead of root |
CMD ["python", "app.py"] | the command to run when a container starts |
docker build -t shop . turns the Dockerfile into an image; docker run -p 8000:8000 shop starts a container from it. One image can run as many containers.
Press Run to see each build step and a summary of the final image. Warnings point out common mistakes. Image sizes in the output are rough estimates by this simulator; check real ones with docker images.
Definition
Image
A packaged, read-only snapshot of an app and everything it needs, built from a Dockerfile.
Container
A running instance of an image, isolated from the other processes on the machine.
RUN vs CMD
RUN executes while the image is built (installing things); CMD is what runs each time a container starts.
Examples
A Dockerfile for a Python web app
Run it in the lessonRun it to see the build steps and what the final image does.
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
USER 1000
CMD ["python", "app.py"]- L1Start from a small official Python image, pinned to a version.
- L3Copy only the dependency list first (the next lesson explains why).
- L4Install the libraries while building, so starting a container is fast.
- L5Then copy the rest of the project.
- L7Don't run as root: if the app is broken into, the attacker gets less.
- L8What a container runs when it starts. The ["..."] form runs the program directly, without a shell.
A Dockerfile with problems
Run it in the lessonIt builds, but the warnings list three real risks.
FROM python:latest
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
ENV API_KEY=sk_live_123
CMD python app.py- L1latest changes over time: next month's build may get a different Python.
- L5Anyone who can pull the image can read this key. Pass secrets when the container starts instead.
- L6No USER line, so the app runs as root.
Common mistakes
Using :latest
python:latest today and in three months are different images, so builds stop being repeatable. Pin a version such as python:3.12-slim.
Secrets in the image
ENV and COPY put values into the image layers for good. Give secrets to the container at start-up (environment variables or a secret store).
Running as root
By default the process in a container is root. Add a USER line so a bug in your app can't do as much damage.
Quick quiz
1. What is the difference between an image and a container?
Show the answer
Answer: A
Build once into an image, then start as many containers from it as you need.
2. `RUN pip install flask` and `CMD ["flask", "run"]`. When does each one run?
Show the answer
Answer: A
Build-time work goes in RUN; the start command goes in CMD.
Practice
3 exercises in three steps: predict what a program prints, change a program to meet a new requirement, then write one from scratch. Your code runs in the browser and is checked the moment you submit.
- PredictWhat actually starts?
A container starts from this image. What runs, as which user, in which folder?
- ModifyFix the risky Dockerfile
Fix three problems: pin the base image to
python:3.12-slim, run as a normal user (USER 1000), and remove the password from the image (it will be passed in when the container starts). - WriteContainerise a Node app
Write a Dockerfile for a Node.js server:
- base image
node:20-slim, working folder/app - copy
package.jsonandpackage-lock.jsonfirst and runnpm ci - then copy the rest of the project
- the server listens on port
3000 - run as the user
node(it exists in the image) - start with
node server.js(use the["..."]form)
- base image
Practise this lesson
Open the interactive lesson to edit and run these examples and solve the exercises with instant feedback. Free to start, no sign-up.
Terms in this lesson
| Term | Chinese | Definition |
|---|---|---|
| Docker | Docker | The most common tool for building and running containers. |
| Dockerfile | Dockerfile | The recipe for a container image. |
| Container image | 容器镜像 | An app packaged with everything it needs to run. |