🚀 Mastering the Dockerfile: A Developer’s Guide to Building Images with Docker


If you're exploring Docker, one of the first tools you’ll encounter is the Dockerfile, a script that defines how to build a Docker image from the ground up. Whether you're containerizing a simple web app or creating complex multi-stage builds, the Dockerfile is your starting point.
In this post, we’ll walk through what a Dockerfile is, why it’s important, and break down each key instruction with explanations and use-cases.
📦 What is a Dockerfile?
A Dockerfile is a text document that contains a series of commands/instructions. These commands tell Docker how to build an image, layer by layer.
Think of it as a recipe for your application’s container. Instead of manually typing out commands to install packages, set environment variables, or copy files, you write it all in a Dockerfile—once—and Docker handles the rest.
🧱 Dockerfile Basics
📝 Format
# This is a comment
INSTRUCTION arguments
Instructions are not case-sensitive, but UPPERCASE is preferred for readability.
The file must begin with a
FROM
instruction.Docker executes each line in the Dockerfile in order to create the image.
🔧 Essential Dockerfile Instructions (With Examples)
Here’s a breakdown of the most commonly used Dockerfile instructions:
1. FROM
– The Base Image
FROM ubuntu:20.04
This defines the base image you’re building on. Every Dockerfile must start with a FROM
.
2. RUN
– Execute Commands
RUN apt-get update && apt-get install -y curl
Used to run shell commands during build time. Each RUN
creates a new image layer.
3. COPY
– Copy Local Files
COPY ./app /usr/src/app
Copies files or directories from your host into the image.
4. ADD
– Like COPY
but More
ADD https://example.com/file.tar.gz /tmp/
Adds files/directories with support for remote URLs and automatic unpacking of compressed files.
5. CMD
– Default Command
CMD ["node", "app.js"]
Defines the default command to run when the container starts. Can be overridden.
6. ENTRYPOINT
– Main Executable
ENTRYPOINT ["python3"]
Like CMD
, but preferred when the container is meant to run a single application. Can work with CMD
for additional arguments.
7. ENV
– Set Environment Variables
ENV NODE_ENV=production
Persists an environment variable in the image.
8. ARG
– Build-Time Variables
ARG VERSION=1.0
RUN echo $VERSION
Used to pass values at build time using --build-arg
.
9. EXPOSE
– Document Ports
EXPOSE 3000
Indicates which port the container listens on (documentation only; doesn’t actually publish the port).
10. WORKDIR
– Set Working Directory
WORKDIR /usr/src/app
Sets the directory for subsequent instructions.
11. USER
– Set User
USER node
Specifies the username or UID the container should use.
12. VOLUME
– Define Mount Point
VOLUME /data
Creates a mount point for external volumes.
13. LABEL
– Add Metadata
LABEL maintainer="sonica@example.com"
Useful for adding metadata like version, author, or license.
14. HEALTHCHECK
– Monitor Container Health
HEALTHCHECK CMD curl --fail http://localhost:3000 || exit 1
Used to define a command that tests the container's health.
15. STOPSIGNAL
– Signal to Stop
STOPSIGNAL SIGTERM
Specifies the system signal used to stop the container gracefully.
16. ONBUILD
– Trigger for Child Builds
ONBUILD COPY . /app
Used to define instructions that execute later, when the image is used as a base for another build.
17. SHELL
– Override Default Shell
SHELL ["/bin/bash", "-c"]
Changes the shell used for RUN
commands.
📁 Sample Dockerfile: Node.js App
# Step 1: Base image
FROM node:18
# Step 2: Set working directory
WORKDIR /usr/src/app
# Step 3: Copy files
COPY package*.json ./
RUN npm install
COPY . .
# Step 4: Expose port and set command
EXPOSE 3000
CMD ["node", "server.js"]
🔍 Tips for Writing Better Dockerfiles
Minimize the number of layers by combining commands using
&&
.Use
.dockerignore
to avoid copying unnecessary files.Always pin to specific versions (e.g.,
python:3.11-slim
) for consistency.Keep your images lean by removing cache, temp files, or using
alpine
base images.
🧠 Final Thoughts
The Dockerfile is a cornerstone of containerized development. Once you master it, you'll have full control over how your application images are built, configured, and run.
If you’re just getting started with Docker, creating and modifying Dockerfiles is a great way to build hands-on skills. Start small, experiment often, and you'll be Docker-fluent in no time!
🔗 Resources
Let’s learn together. 🐳💬
Subscribe to my newsletter
Read articles from Sonica Sonawane directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Sonica Sonawane
Sonica Sonawane
Hi, I'm Sonica! 👋 I’m currently diving into the world of DevOps, focusing on AWS, Docker, Kubernetes, Linux, and GitHub. My passion lies in automating systems, building cloud infrastructure, and optimizing workflows. I’m committed to continuous learning, hands-on projects, and sharing my journey with others in the tech community. Before shifting to DevOps, I worked in IT Sales, where I gained valuable skills in client communication, requirement gathering, and problem-solving. This experience taught me how to connect technical solutions to business needs, which has been instrumental as I transition into DevOps, where technical expertise and problem-solving go hand in hand. Now, I’m eager to apply my sales experience alongside my growing technical skills in cloud engineering and DevOps. Join me as I explore the latest trends, challenges, and solutions in the world of cloud computing!