This tutorial focuses on gaining hands-on experience with using ** Dockerfile ** on ** Alibaba Cloud **.
Dockerfile HEALTHCHECK This section describes how to use HEALTH CHECK in your Dockerfile.
HEALTHCHECK automatically checks the health of the container on the specified schedule.
HEALTHCHECK [OPTIONS] CMD command
The options displayed before CMD are:
--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--start-period=DURATION (default: 0s)
--retries=N (default: 3)
In this tutorial, these times are very long. I want to test it right away to see if the check works.
To add this to your Dockerfile
nano Dockerfile
FROM alpine:3.8
HEALTHCHECK --interval=3s --timeout=1s \
CMD curl -f http://localhost/ || exit 1
Important: Note that the curl -f http: // localhost / health check command always fails for this particular Alpine container.
To build the image
docker build --tag tutorial:demo --file Dockerfile .
Let's start the container and see the result.
docker stop -t 0 tutorial ; docker container prune -f
docker run -ti -d --name tutorial tutorial:demo /bin/sh -c 'while true; do sleep 60; done’
After the container starts, run docker ps -a repeatedly every second (10 seconds) to see the progress of the health check.
docker ps -a
Expected output.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27134771d5dd tutorial:demo "/bin/sh -c 'while t�" 3 seconds ago Up 1 second (health: starting)
After 10 seconds it will look like this:
docker ps -a
Expected output.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27134771d5dd tutorial:demo "/bin/sh -c 'while t�" 12 seconds ago Up 10 seconds (unhealthy) tutorial
(health: starting) is displayed for 10 seconds, but since the check is done every 3 seconds (--interval = 3s), --timeout = 1s is specified.
Let's reduce this interval to 1 second so that we can see our health results faster.
Also, try reducing the number of retries from the default of 3 to 1. --retries = 1
You will rarely use retries = 1 in a PROD environment. 3 is a much more realistic value.
To add this to your Dockerfile
nano Dockerfile
FROM alpine:3.8
HEALTHCHECK --interval=1s --timeout=1s --retries=1 \
CMD curl -f http://localhost/ || exit 1
Build the image using.
docker build --tag tutorial:demo --file Dockerfile .
Let's start the container and see the result.
docker stop -t 0 tutorial ; docker container prune -f
docker run -ti -d --name tutorial tutorial:demo /bin/sh -c 'while true; do sleep 60; done';docker ps -a; sleep .4; docker ps -a; sleep .4; docker ps -a; sleep .4; docker ps -a; sleep .4;
Notice that we check the status of the container every 0.4 seconds.
Expected output.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e83c476c2ee tutorial:demo "/bin/sh -c 'while t�" 1 second ago Up Less than a second (health: starting) tutorial
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e83c476c2ee tutorial:demo "/bin/sh -c 'while t�" 2 seconds ago Up Less than a second (health: starting) tutorial
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e83c476c2ee tutorial:demo "/bin/sh -c 'while t�" 2 seconds ago Up 1 second (unhealthy) tutorial
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e83c476c2ee tutorial:demo "/bin/sh -c 'while t�" 3 seconds ago Up 1 second (unhealthy) tutorial
For 0.8 seconds, your health is (Health: Start).
The status changes to (abnormal) after 1 second.
It's up to you, the administrator, to tweak these settings to suit your actual prod environment.
--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--start-period=DURATION (default: 0s)
--retries=N (default: 3)
As an administrator, you also have to determine the appropriate health check command in prod env. Web server containers, database containers, and hapxi containers all have different health check requirements.
I'm using it here for a quick view of how the state changes.
Let's run a sample of successful health checks to see what your health looks like.
To add this to your Dockerfile
nano Dockerfile
FROM alpine:3.8
HEALTHCHECK --interval=.1s --timeout=.4s --retries=1\
CMD sleep .1 || exit 1
Build the image using.
docker build --tag tutorial:demo --file Dockerfile .
Let's start the container and see the result.
docker stop -t 0 tutorial ; docker container prune -f
docker run -ti -d --name tutorial tutorial:demo /bin/sh -c 'while true; do sleep 60; done';docker ps -a; sleep .4; docker ps -a; sleep .4; docker ps -a; sleep .4; docker ps -a; sleep .4;
Expected output.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c83552f66511 tutorial:demo "/bin/sh -c 'while t�" 1 second ago Up Less than a second (health: starting) tutorial
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c83552f66511 tutorial:demo "/bin/sh -c 'while t�" 2 seconds ago Up Less than a second (healthy) tutorial
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c83552f66511 tutorial:demo "/bin/sh -c 'while t�" 2 seconds ago Up 1 second (healthy) tutorial
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c83552f66511 tutorial:demo "/bin/sh -c 'while t�" 3 seconds ago Up 2 seconds (healthy) tutorial
sleep .1 sleeps gracefully for a tenth of a second, after which it returns a status return code.
Unfortunately, the status filter of the docker ps -a command does not match containers by health. Only created, restarting, running, removing, paused, exited, dead can be filtered.
Unable to run: docker ps --filter status = healthy
Unable to run: docker ps --filter status = unhealthy
below docker ps -a | grep '(healthy)' And docker ps -a | grep '(unhealthy)' Must be used.
Dockerfile EXPOSE Ports In this section you will learn how Dockerfile exposes container ports using EXPOSE.
A container is an isolated execution process. The container must explicitly specify the ports that other containers can access.
A port is the official way a process can contact other processes to send commands.
For example, Apache port 80 is usually open. Apache is quarantined and hidden inside a container. The only way to get something done is to access it through port 80.
The EXPOSE instruction declares the port on which the container listens.
You can specify whether the port is TCP or UDP. If no protocol is specified, the default is TCP.
The EXPOSE instruction does not actually expose the port.
EXPOSE only serves as a document. This declares which port in the container is intended to be open to the public.
From https://docs.docker.com/engine/reference/builder/#expose
To actually expose ports when the container runs, use the -p flag in docker run to expose and map one or more ports, or use the -p flag to expose all exposed ports. Publish and map to higher-order ports.
By default, expose assumes TCP. You can also specify UDP.
EXPOSE 80/tcp
EXPOSE 80/UDP
This tutorial exposes ports 80, tcp and udp.
Edit the Dockerfile as follows.
nano Dockerfile
FROM alpine:3.8
EXPOSE 80/tcp
EXPOSE 80/udp
Build the image using.
docker build --tag tutorial:demo --file Dockerfile .
Let's start the container and see the result.
docker run -ti -d --name tutorial tutorial:demo /bin/sh -c 'while true; do sleep 60; done'
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6269a988e1dd tutorial:demo "/bin/sh -c 'while t�" 1 second ago Up Less than a second (health: starting) 80/tcp, 80/udp tutorial
The ports column shows the exposed ports, but they are not available. You have to publish them. Publish using the docker run command -p 30000: 80 / tcp.
-p 30000:80/tcp
30000 specifies the port number of the host. 80 / tcp specifies the port number of the container.
Let's create a container and see the result.
docker stop -t 0 tutorial; ; docker container prune -f
docker run -p 30000:80/tcp -ti -d --name tutorial tutorial:demo /bin/sh -c '\''while true; do sleep 60; done'\'''
Expected output.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b3e43916708 tutorial:demo "/bin/sh -c 'while t�" 1 second ago Up Less than a second 0.0.0.0:30000->80/tcp, 80/udp tutorial
0.0.0.0.0:30000->80/tcp
Port 30000 on localhost is mapped to port 80 on the container.
You can now see that port 30000 is open on the host.
The ss command is used to display information about sockets. The ss command is used to display socket information. (The netstat command no longer exists in the default installation of CentOS. Use the service command instead.)
ss -t -a -n
Short version, long version of options.
1, -t, --tcp only show TCP sockets. 2, -a, --all Show all sockets. 3, -n, --numeric do not resolve the service name, so the port number is displayed numerically.
Expected output
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
ESTAB 0 0 192.168.56.44:22 192.168.56.11:4118
ESTAB 0 64 192.168.56.44:22 192.168.56.11:2719
LISTEN 0 128 :::30000 :::*
LISTEN 0 128 :::22 :::*
You can see that port 30000 is listening on the host.
30000 has no special meaning. It's just used here as a port number that you can easily find.
Let's publish udp port 80 as well. Try running it.
docker stop -t 0 tutorial; ; docker container prune -f
docker run -p 40080:80/udp 30000:80/tcp -
Check if the publish was successful.
ss -u -a -n
Expected output
State Recv-Q Send-Q Local Address:Port Peer Address:Port
UNCONN 0 0 :::40080 :::*
This time I noticed that I was using the -u argument to display the udp port.
You can use environment variables to send values to a running container.
Environment variables are part of the environment in which the container runs. The syntax is as follows:
syntax: ENV
ENV =
The ENV instruction sets a value in an environment variable.
For example
ENV myVar1=1
ENV myVar42=42
ENV myAlfaVar=alfa value abc
Let's take a look at the env variable in env using our little Alpine Linux distro.
Create a Dockerfile with this content.
FROM alpine:3.8
ENV myVar1 1
ENV my42 42
ENV myVar42=42
ENV myAlfaVar='alfa abc'
Note that we use two methods for declaring env variables.
To build an image
docker build --tag tutorial:demo --file Dockerfile .
Execution:
docker stop -t 0 tutorial ; docker container prune -f
docker run -ti -d --name tutorial tutorial:demo /bin/sh -c 'while true; do sleep 60; done'
docker exec -it tutorial /bin/sh
Enter the printenv command at the # (prompt).
Expected output
/ # printenv
HOSTNAME=1314796592cf
SHLVL=1
HOME=/root
my42=42
TERM=xterm
myVar1=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
myAlfaVar=alfa abc
myVar42=42
PWD=/
/ # exit
All the declared env variables are there.
You can override the env variable when using docker run.
Execution:
docker stop -t 0 tutorial ; docker container prune -f
docker run -e 'my42=44000' -ti -d --name tutorial tutorial:demo /bin/sh -c 'while true; do sleep 60; done'
Now when you enter the container, you can see that my42 is 44000.
docker exec -it tutorial /bin/sh
Expected output
/ # printenv
HOSTNAME=1190753a779e
SHLVL=1
HOME=/root
my42=44000
TERM=xterm
myVar1=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
myAlfaVar=alfa abc
myVar42=42
PWD=/
You now have a hands-on experience of declaring ENV variables in your Dockerfile and overriding ENV variables with docker run -e'my-env-var-name = new value'.
You can also use printenv to inspect the contents of the env variable. (You can also use set or env to display the env variable at the shell prompt)
For more information https://en.wikipedia.org/wiki/Environment_variable
https://docs.docker.com/engine/reference/builder/#env
https://docs.docker.com/engine/reference/builder/#environment-replacement
This concludes Part 2 of 4: You can see the instructions for all Dockerfiles. For more information, please read Part 3 Please give me.
Recommended Posts