Writing Your First Dockerfile
Learn how to create Docker images using Dockerfiles and understand the most common instructions.
Writing Your First Dockerfile
A Dockerfile is a text file containing instructions used to build a Docker image.
Think of a Dockerfile as a recipe. Docker follows each instruction step-by-step and produces a reusable image that can be deployed anywhere.
What Is a Dockerfile?
A Dockerfile defines:
- The base image
- Application dependencies
- Working directories
- Environment variables
- Startup commands
Example:
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Understanding Dockerfile Instructions
FROM
Every Dockerfile starts with a base image.
FROM node:20
Docker downloads the image if it does not already exist locally.
WORKDIR
Sets the working directory inside the container.
WORKDIR /app
All future commands run from this location.
COPY
Copies files from your host machine into the image.
COPY . .
You can also copy specific files:
COPY package.json .
RUN
Executes commands while building the image.
RUN npm install
Common uses:
- Installing dependencies
- Updating packages
- Compiling source code
EXPOSE
Documents which port the application uses.
EXPOSE 3000
This does not publish the port automatically.
CMD
Defines the default command executed when the container starts.
CMD ["npm", "start"]
Only one CMD instruction should exist in a Dockerfile.
Building the Image
Navigate to your project directory and run:
docker build -t my-app:v1 .
Docker reads the Dockerfile and creates an image.
Verify:
docker images
Running the Image
Start a container:
docker run -p 3000:3000 my-app:v1
Your application should now be accessible through your browser.
Best Practices
Use Specific Versions
Avoid:
FROM node:latest
Prefer:
FROM node:20
Reduce Image Size
Use lightweight base images when possible:
FROM node:20-alpine
Leverage Layer Caching
Copy dependency files first:
COPY package*.json ./
RUN npm install
This improves rebuild performance.
Summary
Dockerfiles provide a repeatable way to package applications and dependencies into portable images that can run consistently across environments.