Dockerfile — a text file with instructions for building an image. Each instruction becomes a layer.
Minimal Python Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
Core Instructions
FROM — base image. Always the first line.
FROM python:3.11-slim
FROM ubuntu:22.04
FROM scratch # empty image
WORKDIR — working directory inside the container. Created automatically.
WORKDIR /app
COPY — copy files from the host into the image.
COPY app.py . # copy a file
COPY . . # copy everything
COPY src/ /app/src/ # copy a directory
RUN — run a command at build time. The result is saved into the image.
RUN pip install flask
RUN apt-get update && apt-get install -y curl
CMD — default command when the container starts.
CMD ["python", "app.py"]
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"]
EXPOSE — documents the port (does not actually publish it, just informational).
EXPOSE 8000
ENV — environment variable.
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
Building and Running
# Build an image with a tag
docker build -t myapp:v1 .
# Build with a different Dockerfile
docker build -f Dockerfile.prod -t myapp:prod .
# Run
docker run -p 8000:8000 myapp:v1
.dockerignore
The .dockerignore file at the project root works like .gitignore for Docker. It excludes files from the build context.
.venv/
__pycache__/
*.pyc
.git/
.env
tests/
*.md
Without .dockerignore, Docker copies everything into the image including .git and node_modules — builds will be slow and images will be bloated.
CMD vs ENTRYPOINT
# CMD — can be overridden at runtime:
CMD ["python", "app.py"]
# docker run myapp python other.py ← replaces CMD
# ENTRYPOINT — fixes the command; CMD becomes its arguments:
ENTRYPOINT ["python"]
CMD ["app.py"]
# docker run myapp other.py ← runs python other.py
💬 Comments (0)
No comments yet
Be the first to share your opinion about this article!