Dockerfile

Dockerfile is a syntax for describing a container image. Several container toolchains are capable of compiling Dockerfile files, including Docker and Podman.


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...

  1. observe and respond to signals
  2. exit upon completion with a meaningful exit code
  3. log to stdout
  4. 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


Healthcheck


CategoryRicottone