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! 🐳

LIVE MENTORSHIP ONLY 5 SPOTS

Laravel Mastery
Coaching Class Program

KritiMyantra

Transform from beginner to Laravel expert with our personalized Coaching Class starting June 20, 2025. Limited enrollment ensures focused attention.

Daily Sessions

1-hour personalized coaching

Real Projects

Build portfolio applications

Best Practices

Industry-standard techniques

Career Support

Interview prep & job guidance

Total Investment
$200
Duration
30 hours
1h/day

Enrollment Closes In

Days
Hours
Minutes
Seconds
Spots Available 5 of 10 remaining
Next cohort starts:
June 20, 2025

Join the Program

Complete your application to secure your spot

Application Submitted!

Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.

What happens next?

  • Confirmation email with program details
  • WhatsApp message from our team
  • Onboarding call to discuss your goals

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts