G
GuideDevOps
Lesson 5 of 13

Dockerfile Deep Dive

Part of the Docker tutorial series.

A Dockerfile is a simple text file that contains the instructions Docker uses to build an image. It automates the process of setting up your application environment.

1. Common Dockerfile Instructions

InstructionDescription
FROMSets the base image (usually an OS or runtime).
WORKDIRSets the working directory inside the container.
COPYCopies files from your host to the container.
RUNExecutes commands during the build process (e.g., apt install).
CMDThe command the container runs when it starts.
EXPOSEDocuments which port the application listens on.
ENVSets environment variables.

2. Example: Building a Python App

Let's create a Dockerfile for a simple web application.

Dockerfile:

# 1. Start from a lightweight Python image
FROM python:3.9-slim
 
# 2. Set the working directory
WORKDIR /app
 
# 3. Copy dependencies and install
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
 
# 4. Copy the application code
COPY . .
 
# 5. Expose the port the app runs on
EXPOSE 5000
 
# 6. Run the app
CMD ["python", "app.py"]

Build the Image

Action:

docker build -t my-python-app:v1 .

Result:

[+] Building 4.2s (10/10) FINISHED
 => [internal] load build definition from Dockerfile
 => [1/5] FROM docker.io/library/python:3.9-slim
 => [2/5] WORKDIR /app
 => [3/5] COPY requirements.txt .
 => [4/5] RUN pip install --no-cache-dir -r requirements.txt
 => [5/5] COPY . .
 => exporting to image
 => writing image sha256:a1b2c3d4e5f6...
 => naming to docker.io/library/my-python-app:v1

3. CMD vs ENTRYPOINT

This is a common source of confusion:

  • CMD: Sets a default command. If the user provides an argument to docker run, CMD is ignored.
  • ENTRYPOINT: Sets the main command. Arguments from docker run are appended to it. It cannot be easily overridden.

4. Best Practices for Dockerfiles

  1. Use .dockerignore: Exclude files like node_modules or .git to keep images small.
  2. Order Matters: Put instructions that change often (like COPY . .) at the bottom to leverage layer caching.
  3. Minimize Layers: Combine multiple RUN commands using && if possible.
  4. Use Specific Tags: Avoid latest. Use python:3.9-slim for predictable builds.

Summary

  • A Dockerfile is a recipe for an image.
  • Each instruction creates a new layer.
  • Caching makes builds fast—only rebuilt layers change.