Dockerfile Best Practices
This guide will walk you through the best practices for writing Dockerfiles, including sections, declaring environment variables, using ENTRYPOINT vs CMD, multi-stage builds, and creating lean images.
Step 1: Dockerfile Sections
A typical Dockerfile consists of the following sections:
- FROM: Specifies the base image.
- MAINTAINER: (Deprecated) Specifies the author of the Dockerfile.
- RUN: Executes commands in a new layer on top of the current image.
- COPY or ADD: Copies files/directories into the image.
- WORKDIR: Sets the working directory for subsequent instructions.
- ENV: Sets environment variables.
- EXPOSE: Informs Docker that the container listens on the specified network ports.
- CMD: Provides defaults for an executing container.
- ENTRYPOINT: Configures a container that will run as an executable.
Step 2: Declaring Environment Variables
To declare environment variables in a Dockerfile, use the ENV instruction:
ENV APP_ENV=production
ENV APP_PORT=8080Step 3: ENTRYPOINT vs CMD
- ENTRYPOINT: Sets the command and parameters that will be executed when a container starts. It is used to define the main command.
- CMD: Provides default arguments for the
ENTRYPOINTcommand or sets the command to be executed ifENTRYPOINTis not specified.
Use ENTRYPOINT when you want to define a container with a specific executable. Use CMD to provide defaults that can be overridden from the command line.
Example:
ENTRYPOINT ["python", "app.py"]
CMD ["--help"]Step 4: Multi-Stage Builds
Multi-stage builds help in creating lean images by allowing you to use multiple FROM statements in a single Dockerfile. This is useful for separating the build environment from the runtime environment.
Example:
# Stage 1: Build
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# Stage 2: Runtime
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]Step 5: Creating Lean Images
To create lean images, follow these best practices:
- Use a minimal base image like
alpine. - Remove unnecessary files and dependencies.
- Use multi-stage builds to separate build and runtime environments.
- Combine multiple
RUNinstructions into a single instruction to reduce the number of layers.
Example:
FROM alpine:latest
RUN apk add --no-cache python3
COPY . /app
WORKDIR /app
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python3", "app.py"]Conclusion
You have successfully learned about Dockerfile sections, declaring environment variables, using ENTRYPOINT vs CMD, multi-stage builds, and creating lean images. Following these best practices will help you write efficient and maintainable Dockerfiles.