stackademic

The leading education platform for anyone with an interest in software development.

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 CMD and RUN interchangeably (RUN builds, CMD runs at start)
  • Forgetting a .dockerignore, bloating the build context with node_modules
  • Running as root instead of adding a non-privileged USER
  • Using the latest tag on a base image and getting unpredictable rebuilds

See Also

docker-images-and-containers docker-best-practices docker-compose