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
- What is a Dockerfile?
- Basic Dockerfile Structure
- Essential Dockerfile Instructions
- Optimizing Dockerfile (Best Practices)
- Multi-Stage Builds
- Real-World Dockerfile Examples
- 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) → Usealpine,slimvariants. - Example:
python:3.9-sliminstead ofpython: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! 🐳
Projects to explore next
Source-code projects from the KritiMyantra catalogue. Check each project's details before buying.
Flask Authentication System (Free Version) - Kritim Yantra
🛠 Features✔ Google & GitHub Authentication✔ User Registration & Login✔ Profile/Dashboard Access✔ Secure & Mi...
Flask Blog CMS with Admin Dashboard — Python Source Code
A Flask-based blogging website with a built-in admin dashboard. Manage articles, images, categories, tags and featured p...
Laravel 12 + ReactJS Starter Kit: Add Multi-Language Support (Arabic, English, Spanish) with Blog CRUD
🚀 Installation & Setup Download & Extract Get the ZIP from kritimyantra.com and extract it. Includes preconfigu...
Comments
No comments yet. Be the first to comment.
Sign in to join the discussion.