This content originally appeared on DEV Community and was authored by omkar shelke
Container Files and Dockerfiles: A Comprehensive Guide
A Dockerfile or Containerfile is a text-based document that contains a series of instructions to create a container image. Each instruction in the file builds a layer on top of the previous one, ultimately forming a complete container image that can be run on any system with Docker installed.
Instruction Formats: Shell and Exec Form
The RUN, CMD, and ENTRYPOINT instructions in a Dockerfile or Containerfile can be written in two forms: Shell and Exec form.
Exec Form
- Uses a JSON array syntax with double-quotes around each element.
- Example:
ENTRYPOINT ["/bin/bash", "-c", "echo hello"] - Avoids issues related to shell string parsing.
- Best used for
ENTRYPOINTinstructions, often combined withCMDto set default arguments.
Shell Form
- Uses a simple string syntax that is automatically interpreted by the command shell.
- Example:
RUN apt-get update - Emphasizes ease of use and readability.
Common Dockerfile Instructions
FROM
- Purpose: Sets the base image for the resulting container image.
-
Syntax:
FROM <image>:<tag> -
Example:
FROM ubuntu:latest - Explanation: This instruction initializes a new build stage and specifies the base image. All subsequent instructions will build on this base.
WORKDIR
- The WORKDIR instruction in a Dockerfile serves two main purposes:
- Create the Directory
- Set the Working Directory
- Create the Directory:
- If the directory specified by WORKDIR does not already exist, it will be created.
- Set the Working Directory:
- It sets the working directory for any subsequent RUN, CMD, ENTRYPOINT, COPY, and ADD instructions.
- All paths in these instructions will be relative to the WORKDIR unless absolute paths are specified.
-
Purpose: Sets the working directory for any
RUN,CMD,ENTRYPOINT,COPY, andADDinstructions that follow. -
Syntax:
WORKDIR /path/to/workdir -
Example:
WORKDIR /app -
Explanation: This instruction sets the working directory to
/app. Any subsequent instructions will operate within this directory.
COPY
- Purpose: Copies files or directories from the host system to the container filesystem.
-
Syntax:
COPY <src> <dest> -
Example:
COPY . /app -
Explanation: This instruction copies all files from the current directory on the host to the
/appdirectory in the container.
RUN
- Purpose: Executes commands to modify the image, creating a new layer on top of the current image.
-
Syntax:
- Shell form:
RUN <command> - Exec form:
RUN ["<command>", "<arg1>", "<arg2>"]
- Shell form:
-
Example:
RUN apt-get update RUN apt-get install -y curl Explanation: Each
RUNinstruction will execute the specified commands and create a new image layer.
ENTRYPOINT
- Purpose: Defines the command that will be executed when the container starts.
-
Syntax:
- Exec form:
ENTRYPOINT ["<executable>", "<param1>", "<param2>"] - Shell form:
ENTRYPOINT <command> <param1> <param2>
- Exec form:
-
Example:
ENTRYPOINT ["/app/start.sh"] -
Explanation: This instruction sets
/app/start.shas the main command that will run when the container starts.
CMD
- Purpose: Provides defaults for an executing container. These arguments can be overridden by user-supplied arguments when running the container.
-
Syntax:
- Exec form:
CMD ["<param1>", "<param2>"] - Shell form:
CMD <command> <param1> <param2>
- Exec form:
-
Example:
CMD ["--help"] -
Explanation: This instruction provides default arguments to the
ENTRYPOINTcommand.
USER
-
Purpose: Specifies the user to use when running the image and for any
RUN,CMD, andENTRYPOINTinstructions that follow. -
Syntax:
USER <username> -
Example:
USER appuser -
Explanation: This instruction changes the active user to
appuser, which enhances security by avoiding running as the root user.
LABEL
- Purpose: Adds metadata to the image as key-value pairs.
-
Syntax:
LABEL <key>=<value> -
Example:
LABEL version="1.0" description="My app" - Explanation: This instruction provides metadata that can help with identifying and managing the image.
EXPOSE
- Purpose: Informs Docker that the container listens on the specified network ports at runtime.
-
Syntax:
EXPOSE <port> -
Example:
EXPOSE 8080 - Explanation: This instruction is used for documentation purposes. It does not actually publish the port.
ENV
- Purpose: Sets environment variables.
-
Syntax:
ENV <key>=<value> -
Example:
ENV PATH="/app/bin:$PATH" -
Explanation: This instruction sets the environment variable
PATHto include/app/bin.
ARG
-
Purpose: Defines a variable that users can pass at build-time to the builder with the
docker buildcommand. -
Syntax:
ARG <name>[=<default_value>] -
Example:
ARG VERSION=1.0 -
Explanation: This instruction defines a build-time variable
VERSIONwith a default value of1.0.
VOLUME
- Purpose: Creates a mount point with the specified path and marks it as holding externally mounted volumes from native host or other containers.
-
Syntax:
VOLUME ["/path/to/dir"] -
Example:
VOLUME /data -
Explanation: This instruction defines
/dataas a location to store persistent data.
Practical Example
Here is a simple Dockerfile example to illustrate these instructions:
# Use the official Ubuntu base image
FROM ubuntu:20.04
# Set the working directory
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install curl
RUN apt-get update && apt-get install -y curl
# Set environment variables
ENV PATH="/app/bin:$PATH"
# Define a build argument
ARG VERSION=1.0
# Add metadata
LABEL version=$VERSION description="My Ubuntu-based app"
# Expose port 8080
EXPOSE 8080
# Define the default command to run
CMD ["--help"]
# Set the entrypoint
ENTRYPOINT ["/bin/bash", "-c"]
This Dockerfile sets up a simple Ubuntu-based container with a working directory, copies application files, installs necessary packages, sets environment variables and build arguments, adds metadata, exposes a port, and defines both ENTRYPOINT and CMD.
This content originally appeared on DEV Community and was authored by omkar shelke