Docker
Dockerfiles
Buscar..
Introducción
Los Dockerfiles son archivos que se utilizan para crear imágenes Docker mediante programación. Le permiten crear de forma rápida y reproducible una imagen de Docker, por lo que son útiles para colaborar. Dockerfiles contiene instrucciones para construir una imagen de Docker. Cada instrucción se escribe en una fila y se da en la forma <INSTRUCTION><argument(s)>
. Los Dockerfiles se utilizan para crear imágenes de Docker utilizando el comando de docker build
ventana docker build
.
Observaciones
Dockerfiles son de la forma:
# This is a comment
INSTRUCTION arguments
- Los comentarios comienzan con un
#
- Las instrucciones son solo mayúsculas
- La primera instrucción de un Dockerfile debe ser
FROM
para especificar la imagen base
Al crear un Dockerfile, el cliente Docker enviará un "contexto de compilación" al demonio Docker. El contexto de compilación incluye todos los archivos y carpetas en el mismo directorio que Dockerfile. COPY
operaciones COPY
y ADD
solo pueden usar archivos de este contexto.
Algunos archivos de Docker pueden comenzar con:
# escape=`
Esto se utiliza para indicar al analizador Docker que use `
como un carácter de escape en lugar de \
. Esto es principalmente útil para archivos de Windows Docker.
HelloWorld Dockerfile
Un Dockerfile mínimo se ve así:
FROM alpine
CMD ["echo", "Hello StackOverflow!"]
Esto le indicará a Docker que genere una imagen basada en Alpine ( FROM
), una distribución mínima para contenedores, y que ejecute un comando específico ( CMD
) al ejecutar la imagen resultante.
Constrúyelo y ejecútalo:
docker build -t hello .
docker run --rm hello
Esto dará como resultado:
Hello StackOverflow!
Copiando documentos
Para copiar archivos del contexto de compilación en una imagen de Docker, use la instrucción COPY
:
COPY localfile.txt containerfile.txt
Si el nombre del archivo contiene espacios, use la sintaxis alternativa:
COPY ["local file", "container file"]
El comando COPY
soporta comodines. Se puede usar, por ejemplo, para copiar todas las imágenes al directorio images/
:
COPY *.jpg images/
Nota: en este ejemplo, las images/
pueden no existir. En este caso, Docker lo creará automáticamente.
Exponiendo un puerto
Para declarar puertos expuestos desde un Dockerfile use la instrucción EXPOSE
:
EXPOSE 8080 8082
La configuración de puertos expuestos puede anularse desde la línea de comandos de Docker, pero es una buena práctica establecerlos explícitamente en el Dockerfile ya que ayuda a entender lo que hace una aplicación.
Dockerfiles mejores practicas
Operaciones comunes de grupo
Docker construye imágenes como una colección de capas. Cada capa solo puede agregar datos, incluso si estos datos indican que un archivo se ha eliminado. Cada instrucción crea una nueva capa. Por ejemplo:
RUN apt-get -qq update
RUN apt-get -qq install some-package
Tiene un par de inconvenientes:
- Creará dos capas, produciendo una imagen más grande.
- El uso de
apt-get update
solo en una instrucciónRUN
causa problemas de almacenamiento en caché y, posteriormenteapt-get install
instrucciones deapt-get install
pueden fallar . Supongamos que luego modificaapt-get install
agregando paquetes adicionales, la ventana acoplable interpreta las instrucciones iniciales y modificadas como idénticas y reutiliza el caché de los pasos anteriores. Como resultado, el comandoapt-get update
no se ejecuta porque su versión en caché se usa durante la compilación.
En su lugar, utilice:
RUN apt-get -qq update && \
apt-get -qq install some-package
Como esto solo produce una capa.
Mencionar al mantenedor
Esta suele ser la segunda línea del archivo Docker. Indica quién está a cargo y podrá ayudar.
LABEL maintainer John Doe <[email protected]>
Si lo saltas, no romperá tu imagen. Pero tampoco ayudará a tus usuarios.
Sé conciso
Mantenga su Dockerfile corto. Si es necesaria una configuración compleja, considere usar un script dedicado o configurar imágenes base.
Instrucción de usuario
USER daemon
La instrucción USER
establece el nombre de usuario o UID que se usará cuando se ejecute la imagen y para cualquier instrucción RUN
, CMD
y ENTRYPOINT
que la siga en el Dockerfile
.
Instrucciones de trabajo
WORKDIR /path/to/workdir
La instrucción WORKDIR
establece el directorio de trabajo para las instrucciones RUN
, CMD
, ENTRYPOINT
, COPY
y ADD
que lo siguen en el Dockerfile. Si el WORKDIR
no existe, se creará incluso si no se utiliza en ninguna instrucción de Dockerfile
posterior.
Se puede usar varias veces en un Dockerfile
. Si se proporciona una ruta relativa, será relativa a la ruta de la instrucción anterior WORKDIR
. Por ejemplo:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
La salida del comando pwd
final en este Dockerfile
sería /a/b/c
.
La instrucción WORKDIR
puede resolver las variables de entorno previamente establecidas utilizando ENV
. Solo puede usar variables de entorno establecidas explícitamente en el Dockerfile
. Por ejemplo:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
La salida del comando pwd
final en este Dockerfile sería /path/$DIRNAME
Instrucción de volumen
VOLUME ["/data"]
La instrucción VOLUME
crea un punto de montaje con el nombre especificado y lo marca como que contiene volúmenes montados externamente desde el host nativo u otros contenedores. El valor puede ser una matriz JSON, VOLUME ["/var/log/"]
, o una cadena simple con múltiples argumentos, como VOLUME /var/log
o VOLUME /var/log /var/db
. Para obtener más información / ejemplos e instrucciones de montaje a través del cliente Docker, consulte Compartir directorios a través de la documentación de Volumes.
El comando de docker run
inicializa el volumen recién creado con cualquier dato que exista en la ubicación especificada dentro de la imagen base. Por ejemplo, considere el siguiente fragmento de Dockerfile:
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
Este Dockerfile da como resultado una imagen que causa la ejecución de la ventana acoplable, para crear un nuevo punto de montaje en / myvol y copiar el archivo de saludo en el volumen recién creado.
Nota: Si algún paso de compilación cambia los datos dentro del volumen después de que se haya declarado, esos cambios se descartarán.
Nota: la lista se analiza como una matriz JSON, lo que significa que debe usar comillas dobles (“) alrededor de palabras no comillas simples (').
Instrucciones de copia
COPY
tiene dos formas:
COPY <src>... <dest>
COPY ["<src>",... "<dest>"] (this form is required for paths containing whitespace)
La instrucción COPY
copia los archivos o directorios nuevos desde <src>
y los agrega al sistema de archivos del contenedor en la ruta <dest>
.
Se pueden especificar varios recursos <src>
pero deben ser relativos al directorio de origen que se está construyendo (el contexto de la compilación).
Cada <src>
puede contener comodines y la coincidencia se realizará utilizando las reglas de la filepath.Match
de filepath.Match
de Go filepath.Match
. Por ejemplo:
COPY hom* /mydir/ # adds all files starting with "hom"
COPY hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
El <dest>
es una ruta absoluta, o una ruta relativa a WORKDIR
, en la que se copiará la fuente dentro del contenedor de destino.
COPY test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/ # adds "test" to /absoluteDir/
Todos los archivos y directorios nuevos se crean con un UID y GID de 0.
Nota: Si docker build - < somefile
utilizando stdin ( docker build - < somefile
), no hay un contexto de compilación, por lo que no se puede usar COPY
.
COPY
obedece las siguientes reglas:
La ruta
<src>
debe estar dentro del contexto de la compilación; no puedeCOPY
../algo / algo, porque el primer paso de una construcción de ventana acoplable es enviar el directorio de contexto (y los subdirectorios) al demonio de la ventana acoplable.Si
<src>
es un directorio, se copia todo el contenido del directorio, incluidos los metadatos del sistema de archivos. Nota: el directorio en sí no se copia, solo su contenido.Si
<src>
es cualquier otro tipo de archivo, se copia individualmente junto con sus metadatos. En este caso, si<dest>
finaliza con una barra inclinada /, se considerará un directorio y el contenido de<src>
se escribirá en<dest>/base(<src>)
.Si se especifican múltiples recursos
<src>
, ya sea directamente o debido al uso de un comodín, entonces<dest>
debe ser un directorio, y debe terminar con una barra oblicua/
.Si
<dest>
no finaliza con una barra diagonal, se considerará un archivo normal y el contenido de<src>
se escribirá en<dest>
.Si
<dest>
no existe, se crea junto con todos los directorios faltantes en su ruta.
Las instrucciones ENV y ARG
ENV
ENV <key> <value>
ENV <key>=<value> ...
La instrucción ENV
establece la variable de entorno <key>
al valor. Este valor estará en el entorno de todos los comandos de Dockerfile "descendientes" y se puede reemplazar en línea en muchos también.
La instrucción ENV
tiene dos formas. La primera forma, ENV <key> <value>
, establecerá una única variable en un valor. La cadena completa después del primer espacio se tratará como el <value>
, incluidos caracteres como espacios y comillas.
La segunda forma, ENV <key>=<value> ...
, permite configurar múltiples variables a la vez. Observe que la segunda forma usa el signo igual (=) en la sintaxis, mientras que la primera forma no lo hace. Al igual que el análisis de líneas de comando, se pueden usar comillas y barras invertidas para incluir espacios dentro de los valores.
Por ejemplo:
ENV myName="John Doe" myDog=Rex\ The\ Dog \
myCat=fluffy
y
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy
arrojará los mismos resultados netos en el contenedor final, pero se prefiere la primera forma porque produce una sola capa de caché.
Las variables de entorno establecidas con ENV
persistirán cuando se ejecute un contenedor desde la imagen resultante. Puede ver los valores usando la ventana acoplable inspeccionar, y cambiarlos usando la docker run --env <key>=<value>
.
ARG
Si no desea mantener la configuración, use ARG
lugar. ARG
establecerá entornos solo durante la construcción. Por ejemplo, la configuración
ENV DEBIAN_FRONTEND noninteractive
puede confundir a apt-get
usuarios de apt-get
en una imagen basada en Debian cuando entran al contenedor en un contexto interactivo a través de la docker exec -it the-container bash
.
En su lugar, utilice:
ARG DEBIAN_FRONTEND noninteractive
Alternativamente, también puede establecer un valor para un solo comando utilizando:
RUN <key>=<value> <command>
Exponer instrucción
EXPOSE <port> [<port>...]
La instrucción EXPOSE
informa a Docker que el contenedor escucha en los puertos de red especificados en tiempo de ejecución. EXPOSE
NO hace que los puertos del contenedor sean accesibles para el host. Para hacerlo, debe usar el indicador -p
para publicar un rango de puertos o el indicador -P
para publicar todos los puertos expuestos. Estos indicadores se utilizan en la docker run [OPTIONS] IMAGE [COMMAND][ARG...]
para exponer el puerto al host. Puede exponer un número de puerto y publicarlo externamente bajo otro número.
docker run -p 2500:80 <image name>
Este comando creará un contenedor con el nombre <image> y vinculará el puerto 80 del contenedor al puerto 2500 de la máquina host.
Para configurar la redirección de puertos en el sistema host, consulte el uso del indicador -P
. La función de red de Docker admite la creación de redes sin la necesidad de exponer puertos dentro de la red; para obtener información detallada, consulte la descripción general de esta función).
Etiqueta de instrucciones
LABEL <key>=<value> <key>=<value> <key>=<value> ...
La instrucción LABEL
agrega metadatos a una imagen. Una LABEL
es un par clave-valor. Para incluir espacios dentro de un valor de LABEL
, use comillas y barras invertidas como lo haría en el análisis de línea de comandos. Algunos ejemplos de uso:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
Una imagen puede tener más de una etiqueta. Para especificar múltiples etiquetas, Docker recomienda combinar etiquetas en una sola instrucción de LABEL
siempre que sea posible. Cada instrucción de LABEL
produce una nueva capa que puede resultar en una imagen ineficiente si usa muchas etiquetas. Este ejemplo da como resultado una capa de imagen única.
LABEL multi.label1="value1" multi.label2="value2" other="value3"
Lo anterior también se puede escribir como:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
Las etiquetas son aditivas, incluidas las LABEL
en las imágenes FROM
. Si Docker encuentra una etiqueta / clave que ya existe, el nuevo valor anula cualquier etiqueta anterior con claves idénticas.
Para ver las etiquetas de una imagen, use el comando de inspección de la ventana acoplable.
"Labels": {
"com.example.vendor": "ACME Incorporated"
"com.example.label-with-value": "foo",
"version": "1.0",
"description": "This text illustrates that label-values can span multiple lines.",
"multi.label1": "value1",
"multi.label2": "value2",
"other": "value3"
},
Instrucción CMD
La instrucción CMD
tiene tres formas:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
Solo puede haber una instrucción CMD
en un Dockerfile
. Si enumera más de un CMD
, solo el último CMD
tendrá efecto.
El propósito principal de un CMD
es proporcionar valores predeterminados para un contenedor en ejecución. Estos valores predeterminados pueden incluir un ejecutable, o pueden omitir el ejecutable, en cuyo caso debe especificar también una instrucción ENTRYPOINT
.
Nota: Si se utiliza CMD
para proporcionar argumentos predeterminados para la instrucción ENTRYPOINT
, tanto las instrucciones CMD
como ENTRYPOINT
deben especificarse con el formato de matriz JSON.
Nota: la forma ejecutiva se analiza como una matriz JSON, lo que significa que debe usar comillas dobles (“) alrededor de palabras, no comillas simples (').
Nota: A diferencia del formulario de shell, el formulario exec no invoca un shell de comando. Esto significa que el procesamiento de shell normal no ocurre. Por ejemplo, CMD [ "echo", "$HOME" ]
no realizará la sustitución de variables en $HOME
. Si desea el procesamiento de shell, use el formulario de shell o ejecute un shell directamente, por ejemplo: CMD [ "sh", "-c", "echo $HOME" ]
.
Cuando se utiliza en los formatos de shell o exec, la instrucción CMD
establece el comando que se ejecutará al ejecutar la imagen.
Si usa el formulario de shell de la CMD
, el comando se ejecutará en /bin/sh -c
:
FROM ubuntu
CMD echo "This is a test." | wc -
Si desea ejecutar su comando sin un shell, debe expresar el comando como una matriz JSON y dar la ruta completa al ejecutable. Esta forma de matriz es el formato preferido de CMD
. Cualquier parámetro adicional debe expresarse individualmente como cadenas en la matriz:
FROM ubuntu
CMD ["/usr/bin/wc","--help"]
Si desea que su contenedor ejecute el mismo ejecutable cada vez, debe considerar utilizar ENTRYPOINT
en combinación con CMD
. Ver ENTRYPOINT
.
Si el usuario especifica argumentos para la ejecución de la ventana acoplable, anulará el valor predeterminado especificado en CMD
.
Nota: no confundas RUN
con CMD
. RUN
realmente ejecuta un comando en el momento de crear la imagen y confirma el resultado; CMD
no ejecuta nada en el momento de la compilación, pero especifica el comando deseado para la imagen.
MAINTAINER Instrucción
MAINTAINER <name>
La instrucción MAINTAINER
le permite configurar el campo Autor de las imágenes generadas.
NO UTILICE LA DIRECTIVA DE MANTENIMIENTO
Según la documentación oficial de Docker, la instrucción MAINTAINER
está en desuso. En su lugar, se debe usar la instrucción LABEL
para definir el autor de las imágenes generadas. La instrucción LABEL
es más flexible, permite configurar metadatos y puede verse fácilmente con el comando docker inspect
.
LABEL maintainer="[email protected]"
De instrucción
FROM <image>
O
FROM <image>:<tag>
O
FROM <image>@<digest>
La instrucción FROM
establece la imagen base para instrucciones posteriores. Como tal, un archivo Docker válido debe tener FROM
como primera instrucción. La imagen puede ser cualquier imagen válida; es especialmente fácil comenzar por extraer una imagen de los repositorios públicos.
FROM
debe ser la primera instrucción sin comentarios en el Dockerfile.
FROM
puede aparecer varias veces dentro de un único archivo Docker para crear múltiples imágenes. Simplemente tome nota de la salida de la última ID de imagen por la confirmación antes de cada nuevo comando FROM
.
Los valores de etiqueta o compendio son opcionales. Si omite alguno de ellos, el constructor asume un último por defecto. El constructor devuelve un error si no puede coincidir con el valor de la etiqueta.
RUN Instrucción
RUN
tiene 2 formas:
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form)
La instrucción RUN
ejecutará cualquier comando en una nueva capa sobre la imagen actual y confirmará los resultados. La imagen confirmada resultante se utilizará para el siguiente paso en el Dockerfile
.
Las instrucciones RUN
capas y los compromisos de generación se ajustan a los conceptos centrales de Docker, donde los compromisos son baratos y se pueden crear contenedores desde cualquier punto en el historial de una imagen, al igual que el control de código fuente.
La forma exec hace que sea posible evitar munging cáscara de la secuencia, y para RUN
comandos usando una imagen de base que no contiene el ejecutable shell especificado.
El shell predeterminado para el formulario de shell se puede cambiar usando el comando SHELL
.
En el formulario de shell, puede usar una \
(barra invertida) para continuar una instrucción RUN
en la siguiente línea. Por ejemplo, considera estas dos líneas:
RUN /bin/bash -c 'source $HOME/.bashrc ;\
echo $HOME'
Juntos son equivalentes a esta sola línea:
RUN /bin/bash -c 'source $HOME/.bashrc ; echo $HOME'
Nota: Para usar un shell diferente, que no sea '/ bin / sh', use el formulario exec que pasa en el shell deseado. Por ejemplo, RUN ["/bin/bash", "-c", "echo hello"]
Nota: la forma ejecutiva se analiza como una matriz JSON, lo que significa que debe usar comillas dobles ( “
) alrededor de palabras, no comillas simples ( '
).
Nota: A diferencia del formulario de shell, el formulario exec no invoca un shell de comando. Esto significa que el procesamiento de shell normal no ocurre. Por ejemplo, RUN [ "echo", "$HOME" ]
no realizará la sustitución de variables en $HOME
. Si desea el procesamiento de shell, use el formulario de shell o ejecute un shell directamente, por ejemplo: RUN [ "sh", "-c", "echo $HOME" ]
.
Nota: En el formulario JSON, es necesario escapar de barras invertidas. Esto es particularmente relevante en Windows donde la barra diagonal inversa es el separador de ruta. De lo contrario, la siguiente línea se trataría como un formulario de shell debido a que no es JSON válido y fallará de una manera inesperada: RUN ["c:\windows\system32\tasklist.exe"]
La sintaxis correcta para este ejemplo es: RUN ["c:\\windows\\system32\\tasklist.exe"]
La memoria caché para las instrucciones RUN
no se invalida automáticamente durante la siguiente compilación. La memoria caché para una instrucción como RUN apt-get dist-upgrade -y
se reutilizará durante la siguiente compilación. La memoria caché para las instrucciones RUN
se puede invalidar mediante el uso del indicador --no-cache, por ejemplo, la compilación de docker --no-cache.
Consulte la guía de mejores prácticas de Dockerfile para obtener más información.
El caché para las instrucciones RUN
puede ser invalidado por las instrucciones ADD
. Vea a continuación para más detalles.
Instrucción ONBUILD
ONBUILD [INSTRUCTION]
La instrucción ONBUILD
agrega a la imagen una instrucción de activación que se ejecutará más adelante, cuando la imagen se use como base para otra construcción. El disparador se ejecutará en el contexto de la compilación descendente, como si se hubiera insertado inmediatamente después de la instrucción FROM
en el Dockerfile descendente.
Cualquier instrucción de construcción puede ser registrada como un disparador.
Esto es útil si está compilando una imagen que se usará como base para compilar otras imágenes, por ejemplo, un entorno de compilación de aplicaciones o un demonio que se puede personalizar con la configuración específica del usuario.
Por ejemplo, si su imagen es un generador de aplicaciones Python reutilizable, requerirá que se agregue el código fuente de la aplicación en un directorio en particular, y podría requerir que se llame un script de compilación después de eso. No puede simplemente llamar a ADD
y RUN
ahora, porque todavía no tiene acceso al código fuente de la aplicación, y será diferente para cada compilación de la aplicación. Simplemente puede proporcionar a los desarrolladores de aplicaciones un Dockerfile para copiar y pegar en su aplicación, pero eso es ineficiente, propenso a errores y difícil de actualizar porque se mezcla con el código específico de la aplicación.
La solución es usar ONBUILD
para registrar instrucciones avanzadas para ejecutar más tarde, durante la siguiente etapa de compilación.
Así es como funciona:
Cuando encuentra una instrucción ONBUILD
, el constructor agrega un disparador a los metadatos de la imagen que se está construyendo. La instrucción no afecta de otra manera la construcción actual.
Al final de la compilación, se almacena una lista de todos los desencadenantes en el manifiesto de la imagen, bajo la clave OnBuild. Se pueden inspeccionar con el comando de docker inspect
la docker inspect
. Más tarde, la imagen se puede usar como base para una nueva construcción, utilizando la instrucción FROM
. Como parte del procesamiento de la instrucción FROM
, el constructor descendente busca los activadores ONBUILD
y los ejecuta en el mismo orden en que se registraron. Si alguno de los disparadores falla, la instrucción FROM
se cancela, lo que a su vez hace que la compilación falle. Si todos los activadores tienen éxito, la instrucción FROM
completa y la compilación continúa como siempre.
Los disparadores se eliminan de la imagen final después de ejecutarse. En otras palabras, no son heredados por construcciones de "nietos".
Por ejemplo, podría agregar algo como esto:
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
Advertencia: no se permite el encadenamiento de instrucciones ONBUILD
utilizando ONBUILD
ONBUILD
.
Advertencia: la instrucción ONBUILD
no puede activar las instrucciones FROM
o MAINTAINER
.
Instrucción de STOPSIGNAL
STOPSIGNAL signal
La instrucción STOPSIGNAL
establece la señal de llamada del sistema que se enviará al contenedor para salir. Esta señal puede ser un número sin signo válido que coincida con una posición en la tabla syscall del kernel, por ejemplo 9, o un nombre de señal en el formato SIGNAME, por ejemplo SIGKILL.
Instrucción de SALUD
La instrucción HEALTHCHECK
tiene dos formas:
HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)
La instrucción HEALTHCHECK
le dice a Docker cómo probar un contenedor para verificar que aún funciona. Esto puede detectar casos como un servidor web que está atascado en un bucle infinito y no puede manejar nuevas conexiones, incluso aunque el proceso del servidor todavía se esté ejecutando.
Cuando un contenedor tiene un chequeo de salud especificado, tiene un estado de salud además de su estado normal. Este estado se está iniciando inicialmente. Cada vez que pasa un chequeo de salud, se vuelve saludable (sea cual sea el estado en el que se encontraba anteriormente). Después de un cierto número de fallas consecutivas, se vuelve insalubre.
Las opciones que pueden aparecer antes de CMD
son:
--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--retries=N (default: 3)
La comprobación de estado se ejecutará primero en intervalos de segundos después de que se inicie el contenedor, y luego nuevamente en intervalos de segundos después de que se complete cada verificación anterior.
Si una sola ejecución de la verificación lleva más tiempo que el tiempo de espera, se considera que la verificación ha fallado.
Es necesario volver a intentar las fallas consecutivas de la comprobación de estado para que el contenedor se considere insalubre.
Solo puede haber una instrucción HEALTHCHECK
en un Dockerfile
. Si enumera más de uno, solo tendrá efecto el último HEALTHCHECK
.
El comando después de la palabra clave CMD
puede ser un comando de shell (por ejemplo, HEALTHCHECK CMD /bin/check-running
) o una matriz exec (como con otros comandos de Dockerfile; consulte, por ejemplo, ENTRYPOINT
para obtener más información).
El estado de salida del comando indica el estado de salud del contenedor. Los valores posibles son:
-
0: success
- el envase está sano y listo para usar -
1: unhealthy
- el contenedor no funciona correctamente -
2: starting
: el contenedor aún no está listo para su uso, pero funciona correctamente
Si la sonda devuelve 2 ("inicio") cuando el contenedor ya se ha movido fuera del estado de "inicio", entonces se trata como "no saludable" en su lugar.
Por ejemplo, para comprobar cada cinco minutos aproximadamente, un servidor web puede servir la página principal del sitio en tres segundos:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
Para ayudar a depurar las sondas que fallan, cualquier texto de salida (codificado en UTF-8) que el comando escribe en stdout o stderr se almacenará en el estado de salud y se puede consultar con docker inspect
. Dicha salida debe mantenerse corta (solo se almacenan actualmente los primeros 4096 bytes).
Cuando cambia el estado de health_status
de un contenedor, se genera un evento health_status
con el nuevo estado.
La característica HEALTHCHECK
se agregó en Docker 1.12.
Instrucción SHELL
SHELL ["executable", "parameters"]
La instrucción SHELL
permite anular el shell predeterminado utilizado para la forma de shell de los comandos. El shell predeterminado en Linux es ["/bin/sh", "-c"]
, y en Windows es ["cmd", "/S", "/C"]
. La instrucción SHELL
debe estar escrita en forma JSON en un Dockerfile.
La instrucción SHELL
es particularmente útil en Windows donde hay dos shells nativos muy diferentes y de uso común: cmd y powershell, así como shells alternativos disponibles, incluyendo sh.
La instrucción SHELL
puede aparecer varias veces. Cada instrucción SHELL
anula todas las instrucciones anteriores de SHELL
y afecta a todas las instrucciones posteriores. Por ejemplo:
FROM windowsservercore
# Executed as cmd /S /C echo default
RUN echo default
# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default
# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello
# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello
Las siguientes instrucciones pueden verse afectadas por la instrucción SHELL
cuando su forma de shell se usa en un Dockerfile: RUN
, CMD
y ENTRYPOINT
.
El siguiente ejemplo es un patrón común que se encuentra en Windows que puede optimizarse utilizando la instrucción SHELL
:
...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...
El comando invocado por la ventana acoplable será:
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
Esto es ineficiente por dos razones. Primero, se invoca un procesador de comando cmd.exe innecesario (también conocido como shell). En segundo lugar, cada instrucción RUN
en el formulario de shell requiere un comando de PowerShell adicional que prefija el comando.
Para hacer esto más eficiente, uno de los dos mecanismos puede ser empleado. Una es usar la forma JSON del comando RUN
tal como:
...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...
Si bien el formulario JSON es inequívoco y no utiliza el cmd.exe innecesario, requiere más verbosidad a través de la doble cita y el escape. El mecanismo alternativo es usar la instrucción SHELL
y el formulario de shell, lo que crea una sintaxis más natural para los usuarios de Windows, especialmente cuando se combina con la directiva del analizador de escape:
# escape=`
FROM windowsservercore
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'
Resultando en:
PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 3.584 kB
Step 1 : FROM windowsservercore
---> 5bc36a335344
Step 2 : SHELL powershell -command
---> Running in 87d7a64c9751
---> 4327358436c1
Removing intermediate container 87d7a64c9751
Step 3 : RUN New-Item -ItemType Directory C:\Example
---> Running in 3e6ba16b8df9
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/2/2016 2:59 PM Example
---> 1f1dfdcec085
Removing intermediate container 3e6ba16b8df9
Step 4 : ADD Execute-MyCmdlet.ps1 c:\example\
---> 6770b4c17f29
Removing intermediate container b139e34291dc
Step 5 : RUN c:\example\Execute-MyCmdlet -sample 'hello world'
---> Running in abdcf50dfd1f
Hello from Execute-MyCmdlet.ps1 - passed hello world
---> ba0e25255fda
Removing intermediate container abdcf50dfd1f
Successfully built ba0e25255fda
PS E:\docker\build\shell>
La instrucción SHELL
también podría usarse para modificar la forma en que funciona un shell. Por ejemplo, al usar SHELL cmd /S /C /V:ON|OFF
en Windows, la semántica de expansión de la variable de entorno diferida podría modificarse.
La instrucción SHELL
también se puede usar en Linux en caso de que se requiera un shell alternativo como zsh, csh, tcsh y otros.
La característica SHELL
se agregó en Docker 1.12.
Instalación de paquetes Debian / Ubuntu
Ejecute la instalación en un solo comando de ejecución para fusionar la actualización e instalar. Si agrega más paquetes más tarde, esto ejecutará la actualización nuevamente e instalará todos los paquetes necesarios. Si la actualización se ejecuta por separado, se almacenará en caché y las instalaciones de paquetes pueden fallar. Configurar la interfaz para que no sea interactivo y pasar la opción -y para instalar es necesario para las instalaciones con script. La limpieza y purga al final de la instalación minimiza el tamaño de la capa.
FROM debian
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
openssh-client \
sudo \
vim \
wget \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*