Your First Dockerfile
Everything so far has used an image called quicknotes:1.0. Time to make it. The quicknotes folder holds app.py, which serves the notes page on port 5000, and requirements.txt, which lists its libraries. One more small text file, the Dockerfile, turns that folder into an image anyone can run.
The rule
FROM a base, COPY your code, RUN the setup, CMD the start.
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]Line by line:
FROMpicks the starting image: here a slim Debian with Python 3.12 already installed. Every Dockerfile begins with it.WORKDIR /appcreates/appif needed and makes it the current directory for everything after.COPY requirements.txt .copies a file from your folder (the build context) into/app.RUNexecutes a command during the build and saves the result as a layer: here, installing the libraries.COPY . .copies the rest of the code.EXPOSE 5000documents which port the app listens on. It does not publish anything;-pstill does that.CMDsets the default command that runs when a container starts. The bracketed "exec form" runs Python directly, without a shell in between.
One detail about app.py: inside a container the app must listen on all interfaces (0.0.0.0), not just 127.0.0.1, or published ports cannot reach it.
Build and run it from the quicknotes folder:
docker build -t quicknotes:1.0 .
docker run -d --name notes -p 8080:5000 quicknotes:1.0The final . is the build context: the folder whose files COPY can see. A .dockerignore file keeps things like .git or local virtual environments out of it.
The shortcut
Sort every instruction into build time or start time. FROM, WORKDIR, COPY and RUN do their work during docker build and are frozen into the image. CMD does nothing during the build; it is only a note saying what to run later.
First build
Each instruction runs and becomes a cached layer, including the slow
pip install.
Drills
Answer fast — trust the rule.
Which instruction must a Dockerfile start with (apart from comments and build arguments)?
When does the command in RUN pip install -r requirements.txt execute?
What does EXPOSE 5000 do on its own?
You change only app.py and rebuild. Which step is served from the cache?
What does the final . in docker build -t quicknotes:1.0 . mean?
Remember
- FROM a base, COPY your code, RUN the setup, CMD the start.
- Shortcut: sort instructions into build time (FROM, COPY, RUN) and start time (CMD).
- Trap: EXPOSE does not publish, and copying all code before installing libraries wastes the cache.
