Writing a Dockerfile
How to define a custom image with a Dockerfile and build it
Overview
A Dockerfile is a plain-text script of instructions that tells Docker how to build a custom image. Each instruction creates a cached layer, so ordering them well makes rebuilds fast. Once written, you build the image with docker build and run containers from it like any other image.
Syntax / Usage
Instructions are written in uppercase by convention and executed top to bottom. A typical Dockerfile starts from a base image, copies in code, installs dependencies, and defines a startup command.
# Start from an official base image
FROM node:20-alpine
# Set the working directory inside the image
WORKDIR /app
# Copy dependency manifests first for better caching
COPY package*.json ./
RUN npm install
# Copy the rest of the source
COPY . .
# Document the port and define the default command
EXPOSE 3000
CMD ["node", "server.js"]
Examples
Build an image from the Dockerfile in the current directory and tag it:
docker build -t myapp:1.0 .
A minimal Python Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "main.py"]
Common Mistakes
- Copying all source before installing dependencies, which breaks layer caching
- Using
CMDandRUNinterchangeably (RUNbuilds,CMDruns at start) - Forgetting a
.dockerignore, bloating the build context withnode_modules - Running as root instead of adding a non-privileged
USER - Using the
latesttag on a base image and getting unpredictable rebuilds
See Also
docker-images-and-containers docker-best-practices docker-compose