Skip to content

Anatomy of a Dockerfile

A Dockerfile is the literal text file recipe used to build an image.

It tells the Docker Engine exactly what to start with, what to do, and which command to run when an instance finally starts up.

Here is a super-simple, example Dockerfile for a basic Node application:

Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Hang Tight

We’ll break down each instruction in this Dockerfile in the next section. After that, we’ll write our own to containerize an app.

This is small, but it does a massive amount of heavy lifting.

It translates directly to:

  • start from a lightweight Node 20 base image
  • set up shop inside an /app directory
  • copy only the package manifest files first
  • install the node_modules dependencies
  • copy the rest of the application files over
  • document that the app listens on port 3000
  • define the default start command

With just those lines, we’ve defined exactly how our application should be packaged.

Capitalization Matters

By strict convention, a Dockerfile must be named exactly that. This means a capital D and no file extension.

Docker Engine will look for this Dockerfile, automatically, in the project root.


Dockerfile Reference Docs


Browse Docker Hub

There are six instructions that are almost always present in a Dockerfile.

Let’s unpack them, one by one.