Docker Tutorial · Building Images · Lesson 7 of 26
Writing a Dockerfile
The Dockerfile instructions you need for most images: FROM, WORKDIR, COPY, RUN, ENV, EXPOSE and CMD.
A first Dockerfile
FROM python:3.14-slim # base image
WORKDIR /app # working directory for the next instructions
COPY app.py . # copy files from the build context
ENV GREETING=hello # environment variable baked into the image
EXPOSE 8000 # documents the port (doesn't publish it)
CMD ["python", "app.py"] # default command (exec form)
docker build -t NAME:TAG . builds an image from the Dockerfile in the current directory; the . is the
build context, the files COPY can see.
trap 'docker image rm -f rc-hello:1 > /dev/null 2>&1' EXIT
cat > app.py <<'EOF'
import os, platform
print(f"{os.environ['GREETING']} from Python {platform.python_version()}")
EOF
cat > Dockerfile <<'EOF'
FROM python:3.14-slim
WORKDIR /app
COPY app.py .
ENV GREETING=hello
CMD ["python", "app.py"]
EOF
docker build -q -t rc-hello:1 . > /dev/null
docker run --rm rc-hello:1
docker run --rm -e GREETING=bonjour rc-hello:1
Output
hello from Python 3.14.9 bonjour from Python 3.14.9
Run this on your computer — see “Get Started” for setup.
Use the exec form (["python", "app.py"]) for CMD and ENTRYPOINT, so your process receives signals
directly. See the Dockerfile reference.
Test yourself
What does EXPOSE 8000 do?
Publishes port 8000 on the hostDocuments that the app listens on 8000; it doesn't publish the portOpens the firewallStarts a web server
Show answer
Answer: Documents that the app listens on 8000; it doesn't publish the port
Publishing happens at run time with -p.