This Dockerfile Cheat Sheet serves as a practical reference, detailing essential Dockerfile commands and best practices for creating, running, and managing Docker containers effectively. It covers everything from basic commands, file handling, and environment configuration to advanced features like multi-stage builds and health checks. Designed to be a go-to resource, it provides developers of all skill levels with the tools needed to build, deploy, and troubleshoot Docker containers, supplemented by links to further learning resources and community forums for ongoing support.
Basic Commands
FROM
- Purpose: Sets the base image for subsequent instructions. Every Dockerfile must start with a
FROM
command, except in the case of multi-stage builds. - Usage:
FROM <image>:<tag>
- Example:
FROM ubuntu:20.04
RUN
- Purpose: Executes commands in a new layer on top of the current image and commits the results.
- Usage:
RUN <command>
- Example:
RUN apt-get update && apt-get install -y python3
CMD
- Purpose: Provides defaults for executing a container. There can only be one
CMD
instruction in a Dockerfile. - Usage:
CMD ["executable","param1","param2"]
- Example:
CMD ["echo", "Hello World"]
LABEL
- Purpose: Adds metadata to an image such as version, description, or maintainer.
- Usage:
LABEL <key>=<value> <key>=<value> ...
- Example:
LABEL version="1.0" description="This is an example."
EXPOSE
- Purpose: Informs Docker that the container listens on the specified network ports at runtime. It is purely informational and does not actually publish the port.
- Usage:
EXPOSE <port>
- Example:
EXPOSE 80
ENV
- Purpose: Sets environment variables.
- Usage:
ENV <key>=<value>
- Example:
ENV MY_NAME="John Doe"
Working with Files
COPY
- Purpose: Copies new files or directories from the source location on the host into the filesystem of the container at the specified path.
- Usage:
COPY [--chown=<user>:<group>] <src>... <dest>
- Example:
COPY . /app
- Notes: The
COPY
command only takes local files in the build context or files in stages in multi-stage builds.
ADD
- Purpose: Similar to
COPY
, but with the ability to handle remote URLs and automatically decompress compressed files. - Usage:
ADD [--chown=<user>:<group>] <src>... <dest>
- Example:
ADD https://example.com/example.tar.gz /var/www/html/
- Notes: Use
ADD
for remote resources and archives. For all other copying,COPY
is recommended as it is more transparent.
WORKDIR
- Purpose: Sets the working directory for any
RUN
,CMD
,ENTRYPOINT
,COPY
, andADD
instructions that follow in the Dockerfile. - Usage:
WORKDIR /path/to/workdir
- Example:
WORKDIR /app
- Notes: If the
WORKDIR
does not exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.
Managing Dependencies and Packages
Using RUN for Installation
- Purpose: Installs packages using the package manager available in the image.
- Common Usage:
- For Debian/Ubuntu-based containers:
RUN apt-get update && apt-get install -y package-name
- For Red Hat/CentOS-based containers:
RUN yum install -y package-name
- For Alpine-based containers:
RUN apk add --update package-name
- For Debian/Ubuntu-based containers:
- Example:
RUN apt-get update && apt-get install -y curl
Cleaning Up
- Purpose: Reduces the image size by cleaning up unnecessary files and cache.
- Usage:
RUN apt-get install -y package-name \ && rm -rf /var/lib/apt/lists/*
- Example:
RUN apt-get update && apt-get install -y \ git \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
Minimizing Layer Count
- Purpose: Consolidates RUN commands to reduce the number of layers, thus improving the build process and reducing the image size.
- Best Practice:
- Chain commands using
&&
. - Avoid unnecessary layers by combining related tasks into a single
RUN
statement.
- Chain commands using
- Example:
RUN apt-get update && apt-get install -y \ curl \ git \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
Using Build Arguments (ARG)
- Purpose: Allows you to pass variables during the build stage, which can be used to customize the installation of packages.
- Usage:
ARG VERSION=latest RUN apt-get install -y package-name=${VERSION}
- Example:
ARG PHP_VERSION=7.4 RUN apt-get update && apt-get install -y \ php${PHP_VERSION}
Running Commands and Processes
CMD
- Purpose: Specifies the default command to run when a container starts. Only the last
CMD
instruction in a Dockerfile will take effect. - Usage:
CMD ["executable","param1","param2"] # exec form, preferred CMD command param1 param2 # shell form
- Examples:
CMD ["echo", "Hello world"] # Using exec form CMD echo Hello world # Using shell form
- Notes: If
CMD
is used to provide default command-line arguments forENTRYPOINT
, both should be specified in the JSON array format.
ENTRYPOINT
- Purpose: Configures a container to run as an executable. Any
CMD
instructions become default parameters and can be overridden from the command line when the container starts. - Usage:
ENTRYPOINT ["executable", "param1", "param2"] # exec form, preferred ENTRYPOINT command param1 param2 # shell form
- Examples:
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"] ENTRYPOINT exec top -b
- Notes: Using the exec form ensures that the executable receives signals intended for it, unlike the shell form where the signal is received by the shell process.
CMD vs ENTRYPOINT
- Comparison: While
CMD
can be seen as a way to define default execution commands and arguments,ENTRYPOINT
establishes a container with a specific service in mind, allowing the user to append only new arguments and not overwrite the entire command. - Best Practice:
- Use
ENTRYPOINT
for setting the container's main application. - Reserve
CMD
for default arguments and running additional setups before the main process begins.
- Use
Combining CMD and ENTRYPOINT
- Purpose: To allow the docker container to be run both as an executable and to allow flexibility with the arguments passed.
- Example:
ENTRYPOINT ["executable", "param1"] CMD ["param2", "param3"]
- Explanation: In this configuration,
param1
is a fixed part of the command, whileparam2
andparam3
can be overridden when running the container.
Volumes and Data Management
VOLUME
- Purpose: Creates a mount point with the specified name and marks it as holding externally mounted volumes from the native host or other containers. It’s often used to preserve data across container updates and restarts.
- Usage:
VOLUME ["/data"]
- Example:
VOLUME /var/log /var/db
- Notes:
VOLUME
can be used to enable access to Docker data from outside the Docker container and to share data between containers.- When a volume is declared, any changes made to that volume will be made directly on the host machine and will persist even after the container is deleted.
Best Practices for Data Management
- Decouple applications from storage: Store data (such as database files) on volume containers or mount host directories as volumes.
- Read-only volumes: For added security, specify volumes as read-only when sensitive data must not be modified by the container.
- Example:
VOLUME ["/data:ro"]
- Temporary file storage: Consider using volumes for temporary file storage to avoid filling up the container writable layer and causing performance degradation.
Managing Data in Docker
- Backup, restore, and migrate data volumes: To handle data effectively, you can use Docker commands to backup, restore, or migrate volumes from one container to another.
- Example Commands:
- Backup:
docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
- Restore:
docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu tar xvf /backup/backup.tar
- Backup:
- Notes:
- Ensure that operations on data volumes do not interrupt running services unless necessary.
Network Configuration
EXPOSE
- Purpose: Informs Docker that the container listens on the specified network ports at runtime. This is a declaration and does not actually publish the port.
- Usage:
EXPOSE <port> [<port>/<protocol>...]
- Example:
EXPOSE 80/tcp EXPOSE 443
- Notes:
EXPOSE
does not make the ports of the container accessible to the host. To do this, you need to run the container with the-p
flag.- This instruction is useful for building images that are meant to intercommunicate or are intended to be run in linked containers.
Setting Default Network Settings
- Purpose: Customize network settings such as network mode, enabling IPv6, or using user-defined bridge networks.
- Usage:
- When running containers, use Docker run commands to specify networking configurations:
docker run --network=host --name container_name image_name
- When running containers, use Docker run commands to specify networking configurations:
- Example:
docker run -d --network=my-network --name my-app my-image
- Notes:
- Common network modes include
bridge
,host
,none
, and user-defined networks. --network=host
uses the host’s networking stack, and not isolated networking for the container.
- Common network modes include
Linking Containers
- Purpose: Allows containers to communicate with each other without using port mappings, using a private internal network.
- Usage:
- Link two containers:
docker run --link <name or id>:alias
- Link two containers:
- Example:
docker run --name database --detach some-database docker run --detach --name app --link database:db my-app-image
- Notes:
- Linking is a legacy feature and might be removed in future Docker versions. It’s recommended to use user-defined networks to facilitate communication between containers.
Best Practices
Minimize the Number of Layers
- Purpose: Reduce image size and build complexity by minimizing the number of layers.
- Practice: Combine related commands into a single
RUN
statement where possible, and use multi-stage builds to separate parts of the build process that aren't needed in the final image. - Example:
RUN apt-get update && apt-get install -y \ git \ curl \ && rm -rf /var/lib/apt/lists/*
Use .dockerignore
- Purpose: Speed up the build process by excluding files and directories that aren't necessary for building the Docker image.
- Practice: Create a
.dockerignore
file in the root of your context directory to exclude files like temporary files, logs, and local configuration files. - Example:
.git node_modules tmp/
Leverage Build Cache
- Purpose: Make builds faster by reusing previously cached layers.
- Practice: Structure Dockerfile instructions to maximize cache utilization. For instance, if you're copying files and then running package installations, copy only the files needed for the installation first, perform the installation, then copy the rest of the files.
- Example:
COPY package.json /app/ RUN npm install COPY . /app
Use Specific Base Images
- Purpose: Enhance security and reduce image sizes by using specific, possibly slimmed-down base images.
- Practice: Instead of using generic and large base images like
ubuntu
, use more specific versions likeubuntu:20.04
or even better,ubuntu:20.04-slim
. - Example:
FROM node:14-alpine
Avoid Running as Root
- Purpose: Improve security by limiting the privileges of container processes.
- Practice: Use the
USER
instruction to switch to a non-root user after installing necessary software. - Example:
RUN adduser -D myuser USER myuser
Secure Secrets Management
- Purpose: Protect sensitive information such as passwords and API keys.
- Practice: Avoid hardcoding secrets in Dockerfiles. Use environment variables, Docker secrets, or third-party secrets management tools.
- Example:
ENV API_KEY_ENV_VAR_NAME
Advanced Features
Multi-stage Builds
- Purpose: Simplify the creation of lightweight and secure images by separating build environments from runtime environments.
-
Usage:
# Build stage FROM golang:1.16 as builder WORKDIR /go/src/app COPY . . RUN go build -o /my-app # Final stage FROM alpine:latest COPY --from=builder /my-app /my-app CMD ["/my-app"]
-
Example:
FROM node:12 as builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html
- Notes: This method is particularly useful for languages and frameworks like Go, Java, or Node.js where building the application requires a different set of dependencies than running it.
Using ONBUILD
- Purpose: Adds a trigger instruction that will be executed at a later time, when the image is used as the base for another build.
- Usage:
ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src
- Example:
FROM python:3.7 ONBUILD COPY requirements.txt /app/ ONBUILD RUN pip install --no-cache-dir -r /app/requirements.txt
- Notes:
ONBUILD
is useful for images that are going to be the base of another build, like frameworks or development environments, ensuring that any derived image automatically includes certain necessary instructions.
Health Checks
- Purpose: Allows you to configure the Docker container to periodically check the health of a process or application running within it.
- Usage:
HEALTHCHECK --interval=5m --timeout=3s \ CMD curl -f http://localhost/ || exit 1
- Example:
HEALTHCHECK CMD curl --fail http://localhost:8080/health || exit 1
- Notes: Health checks can help identify containers that are running but not actually functional. Docker can restart them automatically depending on the configured restart policy.
Troubleshooting and Debugging
Common Issues and Solutions
-
Docker build failures:
- Symptoms: Build stops with an error message.
- Common Causes: Syntax errors in Dockerfile, missing files in context, permissions issues.
- Solution:
- Check Dockerfile syntax and ensure all referenced files are available in the build context.
- Ensure that file permissions allow Docker to access necessary files.
-
Container won't start:
- Symptoms: Container exits immediately after start or fails to start.
- Common Causes: Misconfiguration in
CMD
orENTRYPOINT
, necessary services not started. - Solution:
- Use
docker logs container_name
to check the logs for error messages. - Verify that
CMD
andENTRYPOINT
scripts are executable and correctly formatted.
Using Docker Logging
- Purpose: Logs provide insights into what happens when a container runs.
- Usage:
docker logs [container_id or name]
- Example:
docker logs my-running-app
- Notes:
- Checking logs is often the first step in troubleshooting container issues, as they can reveal errors and other runtime information.
Monitoring Tools
- Purpose: Monitoring tools help track container performance and health.
- Common Tools:
- Docker Stats: Provides a live stream of container resource usage statistics.
docker stats
- Portainer: A GUI for managing Docker environments.
- cAdvisor: Google's container advisor that provides container users an understanding of the resource usage and performance characteristics of their running containers.
- Docker Stats: Provides a live stream of container resource usage statistics.
Debugging Best Practices
- Reproducibility: Ensure that the error can be consistently reproduced to accurately diagnose the issue.
- Isolation: Isolate the problematic part of your Dockerfile or container configuration to identify the specific cause.
- Incremental Changes: Make one change at a time to your Dockerfile or container configuration to see what affects the behavior.
Resources
Official Docker Documentation
- Purpose: Provides comprehensive and authoritative details on all aspects of Docker.
- Link:
Recommended Books
- Docker Deep Dive by Nigel Poulton
- Overview: This book is great for both beginners and seasoned users. It covers fundamental concepts to advanced topics in Docker.
- Docker Up & Running by Sean Kane and Karl Matthias
- Overview: Explores practical use cases and best practices for deploying Docker containers at scale.
Online Courses
- Docker Mastery: with Kubernetes +Swarm from a Docker Captain on Udemy
- Overview: A comprehensive course that not only covers Docker but also includes Kubernetes and Swarm, making it ideal for those looking to expand beyond basic Docker usage.
- Introduction to Docker on Coursera
- Overview: Focuses on the basics and is offered by Duke University, making it a solid foundation course.
Video Tutorials
- Docker Official YouTube Channel
- Link:
- Docker YouTube Channel
- Content: Offers a range of tutorials, talks, and demos to help you understand Docker from the ground up.
Community and Forums
- Docker Community Slack
- Link:
- Join Docker Slack
- Purpose: Connect with Docker experts and enthusiasts around the world to share knowledge and solve problems.
- Stack Overflow
- Tag:
- Docker Questions on Stack Overflow
- Purpose: A great place to find solutions to specific problems and engage with an active community of developers.