The Ultimate Guide to Writing a Dockerfile: Best Practices & Examples

Author

Kritim Yantra

Apr 14, 2025

The Ultimate Guide to Writing a Dockerfile: Best Practices & Examples

A Dockerfile is a script that contains instructions to build a Docker image. It automates the process of setting up environments, installing dependencies, and configuring applications.

In this guide, you’ll learn:
Dockerfile syntax & best practices
How to optimize Docker images
Real-world Dockerfile examples


Table of Contents

  1. What is a Dockerfile?
  2. Basic Dockerfile Structure
  3. Essential Dockerfile Instructions
  4. Optimizing Dockerfile (Best Practices)
  5. Multi-Stage Builds
  6. Real-World Dockerfile Examples
  7. Conclusion

1. What is a Dockerfile?

A Dockerfile is a text file that defines:

  • The base image (e.g., ubuntu, python).
  • Commands to install dependencies.
  • Files to copy into the image.
  • Commands to run when the container starts.

Why Use a Dockerfile?

Reproducibility – Same image every time.
Automation – No manual setup needed.
Version Control – Track changes in Git.


2. Basic Dockerfile Structure

A simple Dockerfile looks like this:

# Step 1: Choose a base image
FROM python:3.9-slim

# Step 2: Set working directory
WORKDIR /app

# Step 3: Copy requirements and install dependencies
COPY requirements.txt .
RUN pip install -r requirements.txt

# Step 4: Copy the rest of the app
COPY . .

# Step 5: Define the startup command
CMD ["python", "app.py"]

3. Essential Dockerfile Instructions

Instruction Description Example
FROM Base image (ubuntu, nginx, python) FROM ubuntu:20.04
WORKDIR Sets working directory WORKDIR /app
COPY Copies files from host to container COPY . /app
RUN Executes commands during build RUN apt-get update
CMD Default command when container starts CMD ["npm", "start"]
EXPOSE Declares which ports to expose EXPOSE 80
ENV Sets environment variables ENV DB_HOST=mysql
ARG Build-time variables ARG VERSION=1.0

4. Optimizing Dockerfile (Best Practices)

✔ Use .dockerignore

Prevents unnecessary files (like node_modules, .git) from being copied.

# .dockerignore
node_modules/
.git/
.env

✔ Order Instructions Properly

Docker caches layers, so structure commands from least to most frequently changed:

# Bad (Cache breaks if any file changes)
COPY . .
RUN pip install -r requirements.txt

# Good (Only reinstalls if requirements.txt changes)
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

✔ Use Smaller Base Images

  • Avoid ubuntu (heavy) → Use alpine, slim variants.
  • Example: python:3.9-slim instead of python:3.9.

✔ Combine RUN Commands

Reduces layers and image size.

# Bad (Creates multiple layers)
RUN apt-get update
RUN apt-get install -y curl

# Good (Single layer)
RUN apt-get update && apt-get install -y curl

5. Multi-Stage Builds

Reduces final image size by discarding build dependencies.

Example: Node.js App

# Stage 1: Build the app
FROM node:16 as builder
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
RUN npm run build

# Stage 2: Run the app (only keep production files)
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80

Before: 1.2GB
After: 50MB (only includes nginx and built files)


6. Real-World Dockerfile Examples

1. Python Flask App

FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]

2. Node.js + React App

FROM node:16 as build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80

3. MySQL Database

FROM mysql:8.0
ENV MYSQL_ROOT_PASSWORD=my-secret-pw
COPY init.sql /docker-entrypoint-initdb.d/
EXPOSE 3306

7. Conclusion

  • Dockerfile automates image creation → No manual setup.
  • Optimize with .dockerignore, multi-stage builds, and small base images.
  • Follow best practices for faster builds and smaller images.

Next Steps

  • Try building your own Dockerfile.
  • Learn Docker Compose for multi-container apps.

Got questions? Ask in the comments! 🚀

Happy Dockerizing! 🐳

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts