docker Dockerfile - ghdrako/doc_snipets GitHub Wiki

FROM

FROM scratch #  create a new image with no parent image
FROM ubuntu
FROM <image> [AS <name>]
FROM <image>[:<tag>] [AS <name>]
FROM <image>[@<digest>] [AS <name>]

MAINTAINER

MAINTAINER user <[email protected]>

COPY

COPY copy files and directories from your local host to inside the container.

COPY test /newdir/tes

ADD

The ADD instruction is useful when you’re adding files from remote URLs or you have compressed files from the local filesystem that need to be automatically extracted into the container filesystem.

ADD

ADD http://www.mysite.com/file.tar.gz/code/source
ADD https://github.com/gohugoio/hugo/releases/download/v0.88.0/hugo_0.88.0_Linux-64bit.tar.gz /app/ # download compresed file from internet and place in docer in compresed form
ADD hugo_0.88.0_Linux-64bit.tar.gz /app/ # local compresed file is placed in docer uncompressed

CHOWN

ADD --chown=<user>:<group> <source> <destination>
COPY --chown=<user>:<group> <source> <destination>

Wildcard

ADD *.py /apps/
COPY *.py /apps/

Compare ADD COPY

Source COPY ADD
URL NO YES
extra features like local-only tar extraction NO YES
regular expression handling NO YES

To local files COPY is recommended

ENV

sets the environment variables in the container, for example, setting a log path other than the long one that the Docker engine sets by default.

ENV <key> <value>
ENV <key>=<value> ...
ENV log_dir /var/log
docker inspect sathyabhat/env | jq ".[0].Config.Env"

The environment variables defined for a container can be changed when running a container with the -e flag. In the previous example, change the LOGS_DIR value to /logs for a container. This is achieved by typing the following command:

docker run -it -e LOGS_DIR="/logs" sathyabhat/env
docker run -it -e LOGS_DIR="/logs" -e APPS_DIR="/opt" sathyabhat/env # assign multiple environment variables,

USER

By default, the Docker engine will set the container’s user to root, which can be harmful.You should set a user ID and username to your container.

USER 75 engy

WORKDIR

WORKDIR to set your active directory. The paths provided in multiple WORKDIR instructions will concatenate

WORKDIR /var
WORKDIR source    # /var/source
RUN apt-get update
FROM ubuntu:latest
WORKDIR /usr
WORKDIR src
WORKDIR app
CMD pwd

VOLUME

VOLUME instruction creates a directory in the image filesystem, which can later be used for mounting volumes from the Docker host or the other containers.

VOLUME vol

EXPOSE

This instruction is to make the container port accessible from the browser, outside the container, so that the world can send requests to the container services.

  • You can specify multiple ports in a single line.
  • By default, the Docker engine will assign TCP as your protocol.
  • Protocol TCP or UDP.
EXPOSE <port> [<port>/<protocol>...]
EXPOSE 53/tcp
EXPOSE 53/udp
EXPOSE 8081 80/udp # expose port 8081 as a TCP port and 80 as UDP

Note an EXPOSE instruction doesn’t publish the port. for the port to be published to the host, you need to use the -p flag with docker run to publish and map the ports.

docker run -d -p 8080:80 sathyabhat:web

RUN

Use to install any packages as a new layer inside the image during the build time.

RUN instruction will execute any command during the build step of the container. This creates a new layer that is available for the next steps in the Dockerfile.

RUN has two forms, the shell form and the exec form

  • shell form - This form makes it possible to use shell variables, subcommands, command pipes, and command chains in the RUN instruction itself.
RUN <command>
RUN echo `uname -rv` > $HOME/kernel-info
  • exec form
RUN ["executible", "parameter 1", " parameter 2"]

FROM ubuntu
RUN apt-get update && apt-get install curl

To reduce the number of layers, and to prevent packages not being able to be installed due to the package cache being out of date, it is best to chain the update and installs

RUN apt-get update && apt-get install -y \
pkg1 \
pkg2 \
pkg3 \
pkg4

LABEL

The LABEL instruction adds metadata to an image as a key-value pair.

LABEL <key>=<value> <key>=<value> <key>=<value> …

CMD

Add a health check to the CMD instruction - which tells the Docker engine to kill the container with exit status 1 if the container health fails

HEALTHCHECK CMD curl --fail http://localhost/health ||exit 1

The CMD syntax uses this form [“param”, param”, “param”] when used in conjunction with the ENTRYPOINT instruction. It should be in the following form CMD [“executable”, "param1”, “param2”…] if used by itself.

CMD "echo" "Hello World!"
CMD ["executable","param1","param2"] # exec form
CMD ["param1","param2"] # as default parameters to ENTRYPOINT
CMD command param1 param2 # shell form

Difference CMD RUN

CMD RUN
CMD is executed when you run a container from your image RUN instruction is executed during the build time of the image
You can have only one CMD instruction in a Dockerfile. If you add more, only the last one takes effect. Other are ignored. you can have as many RUN instructions as you need in the same Dockerfile

ENTRYPOINT

We will use the ENTRYPOINT key to define the main process the container will run. If this key isn’t defined, the /bin/sh shell will be used for Linux containers and cmd.exe for Microsoft Windows containers. This key can come already modified in our base images, with a custom value, but we can also override it in our Dockerfile declaration to modify our container’s behavior.

You can also use the CMD key, which allows you to specify which arguments should be passed to the shell, Windows command, or any other defined ENTRYPOINT. As such, we can think of the main process execution as the concatenation or sum of the ENTRYPOINT and CMD keys.

Every Docker container has a default ENTRYPOINT/bin/sh -c. Anything you add to CMD is appended post ENTRYPOINT and executed; for example, CMD ["nginx", "-g", "daemon off;"] will be generated as /bin/sh -c nginx -g daemon off;. Now, if you use a custom ENTRYPOINT instead, the commands you use while launching the container will be appended post it. So, if you define ENTRYPOINT ["nginx", "-g"] and use docker run nginx daemon off;, you will get a similar result.

To get a similar behavior without adding any CMD arguments while launching the container, you can also use ENTRYPOINT ["nginx", "-g", "daemon off;"].

Tip Use ENTRYPOINT unless there is a need for a specific CMD requirement. Using ENTRYPOINT ensures that users cannot change the default behavior of your container, so it's a more secure alternative.

The CMD and ENTRYPOINT instructions define which command is executed when running a container.

To instantly run an executable command when a container is crafted from an image, use the ENTRYPOINT instruction.

ENTRYPOINT ["executable", "param1", "param2"] # exec form
ENTRYPOINT command param1 param2 # shell form

ENTRYPOINT overrides the CMD instruction, and CMD’s parameters are used as arguments to ENTRYPOINT.

CMD "This is my container"
ENTRYPOINT echo

When you run a container from this image, the Docker engine will execute it as ENTRYPOINT echo "This is my container" and will print This is my container

The ENTRYPOINT instruction is best when you want your container to function like an executable, and the CMD instruction provides the defaults for an executing container.

HEALTHCHECK

To ensure that our main process runs correctly within our container, we should add a health probe that will indicate whether this process is healthy or not.

we can use the HEALTHCHECK key to define a command line that will check our main application’s health. We can use a script or binary with arguments, such as curl for web servers, or a database client if we run a database server. What is very important for health checks is that the command exits correctly (exit 0) if the application is healthy. If our check process exits with any other signal, the container will die as a result of the application being set as unhealthy. The HEALTHCHECK key will allow us to manage how the checks must be executed, to keep the application up and running. We can modify the number of checks that will mark the main process as unhealthy and the interval for these checks. When the defined number of tries is reached with a negative response (any exit different than 0), the container runtime is informed that even if the main process seems to be running correctly, the service is not working, and the container should die. This usually means a new healthy one is created, but for this process to work, we should configure that container with the restart: always option.

There are two different ways to configure the HEALTHCHECK in docker. They are:

HEALTHCHECK [OPTIONS] CMD command

which will execute the specified command to check the status of the application in the container.

Or the other option:

HEALTHCHECK NONE

Example

HEALTHCHECK CMD curl --fail http://localhost:3000 || exit 1

The curl command checks whether the application is running or not making a request to localhost:3000. If the request returns a 200, it will return exit code 0; if the application crashes, it will return exit code 1. These exit codes are how Docker's HEALTHCHECK determines the health of the container. Based on that, we can check the status of the application in the container.

There are a few options that we can use to customize our HEALTHCHECK instruction:

  • interval - DURATION (default: 30s) - time between the health check for the application container. it waits for the specified time from one check to another.
  • timeout - DURATION (default: 30s) - time that the health check waits for a response to consider the status of the container
  • start-period - DURATION (default: 0s) - number of seconds the container needs to start; health check will wait for that time to start.
  • retries - DURATION (default: 3) - number of consecutive health check failures required to declare the container status as unhealthy
FROM nginx
COPY index.html /usr/share/nginx/html/index.html
HEALTHCHECK CMD curl --fail http://localhost:80
FROM nginx:1.13
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost/ || exit 1
EXPOSE 80
⚠️ **GitHub.com Fallback** ⚠️