Dockerfile
Dockerfile is a syntax for describing a container image. Several container toolchains are capable of compiling Dockerfile files, including Docker and Podman.
Contents
Example
# Setup FROM alpine:latest RUN apk update RUN apk add postgres14 # Data persistence VOLUME /var/lib/postgresql/data # Configuration COPY local/path/to/postgresql.conf /etc/postgresql/postgresql.conf # The containerized process USER postgres CMD ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]
From
Label
The LABEL command is used for image metadata.
LABEL version="1.0" LABEL description="This text illustrates \ that label-values can span multiple lines."
Arg and Env
Run and Shell
Shell
The SHELL command overrides how RUN commands are handled. The default shell is ["/bin/sh", "-c"] on Linux and ["cmd", "/S", "/C"] on Windows.
Add
Copy
Copy from
COPY has a --from=CONTAINER option.
In a multi-stage build, files and binaries are copied from a build container into the production container. This keeps the statically-compiled dependencies outside of the production image.
FROM golang:latest AS builder WORKDIR /app COPY * ./ RUN go mod download RUN go build -o /my-binary-name FROM alpine:latest WORKDIR / COPY --from=builder /my-binary-name /my-binary-name EXPOSE 8080 ENTRYPOINT ["/my-binary-name"]
Volume
User
Workdir
Cmd
The CMD command is used to define the default process for an image. There can only be one CMD command in a Dockerfile.
Some best practices follow.
Run without a shell
If the command is a string, it is processed by a shell just like a RUN command.
If the command is a JSON array, it is executed directly. This is always preferable.
Run in foreground
Container images are designed to run singular services, and accordingly expect services to behave like userspace utilities. These expectations include...
- observe and respond to signals
- exit upon completion with a meaningful exit code
- log to stdout
- print errors to stderr
Most services can be run in the foreground, as init systems prefer to handle forking internally. Some can even be configured to use stdout and sterr correctly.
For services that cannot be made to fit this model, consider using a supervisor.
Use a supervisor
Supervisord is a minimal init system for use in containers. Consider the below Dockerfile:
FROM alpine:latest RUN apk add supervisord USER root CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
The container's main process will be supervisord(1), and the services will instead be managed by that process.
Entrypoint
The ENTRYPOINT command is very similar to CMD, and in many cases they can be used interchangeably.
Entrypoint and Cmd
If ENTRYPOINT and CMD are used in the same Dockerfile, then ENTRYPOINT acts as the default program while CMD acts as the default argument.
FROM alpine:latest ENTRYPOINT ["/bin/ping","-c","3"] CMD ["localhost"]
Expose