Writing a Dockerfile
A Dockerfile is a text file with step-by-step instructions Docker uses to build an image.
Syntax
FROM base-image
WORKDIR /app
COPY . .
RUN some-command
CMD ["executable", "arg"]A Dockerfile is a plain text file that lists the instructions Docker follows to assemble an image. Each instruction is a keyword in capital letters.
Common instructions
FROM— the base image to start from.WORKDIR— sets the working directory inside the image.COPY— copies files from your machine into the image.RUN— executes a command at build time (for example, install packages).EXPOSE— documents which port the app listens on.CMD— the default command run when a container starts.
Order matters
Docker runs the instructions top to bottom, and each one becomes a cached layer. Put things that change rarely (like installing dependencies) near the top.
Example
# A simple Dockerfile for a Node.js app
FROM node:20-alpine
WORKDIR /app
# Copy dependency files first for better caching
COPY package*.json ./
RUN npm install
# Copy the rest of the source
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]When to use it
- A backend team writes a Dockerfile to reproducibly build their Go service into an image for every CI run.
- A data scientist writes a Dockerfile to freeze their Python environment so a model always trains with the same package versions.
- An ops engineer writes a Dockerfile for an internal CLI tool so any team member can use it without installing dependencies.
More examples
Minimal Node.js Dockerfile
A basic Dockerfile that installs production dependencies and starts a Node.js server.
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]Python app Dockerfile
Builds a Python application image using a slim base to keep the image size small.
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]Dockerfile with HEALTHCHECK
Adds a health check so Docker knows the container is ready and restarts it if it becomes unhealthy.
FROM nginx:alpine
COPY ./html /usr/share/nginx/html
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget -qO- http://localhost/ || exit 1
EXPOSE 80
Discussion