Compartir comentarios
Las respuestas se generan en base a la documentación.

docker container run

DescripciónCrea y ejecuta un nuevo contenedor a partir de una imagen
Usodocker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
Alias
docker run

Descripción

El comando docker run ejecuta un comando en un nuevo contenedor, descargando (pull) la imagen si es necesario e iniciando el contenedor.

Puedes reiniciar un contenedor detenido con todos sus cambios anteriores intactos usando docker start. Usa docker ps -a para ver una lista de todos los contenedores, incluidos los que están detenidos.

Opciones

OpciónPredeterminadoDescripción
--add-hostAñade una asignación personalizada de host a IP (host:ip)
--annotationAPI 1.43+ Añade una anotación al contenedor (se pasa al entorno de ejecución OCI)
-a, --attachSe asocia a STDIN, STDOUT o STDERR
--blkio-weightE/S de bloque (peso relativo), entre 10 y 1000, o 0 para desactivar (por defecto 0)
--blkio-weight-devicePeso de E/S de bloque (peso relativo del dispositivo)
--cap-addAñade capacidades de Linux
--cap-dropDescarta capacidades de Linux
--cgroup-parentCgroup primario opcional para el contenedor
--cgroupnsAPI 1.41+ Espacio de nombres cgroup a utilizar (host|private)
'host': Ejecuta el contenedor en el espacio de nombres cgroup del host Docker
'private': Ejecuta el contenedor en su propio espacio de nombres cgroup privado
'': Utiliza el espacio de nombres cgroup configurado por la
opción default-cgroupns-mode en el demonio (por defecto)
--cidfileEscribe el ID del contenedor en el archivo
--cpu-countCantidad de CPU (solo Windows)
--cpu-percentPorcentaje de CPU (solo Windows)
--cpu-periodLimita el período del programador completamente justo (CFS) de la CPU
--cpu-quotaLimita la cuota del programador completamente justo (CFS) de la CPU
--cpu-rt-periodAPI 1.25+ Limita el período en tiempo real de la CPU en microsegundos
--cpu-rt-runtimeAPI 1.25+ Limita el tiempo de ejecución en tiempo real de la CPU en microsegundos
-c, --cpu-sharesCuotas de CPU (peso relativo)
--cpusAPI 1.25+ Número de CPUs
--cpuset-cpusCPUs en las que se permite la ejecución (0-3, 0,1)
--cpuset-memsMemoria (MEMs) en las que se permite la ejecución (0-3, 0,1)
-d, --detachEjecuta el contenedor en segundo plano e imprime el ID del contenedor
--detach-keysInvalida la secuencia de teclas para desasociar un contenedor
--deviceAñade un dispositivo del host al contenedor
--device-cgroup-ruleAñade una regla a la lista de dispositivos permitidos del cgroup
--device-read-bpsLimita la velocidad de lectura (bytes por segundo) de un dispositivo
--device-read-iopsLimita la velocidad de lectura (E/S por segundo) de un dispositivo
--device-write-bpsLimita la velocidad de escritura (bytes por segundo) en un dispositivo
--device-write-iopsLimita la velocidad de escritura (E/S por segundo) en un dispositivo
--dnsEstablece servidores DNS personalizados
--dns-optionEstablece opciones de DNS
--dns-searchEstablece dominios de búsqueda DNS personalizados
--domainnameNombre de dominio NIS del contenedor
--entrypointSobrescribe el ENTRYPOINT por defecto de la imagen
-e, --envEstablece variables de entorno
--env-fileLee un archivo de variables de entorno
--exposeExpone un puerto o un rango de puertos
--gpusAPI 1.40+ Dispositivos GPU a añadir al contenedor ('all' para pasar todas las GPUs)
--group-addAñade grupos adicionales a los que unirse
--health-cmdComando a ejecutar para comprobar la salud
--health-intervalTiempo entre ejecuciones de la comprobación (ms|s|m|h) (por defecto 0s)
--health-retriesFallos consecutivos necesarios para reportar que no es saludable (unhealthy)
--health-start-intervalAPI 1.44+ Tiempo entre ejecuciones de la comprobación durante el período de inicio (ms|s|m|h) (por defecto 0s)
--health-start-periodAPI 1.29+ Período de inicio para que el contenedor se inicialice antes de comenzar la cuenta regresiva de reintentos de salud (ms|s|m|h) (por defecto 0s)
--health-timeoutTiempo máximo permitido para que se ejecute una comprobación (ms|s|m|h) (por defecto 0s)
--helpImprime el uso
-h, --hostnameNombre de host del contenedor
--initAPI 1.25+ Ejecuta un init dentro del contenedor que reenvía señales y recolecta procesos huérfanos
-i, --interactiveMantiene STDIN abierto incluso si no está asociado
--io-maxbandwidthLímite máximo de ancho de banda de E/S para la unidad del sistema (solo Windows)
--io-maxiopsLímite máximo de IOps para la unidad del sistema (solo Windows)
--ipDirección IPv4 (por ejemplo, 172.30.100.104)
--ip6Dirección IPv6 (por ejemplo, 2001:db8::33)
--ipcModo IPC a utilizar
--isolationTecnología de aislamiento del contenedor
-l, --labelEstablece metadatos en un contenedor
--label-fileLee un archivo delimitado por líneas de etiquetas
--linkAñade un enlace a otro contenedor
--link-local-ipDirecciones IPv4/IPv6 de enlace local (link-local) del contenedor
--log-driverControlador de registros (logging driver) para el contenedor
--log-optOpciones del controlador de registros
--mac-addressDirección MAC del contenedor (por ejemplo, 92:d0:c6:0a:29:33)
-m, --memoryLímite de memoria
--memory-reservationLímite flexible de memoria (soft limit)
--memory-swapLímite de intercambio (swap) igual a la memoria más el intercambio: '-1' para habilitar intercambio ilimitado
--memory-swappiness-1Ajusta la agresividad de intercambio (swappiness) de memoria del contenedor (0 a 100)
--mountAsocia un montaje de sistema de archivos al contenedor
--nameAsigna un nombre al contenedor
--networkConecta un contenedor a una red
--network-aliasAñade un alias de ámbito de red para el contenedor
--no-healthcheckDesactiva cualquier HEALTHCHECK especificado en el contenedor
--oom-kill-disableDesactiva OOM Killer (eliminación por falta de memoria)
--oom-score-adjAjusta las preferencias OOM del host (-1000 a 1000)
--pidEspacio de nombres PID a utilizar
--pids-limitAjusta el límite de pids del contenedor (establece -1 para ilimitado)
--platformAPI 1.32+ Establece la plataforma si el servidor tiene capacidad multiplataforma
--privilegedConcede privilegios extendidos a este contenedor
-p, --publishPublica puerto(s) de un contenedor en el host
-P, --publish-allPublica todos los puertos expuestos a puertos aleatorios
--pullmissingDescarga (pull) la imagen antes de ejecutar (always, missing, never)
-q, --quietSuprime la salida de la descarga (pull)
--read-onlyMonta el sistema de archivos raíz del contenedor como de solo lectura
--restartnoPolítica de reinicio a aplicar cuando un contenedor finaliza
--rmElimina automáticamente el contenedor y sus volúmenes anónimos asociados cuando finaliza
--runtimeEntorno de ejecución (runtime) a utilizar para este contenedor
--security-optOpciones de seguridad (Security Options)
--shm-sizeTamaño de /dev/shm
--sig-proxytrueRedirige las señales recibidas al proceso
--stop-signalSeñal para detener el contenedor
--stop-timeoutAPI 1.25+ Tiempo de espera (en segundos) para detener un contenedor
--storage-optOpciones del controlador de almacenamiento para el contenedor
--sysctlOpciones de sysctl
--tmpfsMonta un directorio tmpfs
-t, --ttyAsigna un pseudo-TTY
--ulimitOpciones de ulimit
--use-api-socketMonta mediante bind el socket de la API de Docker y la autenticación requerida
-u, --userNombre de usuario o UID (formato: <nombre|uid>[:<grupo|gid>])
--usernsEspacio de nombres de usuario a utilizar
--utsEspacio de nombres UTS a utilizar
-v, --volumeMonta un volumen mediante bind mount
--volume-driverControlador de volúmenes opcional para el contenedor
--volumes-fromMonta volúmenes desde el/los contenedor(es) especificado(s)
-w, --workdirDirectorio de trabajo dentro del contenedor

Ejemplos

Asignar nombre (--name)

El flag --name te permite especificar un identificador personalizado para un contenedor. El siguiente ejemplo ejecuta un contenedor llamado test utilizando la imagen nginx:alpine en modo desasociado (detached).

$ docker run --name test -d nginx:alpine
4bed76d3ad428b889c56c1ecc2bf2ed95cb08256db22dc5ef5863e1d03252a19
$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED        STATUS                  PORTS     NAMES
4bed76d3ad42   nginx:alpine   "/docker-entrypoint.…"   1 second ago   Up Less than a second   80/tcp    test

Puedes hacer referencia al contenedor por su nombre con otros comandos. Por ejemplo, los siguientes comandos detienen y eliminan un contenedor llamado test:

$ docker stop test
test
$ docker rm test
test

Si no especificas un nombre personalizado con el flag --name, el demonio asigna un nombre generado aleatoriamente, como vibrant_cannon, al contenedor. Usar un nombre definido de forma personalizada ofrece la ventaja de tener un identificador fácil de recordar para el contenedor.

Además, si conectas el contenedor a una red bridge definida por el usuario, otros contenedores en la misma red pueden referirse a él por su nombre a través de DNS.

$ docker network create mynet
cb79f45948d87e389e12013fa4d969689ed2c3316985dd832a43aaec9a0fe394
$ docker run --name test --net mynet -d nginx:alpine
58df6ecfbc2ad7c42d088ed028d367f9e22a5f834d7c74c66c0ab0485626c32a
$ docker run --net mynet busybox:latest ping test
PING test (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.073 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.411 ms
64 bytes from 172.18.0.2: seq=2 ttl=64 time=0.319 ms
64 bytes from 172.18.0.2: seq=3 ttl=64 time=0.383 ms
...

Capturar el ID del contenedor (--cidfile)

Para ayudar con la automatización, puedes hacer que Docker escriba el ID del contenedor en un archivo de tu elección. Esto es similar a cómo algunos programas escriben su ID de proceso en un archivo (es posible que los conozcas como archivos PID):

$ docker run --cidfile /tmp/docker_test.cid ubuntu echo "test"

Esto crea un contenedor e imprime test en la consola. El flag cidfile hace que Docker intente crear un nuevo archivo y escriba el ID del contenedor en él. Si el archivo ya existe, Docker devuelve un error. Docker cierra este archivo cuando docker run finaliza.

Ajustes de PID (--pid)

--pid=""  : Establece el modo de espacio de nombres PID (Proceso) para el contenedor,
             'container:<name|id>': se une al espacio de nombres PID de otro contenedor
             'host': utiliza el espacio de nombres PID del host dentro del contenedor

Por defecto, todos los contenedores tienen activado el espacio de nombres PID.

El espacio de nombres PID proporciona separación de procesos. El espacio de nombres PID elimina la vista de los procesos del sistema y permite reutilizar los IDs de proceso, incluido el PID 1.

En ciertos casos, deseas que tu contenedor comparta el espacio de nombres de procesos del host, lo que permite a los procesos del contenedor ver todos los procesos del sistema. Por ejemplo, podrías construir un contenedor con herramientas de depuración como strace o gdb, pero querer usar estas herramientas para depurar procesos dentro del contenedor.

Ejemplo: ejecutar htop dentro de un contenedor

Para ejecutar htop en un contenedor que comparte el espacio de nombres de procesos del host:

  1. Ejecuta un contenedor alpine con la opción --pid=host:

    $ docker run --rm -it --pid=host alpine
    
  2. Instala htop en el contenedor:

    / # apk add --quiet htop
    
  3. Invoca el comando htop.

    / # htop
    

Ejemplo: unirse al espacio de nombres PID de otro contenedor

Unirse al espacio de nombres PID de otro contenedor puede ser útil para depurar dicho contenedor.

  1. Inicia un contenedor que ejecute un servidor Nginx:

    $ docker run --rm --name my-nginx -d nginx:alpine
    
  2. Ejecuta un contenedor Alpine que asocie el espacio de nombres --pid al contenedor my-nginx:

    $ docker run --rm -it --pid=container:my-nginx \
      --cap-add SYS_PTRACE \
      --security-opt seccomp=unconfined \
      alpine
    
  3. Instala strace en el contenedor Alpine:

    / # apk add strace
    
  4. Asóciate al proceso 1, el ID de proceso del contenedor my-nginx:

    / # strace -p 1
    strace: Process 1 attached
    

Desactivar el remapeo de espacios de nombres para un contenedor (--userns)

Si habilitas los espacios de nombres de usuario (user namespaces) en el demonio, todos los contenedores se iniciarán con los espacios de nombres de usuario activados por defecto. Para desactivar el remapeo de espacios de nombres de usuario para un contenedor específico, puedes establecer el flag --userns en host.

docker run --userns=host hello-world

host es el único valor válido para el flag --userns.

Para más información, consulta Aislar contenedores con espacios de nombres de usuario.

Ajustes de UTS (--uts)

--uts=""  : Establece el modo de espacio de nombres UTS para el contenedor
            'host': utiliza el espacio de nombres UTS del host dentro del contenedor

El espacio de nombres UTS sirve para establecer el nombre de host y el dominio que es visible para los procesos en ejecución en ese espacio de nombres. Por defecto, todos los contenedores, incluidos aquellos con --network=host, tienen su propio espacio de nombres UTS. Establecer --uts en host hace que el contenedor utilice el mismo espacio de nombres UTS que el host.

Note

Docker no permite combinar los flags --hostname y --domainname con --uts=host. Esto es para evitar que los contenedores que se ejecutan en el espacio de nombres UTS del host intenten cambiar la configuración de este.

Es posible que desees compartir el espacio de nombres UTS con el host si quieres que el nombre de host del contenedor cambie a medida que cambia el nombre de host del host. Un caso de uso más avanzado sería cambiar el nombre de host del host desde un contenedor.

Ajustes de IPC (--ipc)

--ipc="MODE"  : Establece el modo IPC para el contenedor

El flag --ipc acepta los siguientes valores:

ValorDescripción
""Utiliza el valor predeterminado del demonio.
"none"Espacio de nombres IPC propio y privado, con /dev/shm sin montar.
"private"Espacio de nombres IPC propio y privado.
"shareable"Espacio de nombres IPC propio y privado, con posibilidad de compartirlo con otros contenedores.
"container:<nombre-o-ID>"Se une al espacio de nombres IPC de otro contenedor ("compartible").
"host"Utiliza el espacio de nombres IPC del sistema host.

Si no se especifica, se utiliza el valor predeterminado del demonio, que puede ser "private" o "shareable", dependiendo de la versión y configuración del demonio.

Los espacios de nombres de comunicación entre procesos (IPC) de System V proporcionan separación de segmentos de memoria compartida con nombre, semáforos y colas de mensajes.

Los segmentos de memoria compartida se utilizan para acelerar la comunicación entre procesos a la velocidad de la memoria, en lugar de a través de tuberías o de la pila de red. La memoria compartida se utiliza habitualmente en bases de datos y aplicaciones de alto rendimiento personalizadas (típicamente C/OpenMPI, C++/usando bibliotecas boost) para computación científica e industrias de servicios financieros. Si este tipo de aplicaciones se dividen en múltiples contenedores, es posible que necesites compartir los mecanismos IPC de los contenedores, utilizando el modo "shareable" para el contenedor principal (es decir, "donante") y "container:<donante-nombre-o-ID>" para los demás contenedores.

Escalar privilegios del contenedor (--privileged)

El flag --privileged concede las siguientes capacidades a un contenedor:

  • Habilita todas las capacidades del kernel de Linux
  • Desactiva el perfil seccomp predeterminado
  • Desactiva el perfil AppArmor predeterminado
  • Desactiva la etiqueta de proceso SELinux
  • Concede acceso a todos los dispositivos del host
  • Permite la lectura y escritura en /sys
  • Permite la lectura y escritura en los montajes de cgroups

En otras palabras, el contenedor puede hacer casi todo lo que el host puede hacer. Este flag existe para permitir casos de uso especiales, como ejecutar Docker dentro de Docker.

Warning

Utiliza el flag --privileged con precaución. Un contenedor con --privileged no es un proceso aislado de forma segura. Los contenedores en este modo pueden obtener una shell de root en el host y tomar el control del sistema.

Para la mayoría de los casos de uso, este flag no debería ser la solución preferida. Si tu contenedor requiere privilegios escalados, deberías preferir otorgar explícitamente los permisos necesarios, por ejemplo, añadiendo capacidades individuales del kernel con --cap-add.

Para más información, consulta Privilegios en tiempo de ejecución y capacidades de Linux

El siguiente ejemplo no funciona porque, por defecto, Docker descarta la mayoría de las capacidades del kernel potencialmente peligrosas, incluida CAP_SYS_ADMIN (que se requiere para montar sistemas de archivos).

$ docker run -t -i --rm ubuntu bash
root@bc338942ef20:/# mount -t tmpfs none /mnt
mount: permission denied

Funciona cuando añades el flag --privileged:

$ docker run -t -i --privileged ubuntu bash
root@50e3f57e16e6:/# mount -t tmpfs none /mnt
root@50e3f57e16e6:/# df -h
Filesystem      Size  Used Avail Use% Mounted on
none            1.9G     0  1.9G   0% /mnt

Establecer el directorio de trabajo (-w, --workdir)

$ docker run -w /path/to/dir/ ubuntu pwd

La opción -w ejecuta el comando especificado dentro del directorio indicado, en este ejemplo, /path/to/dir/. Si la ruta no existe, Docker la crea dentro del contenedor.

Establecer opciones del controlador de almacenamiento por contenedor (--storage-opt)

$ docker run -it --storage-opt size=120G fedora /bin/bash

Esto (size) limita el tamaño del sistema de archivos del contenedor a 120G en el momento de la creación. Esta opción solo está disponible para los controladores de almacenamiento btrfs, overlay2, windowsfilter y zfs.

Para el controlador de almacenamiento overlay2, la opción de tamaño solo está disponible si el sistema de archivos subyacente es xfs y está montado con la opción de montaje pquota. Bajo estas condiciones, puedes pasar cualquier tamaño inferior al del sistema de archivos subyacente.

Para los controladores de almacenamiento windowsfilter, btrfs y zfs, no puedes pasar un tamaño inferior al Default BaseFS Size.

Montar tmpfs (--tmpfs)

El flag --tmpfs te permite crear un montaje tmpfs.

Las opciones que puedes pasar a --tmpfs son idénticas al comando de Linux mount -t tmpfs -o. El siguiente ejemplo monta un tmpfs vacío en el contenedor con las opciones rw, noexec, nosuid y size=65536k.

$ docker run -d --tmpfs /run:rw,noexec,nosuid,size=65536k my_image

Para más información, consulta Montajes tmpfs.

Montar volumen (-v)

$ docker  run  -v $(pwd):$(pwd) -w $(pwd) -i -t  ubuntu pwd

El ejemplo anterior monta el directorio actual en el contenedor en la misma ruta utilizando el flag -v, lo establece como directorio de trabajo y luego ejecuta el comando pwd dentro del contenedor.

A partir de la versión 23 de Docker Engine, puedes utilizar rutas relativas en el host.

$ docker  run  -v ./content:/content -w /content -i -t  ubuntu pwd

El ejemplo anterior monta el directorio content del directorio actual en el contenedor en la ruta /content utilizando el flag -v, lo establece como directorio de trabajo y luego ejecuta el comando pwd dentro del contenedor.

$ docker run -v /doesnt/exist:/foo -w /foo -i -t ubuntu bash

Cuando el directorio del host de un volumen montado mediante bind no existe, Docker lo crea automáticamente en el host por ti. En el ejemplo anterior, Docker crea la carpeta /doesnt/exist antes de iniciar el contenedor.

Montar volumen como solo lectura (--read-only)

$ docker run --read-only -v /icanwrite busybox touch /icanwrite/here

Puedes utilizar volúmenes en combinación con el flag --read-only para controlar dónde escribe archivos un contenedor. El flag --read-only monta el sistema de archivos raíz del contenedor como de solo lectura, prohibiendo la escritura en ubicaciones distintas de los volúmenes especificados para el contenedor.

$ docker run -t -i -v /var/run/docker.sock:/var/run/docker.sock -v /path/to/static-docker-binary:/usr/bin/docker busybox sh

Al montar mediante bind el socket Unix de Docker y el binario de Docker enlazado estáticamente (consulta obtener el binario de Linux), concedes al contenedor acceso completo para crear y manipular el demonio de Docker del host.

En Windows, debes especificar las rutas utilizando la semántica de rutas estilo Windows.

PS C:\> docker run -v c:\foo:c:\dest microsoft/nanoserver cmd /s /c type c:\dest\somefile.txt
Contents of file

PS C:\> docker run -v c:\foo:d: microsoft/nanoserver cmd /s /c type d:\somefile.txt
Contents of file

Los siguientes ejemplos fallan al utilizar contenedores basados en Windows, ya que el destino de un volumen o montaje bind dentro del contenedor debe ser uno de los siguientes: un directorio inexistente o vacío; o una unidad distinta de C:. Además, el origen de un montaje bind debe ser un directorio local, no un archivo.

net use z: \\remotemachine\share
docker run -v z:\foo:c:\dest ...
docker run -v \\uncpath\to\directory:c:\dest ...
docker run -v c:\foo\somefile.txt:c:\dest ...
docker run -v c:\foo:c: ...
docker run -v c:\foo:c:\existing-directory-with-contents ...

Para información detallada sobre volúmenes, consulta Administrar datos en contenedores.

Añadir montajes bind o volúmenes utilizando el flag --mount

El flag --mount te permite montar volúmenes, directorios del host y montajes tmpfs en un contenedor.

El flag --mount admite la mayoría de las opciones compatibles con -v o el flag --volume, pero utiliza una sintaxis diferente. Para información detallada sobre el flag --mount y una comparación entre --volume y --mount, consulta Montajes bind.

Aunque no hay planes para declarar obsoleto --volume, se recomienda el uso de --mount.

Ejemplos:

$ docker run --read-only --mount type=volume,target=/icanwrite busybox touch /icanwrite/here
$ docker run -t -i --mount type=bind,src=/data,dst=/data busybox sh

Publicar o exponer puerto (-p, --expose)

$ docker run -p 127.0.0.1:80:8080/tcp nginx:alpine

Esto vincula el puerto 8080 del contenedor al puerto TCP 80 en 127.0.0.1 del host. También puedes especificar puertos udp y sctp. La página de descripción general de redes explica detalladamente cómo publicar puertos con Docker.

Note

Si no especificas una dirección IP (es decir, -p 80:80 en lugar de -p 127.0.0.1:80:80) al publicar los puertos de un contenedor, Docker publica el puerto en todas las interfaces (dirección 0.0.0.0) por defecto. Estos puertos son accesibles externamente. Esto también se aplica si configuraste UFW para bloquear este puerto específico, ya que Docker administra sus propias reglas de iptables. Leer más

$ docker run --expose 80 nginx:alpine

Esto expone el puerto 80 del contenedor sin publicar el puerto en las interfaces del sistema host.

Publicar todos los puertos expuestos (-P, --publish-all)

$ docker run -P nginx:alpine

El flag -P, o --publish-all, publica todos los puertos expuestos en el host. Docker vincula cada puerto expuesto a un puerto aleatorio en el host.

El flag -P solo publica puertos que están explícitamente marcados como expuestos, ya sea mediante la instrucción EXPOSE del Dockerfile o el flag --expose del comando docker run.

El rango de puertos se encuentra dentro de un rango de puertos efímeros definido por /proc/sys/net/ipv4/ip_local_port_range. Utiliza el flag -p para mapear explícitamente un solo puerto o rango de puertos.

Establecer la política de descarga (--pull)

Utiliza el flag --pull para establecer la política de descarga de la imagen al crear (y ejecutar) el contenedor.

El flag --pull puede tomar uno de estos valores:

ValorDescripción
missing (por defecto)Descarga la imagen si no se encuentra en la caché de imágenes, o utiliza la imagen en caché en caso contrario.
neverNo descarga la imagen, incluso si no se encuentra, y produce un error si la imagen no existe en la caché de imágenes.
alwaysSiempre realiza una descarga (pull) antes de crear el contenedor.

Al crear (y ejecutar) un contenedor a partir de una imagen, el demonio comprueba si la imagen existe en la caché de imágenes local. Si falta la imagen, se devuelve un error a la CLI, lo que le permite iniciar una descarga.

El valor predeterminado (missing) consiste en descargar únicamente la imagen si no está presente en la caché de imágenes del demonio. Este valor predeterminado te permite ejecutar imágenes que solo existen localmente (por ejemplo, imágenes que construiste a partir de un Dockerfile pero que no se han subido a un registro), y reduce el uso de la red.

La opción always siempre inicia una descarga antes de crear el contenedor. Esta opción garantiza que la imagen esté actualizada y evita que utilices imágenes obsoletas, pero puede no ser adecuada en situaciones en las que deseas probar una imagen construida localmente antes de subirla (ya que descargar la imagen sobrescribe la imagen existente en la caché de imágenes).

La opción never desactiva la descarga (implícita) de imágenes al crear contenedores, y solo utiliza imágenes que están disponibles en la caché de imágenes. Si la imagen especificada no se encuentra, se produce un error y el contenedor no se crea. Esta opción es útil en situaciones en las que la red no está disponible, o para evitar que las imágenes se descarguen implícitamente al crear contenedores.

El siguiente ejemplo muestra docker run con la opción --pull=never configurada, lo que produce un error ya que la imagen no se encuentra en la caché de imágenes:

$ docker run --pull=never hello-world
docker: Error response from daemon: No such image: hello-world:latest.

Establecer variables de entorno (-e, --env, --env-file)

$ docker run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash

Utiliza los flags -e, --env y --env-file para establecer variables de entorno simples (no de matriz) en el contenedor que estás ejecutando, o sobrescribir variables definidas en el Dockerfile de la imagen que estás ejecutando.

Puedes definir la variable y su valor al ejecutar el contenedor:

$ docker run --env VAR1=value1 --env VAR2=value2 ubuntu env | grep VAR
VAR1=value1
VAR2=value2

También puedes utilizar variables exportadas a tu entorno local:

export VAR1=value1
export VAR2=value2

$ docker run --env VAR1 --env VAR2 ubuntu env | grep VAR
VAR1=value1
VAR2=value2

Al ejecutar el comando, el cliente CLI de Docker comprueba el valor que tiene la variable en tu entorno local y lo pasa al contenedor. Si no se proporciona un = y esa variable no está exportada en tu entorno local, la variable no se define (unset) en el contenedor.

También puedes cargar las variables de entorno desde un archivo. Este archivo debe utilizar la sintaxis <variable>=value (que establece la variable al valor dado) o <variable> (que toma el valor del entorno local), y # para los comentarios. Las líneas que comienzan con # se tratan como comentarios de línea y se ignoran, mientras que un # que aparece en cualquier otro lugar de una línea se trata como parte de la variable.

$ cat env.list
# This is a comment
VAR1=value1
VAR2=value2
USER

$ docker run --env-file env.list ubuntu env | grep -E 'VAR|USER'
VAR1=value1
VAR2=value2
USER=jonzeolla

Establecer metadatos en el contenedor (-l, --label, --label-file)

Una etiqueta es un par key=value que aplica metadatos a un contenedor. Para etiquetar un contenedor con dos etiquetas:

$ docker run -l my-label --label com.example.foo=bar ubuntu bash

La clave my-label no especifica un valor, por lo que la etiqueta toma por defecto una cadena vacía (""). Para añadir varias etiquetas, repite el flag de etiqueta (-l o --label).

El par key=value debe ser único para evitar sobrescribir el valor de la etiqueta. Si especificas etiquetas con claves idénticas pero valores diferentes, cada valor posterior sobrescribe el anterior. Docker utiliza el último par key=value que proporciones.

Utiliza el flag --label-file para cargar varias etiquetas desde un archivo. Delimita cada etiqueta en el archivo con una marca de fin de línea. El siguiente ejemplo carga etiquetas desde un archivo de etiquetas en el directorio actual:

$ docker run --label-file ./labels ubuntu bash

El formato del archivo de etiquetas es similar al formato para cargar variables de entorno. (A diferencia de las variables de entorno, las etiquetas no son visibles para los procesos que se ejecutan dentro del contenedor). El siguiente ejemplo muestra el formato de un archivo de etiquetas:

com.example.label1="a label"

# this is a comment
com.example.label2=another\ label
com.example.label3

Puedes cargar varios archivos de etiquetas proporcionando múltiples flags --label-file.

Para información adicional sobre cómo trabajar con etiquetas, consulta Etiquetas.

Conectar un contenedor a una red (--network)

Para iniciar un contenedor y conectarlo a una red, utiliza la opción --network.

Si deseas añadir un contenedor en ejecución a una red, utiliza el subcomando docker network connect.

Puedes conectar varios contenedores a la misma red. Una vez conectados, los contenedores pueden comunicarse utilizando únicamente la dirección IP o el nombre de otro contenedor. Para redes de tipo overlay o complementos personalizados que admiten conectividad multihost, los contenedores conectados a la misma red multihost pero iniciados desde diferentes motores también pueden comunicarse de esta manera.

Note

La red bridge predeterminada solo permite que los contenedores se comuniquen entre sí utilizando direcciones IP internas. Las redes bridge creadas por el usuario proporcionan resolución DNS entre contenedores utilizando los nombres de los contenedores.

Puedes desconectar un contenedor de una red utilizando el comando docker network disconnect.

Los siguientes comandos crean una red llamada my-net y añaden un contenedor busybox a la red my-net.

$ docker network create my-net
$ docker run -itd --network=my-net busybox

También puedes elegir las direcciones IP para el contenedor con los flags --ip y --ip6 cuando inicias el contenedor en una red definida por el usuario. Para asignar una IP estática a los contenedores, debes especificar el bloque de subred para la red.

$ docker network create --subnet 192.0.2.0/24 my-net
$ docker run -itd --network=my-net --ip=192.0.2.69 busybox

Para conectar el contenedor a más de una red, repite la opción --network.

$ docker network create --subnet 192.0.2.0/24 my-net1
$ docker network create --subnet 192.0.3.0/24 my-net2
$ docker run -itd --network=my-net1 --network=my-net2 busybox

Para especificar opciones al conectarse a más de una red, utiliza la sintaxis extendida para el flag --network. Las opciones separadas por comas que se pueden especificar en la sintaxis extendida --network son:

OportunidadEquivalente de nivel superiorDescripción
nameEl nombre de la red (obligatorio)
alias--network-aliasAñade un alias de ámbito de red para el contenedor
ip--ipDirección IPv4 (por ejemplo, 172.30.100.104)
ip6--ip6Dirección IPv6 (por ejemplo, 2001:db8::33)
mac-address--mac-addressDirección MAC del contenedor (por ejemplo, 92:d0:c6:0a:29:33)
link-local-ip--link-local-ipDirecciones de enlace local (link-local) IPv4/IPv6 del contenedor
driver-optdocker network connect --driver-optOpciones del controlador de red
gw-priorityLa prioridad de puerta de enlace (gw-priority) más alta proporciona la puerta de enlace predeterminada. Acepta valores positivos y negativos.
$ docker network create --subnet 192.0.2.0/24 my-net1
$ docker network create --subnet 192.0.3.0/24 my-net2
$ docker run -itd --network=name=my-net1,ip=192.0.2.42 --network=name=my-net2,ip=192.0.3.42 busybox

Los ajustes de sysctl que comienzan con net.ipv4., net.ipv6. o net.mpls. se pueden establecer por interfaz utilizando la etiqueta de driver-opt com.docker.network.endpoint.sysctls. El nombre de la interfaz debe ser la cadena IFNAME.

To set more than one sysctl for an interface, quote the whole driver-opt field, remembering to escape the quotes for the shell if necessary. For example, if the interface to my-net is given name eth0, the following example sets sysctls net.ipv4.conf.eth0.log_martians=1 and net.ipv4.conf.eth0.forwarding=0, and assigns the IPv4 address 192.0.2.42.

$ docker network create --subnet 192.0.2.0/24 my-net
$ docker run -itd --network=name=my-net,\"driver-opt=com.docker.network.endpoint.sysctls=net.ipv4.conf.IFNAME.log_martians=1,net.ipv4.conf.IFNAME.forwarding=0\",ip=192.0.2.42 busybox
Note

Los controladores de red pueden restringir los ajustes de sysctl que se pueden modificar y, para proteger el funcionamiento de la red, es posible que se añadan nuevas restricciones en el futuro.

Para más información sobre cómo conectar un contenedor a una red al utilizar el comando run, consulta la descripción general de redes de Docker.

Montar volúmenes desde un contenedor (--volumes-from)

$ docker run --volumes-from 777f7dc92da7 --volumes-from ba8c0c54f0f2:ro -i -t ubuntu pwd

El flag --volumes-from monta todos los volúmenes definidos desde los contenedores referenciados. Puedes especificar más de un contenedor repitiendo el argumento --volumes-from. El ID del contenedor puede tener opcionalmente el sufijo :ro o :rw para montar los volúmenes en modo de solo lectura o lectura-escritura, respectivamente. Por defecto, Docker monta los volúmenes en el mismo modo (lectura-escritura o solo lectura) que el contenedor de referencia.

Los sistemas de etiquetado como SELinux requieren colocar etiquetas adecuadas en el contenido de los volúmenes montados en un contenedor. Sin una etiqueta, el sistema de seguridad podría impedir que los procesos que se ejecutan dentro del contenedor utilicen el contenido. Por defecto, Docker no cambia las etiquetas establecidas por el sistema operativo.

Para cambiar la etiqueta en el contexto del contenedor, puedes añadir uno de los dos sufijos :z o :Z al montaje del volumen. Estos sufijos indican a Docker que vuelva a etiquetar los objetos de archivo en los volúmenes compartidos. La opción z indica a Docker que dos contenedores comparten el contenido del volumen. Como resultado, Docker etiqueta el contenido con una etiqueta de contenido compartido. Las etiquetas de volúmenes compartidos permiten que todos los contenedores lean y escriban el contenido. La opción Z indica a Docker que etiquete el contenido con una etiqueta privada no compartida. Únicamente el contenedor actual puede utilizar un volumen privado.

Modo desasociado (Detached) (-d, --detach)

El flag --detach (o -d) inicia un contenedor como un proceso en segundo plano que no ocupa tu ventana de terminal. Por diseño, los contenedores iniciados en modo desasociado finalizan cuando el proceso raíz utilizado para ejecutar el contenedor finaliza, a menos que también especifiques la opción --rm. Si utilizas -d con --rm, el contenedor se elimina cuando finaliza o cuando el demonio finaliza, lo que ocurra primero.

No pases un comando service x start a un contenedor desasociado. Por ejemplo, este comando intenta iniciar el servicio nginx.

$ docker run -d -p 80:80 my_image service nginx start

Esto logra iniciar el servicio nginx dentro del contenedor. Sin embargo, falla en el paradigma del contenedor desasociado ya que el proceso raíz (service nginx start) finaliza y el contenedor desasociado se detiene como está diseñado. Como resultado, el servicio nginx se inicia pero no se puede utilizar. En su lugar, para iniciar un proceso como el servidor web nginx haz lo siguiente:

$ docker run -d -p 80:80 my_image nginx -g 'daemon off;'

Para realizar operaciones de entrada/salida con un contenedor desasociado, utiliza conexiones de red o volúmenes compartidos. Estos son necesarios porque el contenedor ya no está escuchando en la línea de comandos donde se ejecutó docker run.

Invalidar la secuencia de desasociación (--detach-keys)

Utiliza la opción --detach-keys para invalidar la secuencia de teclas de Docker para desasociar. Esto es útil si la secuencia predeterminada de Docker entra en conflicto con la secuencia de teclas que utilizas para otras aplicaciones. Hay dos formas de definir tu propia secuencia de teclas de desasociación: como una invalidación por contenedor o como una propiedad de configuración en toda tu configuración.

Para invalidar la secuencia para un contenedor individual, utiliza el flag --detach-keys="<secuencia>" con el comando docker attach. El formato de la <secuencia> es una letra [a-Z] o ctrl- combinado con cualquiera de los siguientes:

  • a-z (un solo carácter alfabético en minúscula)
  • @ (arroba)
  • [ (corchete izquierdo)
  • \\ (dos barras invertidas)
  • _ (guion bajo)
  • ^ (circunflejo)

Los valores a, ctrl-a, X o ctrl-\\ son ejemplos de secuencias de teclas válidas. Para configurar una secuencia de teclas predeterminada diferente para todos los contenedores, consulta la sección del archivo de configuración.

Añadir un dispositivo del host al contenedor (--device)

$ docker run -it --rm \
    --device=/dev/sdc:/dev/xvdc \
    --device=/dev/sdd \
    --device=/dev/zero:/dev/foobar \
    ubuntu ls -l /dev/{xvdc,sdd,foobar}

brw-rw---- 1 root disk 8, 2 Feb  9 16:05 /dev/xvdc
brw-rw---- 1 root disk 8, 3 Feb  9 16:05 /dev/sdd
crw-rw-rw- 1 root root 1, 5 Feb  9 16:05 /dev/foobar

A menudo es necesario exponer directamente dispositivos a un contenedor. La opción --device lo permite. Por ejemplo, añadir un dispositivo de almacenamiento de bloques específico, un dispositivo de bucle (loop) o un dispositivo de audio a un contenedor que de otro modo no tendría privilegios (sin el flag --privileged) y hacer que la aplicación acceda directamente a él.

Por defecto, el contenedor es capaz de leer (read), escribir (write) y crear nodos (mknod) en estos dispositivos. Esto se puede invalidar utilizando un tercer conjunto de opciones :rwm para cada flag --device. Si el contenedor se ejecuta en modo privilegiado, Docker ignora los permisos especificados.

$ docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk  /dev/xvdc

Command (m for help): q
$ docker run --device=/dev/sda:/dev/xvdc:r --rm -it ubuntu fdisk  /dev/xvdc
You will not be able to write the partition table.

Command (m for help): q

$ docker run --device=/dev/sda:/dev/xvdc:rw --rm -it ubuntu fdisk  /dev/xvdc

Command (m for help): q

$ docker run --device=/dev/sda:/dev/xvdc:m --rm -it ubuntu fdisk  /dev/xvdc
fdisk: unable to open /dev/xvdc: Operation not permitted
Note

La opción --device no se puede utilizar de forma segura con dispositivos efímeros. No deberías añadir dispositivos de bloque que puedan ser eliminados a contenedores no confiables con --device.

Para Windows, el formato de la cadena pasada a la opción --device es de la forma --device=<IdType>/<Id>. A partir de Windows Server 2019 y Windows 10 October 2018 Update, Windows solo admite un IdType de class y el Id como un GUID de clase de interfaz de dispositivo. Consulta la tabla definida en los documentos de contenedores de Windows para obtener una lista de los GUID de clase de interfaz de dispositivo compatibles con contenedores.

Si especificas esta opción para un contenedor de Windows aislado por procesos, Docker hace que todos los dispositivos que implementan el GUID de clase de interfaz de dispositivo solicitado estén disponibles en el contenedor. Por ejemplo, el comando de abajo hace que todos los puertos COM del host sean visibles en el contenedor.

PS C:\> docker run --device=class/86E0D1E0-8089-11D0-9CE4-08003E301F73 mcr.microsoft.com/windows/servercore:ltsc2019
Note

La opción --device solo es compatible con contenedores Windows aislados por procesos, y produce un error si el aislamiento del contenedor es hyperv.

Dispositivos CDI

La Interfaz de Dispositivos de Contenedor (CDI) es un mecanismo estandarizado para que los entornos de ejecución de contenedores creen contenedores que puedan interactuar con dispositivos de terceros.

CDI actualmente solo es compatible con contenedores Linux y está habilitado de forma predeterminada desde Docker Engine 28.3.0.

Con CDI, las configuraciones de los dispositivos se definen de forma declarativa mediante un archivo JSON o YAML. Además de permitir que el contenedor interactúe con el nodo del dispositivo, también te permite especificar configuraciones adicionales para el dispositivo, como variables de entorno, montajes del host (como objetos compartidos) y ganchos (hooks) ejecutables.

Puedes hacer referencia a un dispositivo CDI con el flag --device utilizando el nombre completo del dispositivo, como se muestra en el siguiente ejemplo:

$ docker run --device=vendor.com/class=device-name --rm -it ubuntu

Esto inicia un contenedor ubuntu con acceso al dispositivo CDI especificado, vendor.com/class=device-name, asumiendo que:

  • Se encuentra disponible en el sistema que ejecuta el demonio una especificación CDI válida (archivo JSON o YAML) para el dispositivo solicitado, en uno de los directorios de especificaciones CDI configurados.
  • Se ha habilitado la característica CDI en el demonio; consulta Habilitar dispositivos CDI.

Asociar a STDIN/STDOUT/STDERR (-a, --attach)

El flag --attach (o -a) indica a docker run que se vincule a las entradas y salidas STDIN, STDOUT o STDERR del contenedor. Esto hace posible manipular la salida y la entrada según sea necesario. Puedes especificar a cuál de los tres flujos estándar (STDIN, STDOUT, STDERR) deseas conectarte en su lugar, como en:

$ docker run -a stdin -a stdout -i -t ubuntu /bin/bash

El siguiente ejemplo canaliza datos a un contenedor e imprime el ID del contenedor asociándose únicamente a la entrada STDIN del contenedor.

$ echo "test" | docker run -i -a stdin ubuntu cat -

El siguiente ejemplo no imprime nada en la consola a menos que haya un error, porque la salida solo está asociada a STDERR del contenedor. Los registros (logs) del contenedor siguen almacenando lo que se escribe en STDERR y STDOUT.

$ docker run -a stderr ubuntu echo test

El siguiente ejemplo muestra una forma de utilizar --attach para canalizar un archivo a un contenedor. El comando imprime el ID del contenedor una vez finalizada la construcción y puedes recuperar los registros de la construcción utilizando docker logs. Esto es útil si necesitas canalizar un archivo u otra cosa a un contenedor y recuperar el ID del contenedor una vez que este ha terminado de ejecutarse.

$ cat somefile | docker run -i -a stdin mybuilder dobuild
Note

Un proceso que se ejecuta como PID 1 dentro de un contenedor recibe un trato especial por parte de Linux: ignora cualquier señal con la acción predeterminada. Por lo tanto, el proceso no finaliza con SIGINT o SIGTERM a menos que esté programado para hacerlo.

Consulta también el comando docker cp.

Mantener STDIN abierto (-i, --interactive)

El flag --interactive (o -i) mantiene abierta la entrada STDIN del contenedor y te permite enviar entradas al contenedor a través de la entrada estándar.

$ echo hello | docker run --rm -i busybox cat
hello

El flag -i se utiliza muy a menudo junto con el flag --tty para vincular los flujos de E/S del contenedor a una pseudoterminal, creando una sesión de terminal interactiva para el contenedor. Consulta Asignar un pseudo-TTY para más ejemplos.

$ docker run -it debian
root@10a3e71492b0:/# factor 90
90: 2 3 3 5
root@10a3e71492b0:/# exit
exit

Usar el flag -i por sí solo permite la composición, como canalizar entradas a los contenedores:

$ docker run --rm -i busybox echo "foo bar baz" \
  | docker run --rm -i busybox awk '{ print $2 }' \
  | docker run --rm -i busybox rev
rab

Especificar un proceso de inicio (init)

Puedes utilizar el flag --init para indicar que se debe utilizar un proceso de inicio como el PID 1 en el contenedor. Especificar un proceso de inicio garantiza que las responsabilidades habituales de un sistema de inicio, como la recolección de procesos zombi, se realicen dentro del contenedor creado.

El proceso de inicio predeterminado utilizado es el primer ejecutable docker-init que se encuentre en la ruta del sistema del proceso del demonio de Docker. Este binario docker-init, incluido en la instalación predeterminada, está respaldado por tini.

Asignar un pseudo-TTY (-t, --tty)

El flag --tty (o -t) asocia un pseudo-TTY al contenedor, conectando tu terminal a los flujos de E/S del contenedor. Asignar un pseudo-TTY al contenedor significa que obtienes acceso a las funciones de entrada y salida que proporcionan los dispositivos TTY.

Por ejemplo, el siguiente comando ejecuta el comando passwd en un contenedor debian para establecer una nueva contraseña para el usuario root.

$ docker run -i debian passwd root
New password: karjalanpiirakka9
Retype new password: karjalanpiirakka9
passwd: password updated successfully

Si ejecutas este comando solo con el flag -i (que te permite enviar texto a STDIN del contenedor), el prompt de passwd muestra la contraseña en texto plano. Sin embargo, si intentas lo mismo pero añadiendo también el flag -t, la contraseña se oculta:

$ docker run -it debian passwd root
New password:
Retype new password:
passwd: password updated successfully

Esto se debe a que passwd puede suprimir la salida de caracteres en la terminal utilizando la función de desactivación de eco de TTY.

Puedes utilizar el flag -t sin el flag -i. Esto sigue asignando un pseudo-TTY al contenedor, pero sin forma de escribir en STDIN. El único momento en que esto puede ser útil es si la salida del contenedor requiere un entorno TTY.

Especificar cgroups personalizados

Utilizando el flag --cgroup-parent, puedes pasar un cgroup específico en el que ejecutar un contenedor. Esto te permite crear y administrar cgroups por tu cuenta. Puedes definir recursos personalizados para esos cgroups y colocar contenedores bajo un grupo principal común.

Utilizar dispositivos creados dinámicamente (--device-cgroup-rule)

Docker asigna los dispositivos disponibles a un contenedor en el momento de la creación. Los dispositivos asignados se añaden al archivo cgroup.allow y se crean en el contenedor cuando se ejecuta. Esto plantea un problema cuando necesitas añadir un nuevo dispositivo a un contenedor en ejecución.

Una solución es añadir una regla más permisiva a un contenedor permitiéndole el acceso a una gama más amplia de dispositivos. Por ejemplo, suponiendo que el contenedor necesita acceso a un dispositivo de caracteres con un número mayor (major) 42 y cualquier número menor (minor) (que se añade a medida que aparecen nuevos dispositivos), añade la siguiente regla:

$ docker run -d --device-cgroup-rule='c 42:* rmw' --name my-container my-image

Luego, un usuario podría pedir a udev que ejecute un script que ejecute docker exec my-container mknod newDevX c 42 <minor> en el dispositivo requerido cuando este se añada.

Note

Aún debes añadir explícitamente los dispositivos inicialmente presentes al comando docker run / docker create.

Acceder a una GPU NVIDIA

El flag --gpus te permite acceder a los recursos de la GPU NVIDIA. En primer lugar, debes instalar nvidia-container-runtime.

Note

También puedes especificar una GPU como un dispositivo CDI con el flag --device, consulta Dispositivos CDI.

Lee Especificar los recursos de un contenedor para más información.

Para utilizar --gpus, especifica qué GPUs (o todas) usar. Si no proporcionas ningún valor, Docker utiliza todas las GPUs disponibles. El siguiente ejemplo expone todas las GPUs disponibles.

$ docker run -it --rm --gpus all ubuntu nvidia-smi

Utiliza la opción device para especificar las GPUs. El ejemplo de abajo expone una GPU específica.

$ docker run -it --rm --gpus device=GPU-3a23c669-1f69-c64e-cf85-44e9b07e7a2a ubuntu nvidia-smi

El ejemplo de abajo expone la primera y la tercera GPU.

$ docker run -it --rm --gpus '"device=0,2"' ubuntu nvidia-smi

Políticas de reinicio (--restart)

Utiliza el flag --restart para especificar la política de reinicio de un contenedor. Una política de reinicio controla si el demonio de Docker reinicia un contenedor después de su salida. Docker admite las siguientes políticas de reinicio:

FlagDescripción
noNo reinicia automáticamente el contenedor. (Por defecto)
on-failure[:max-retries]Reinicia el contenedor si este finaliza debido a un error, lo que se manifiesta como un código de salida distinto de cero. Opcionalmente, limita el número de veces que el demonio de Docker intenta reiniciar el contenedor utilizando la opción :max-retries. La política on-failure solo activa un reinicio si el contenedor finaliza con un fallo. No reinicia el contenedor si el demonio se reinicia.
alwaysReinicia siempre el contenedor si se detiene. Si se detiene manualmente, solo se reinicia cuando el demonio de Docker se reinicia o el propio contenedor se reinicia manualmente.
unless-stoppedSimilar a always, excepto que cuando el contenedor se detiene (manualmente o de otro modo), no se reinicia incluso después de que el demonio de Docker se reinicie.
$ docker run --restart=always redis

Esto ejecuta el contenedor redis con una política de reinicio always. Si el contenedor finaliza, Docker lo reinicia.

Cuando una política de reinicio está activa en un contenedor, este se muestra como Up o Restarting en docker ps. También puede ser útil utilizar docker events para ver la política de reinicio en efecto.

Se añade un retraso incremental (el doble del retraso anterior, comenzando en 100 milisegundos) antes de cada reinicio para evitar saturar el servidor. Esto significa que el demonio espera 100 ms, luego 200 ms, 400, 800, 1600, etc., hasta que se alcance el límite de on-failure, se alcance el retraso máximo de 1 minuto o cuando ejecutes docker stop o docker rm -f sobre el contenedor.

Si un contenedor se reinicia correctamente (se inicia y se ejecuta durante al menos 10 segundos), el retraso se restablece a su valor predeterminado de 100 ms.

Especificar un límite para los intentos de reinicio

Puedes especificar el número máximo de veces que Docker intentará reiniciar el contenedor al utilizar la política on-failure. Por defecto, Docker nunca deja de intentar reiniciar el contenedor.

El siguiente ejemplo ejecuta el contenedor redis con una política de reinicio de on-failure y un número máximo de reinicios de 10.

$ docker run --restart=on-failure:10 redis

Si el contenedor redis finaliza con un estado de salida distinto de cero más de 10 veces seguidas, Docker deja de intentar reiniciar el contenedor. Proporcionar un límite máximo de reinicio solo es válido para la política on-failure.

Inspeccionar los reinicios de los contenedores

El número de reinicios (intentados) de un contenedor se puede obtener utilizando el comando docker inspect. Por ejemplo, para obtener el número de reinicios del contenedor "my-container":

$ docker inspect -f "{{ .RestartCount }}" my-container
2

O bien, para obtener la última vez que el contenedor fue (re)iniciado:

$ docker inspect -f "{{ .State.StartedAt }}" my-container
2015-03-04T23:47:07.691840179Z

Combinar --restart (política de reinicio) con el flag --rm (limpieza) produce un error. Al reiniciar el contenedor, los clientes conectados se desconectan.

Limpieza (--rm)

Por defecto, el sistema de archivos de un contenedor persiste incluso después de que este finalice. Esto facilita enormemente la depuración, ya que puedes inspeccionar el estado final del contenedor y conservar todos tus datos.

Si ejecutas procesos en primer plano a corto plazo, estos sistemas de archivos de los contenedores pueden empezar a acumularse. Si deseas que Docker limpie automáticamente el contenedor y elimine el sistema de archivos cuando este finalice, utiliza el flag --rm:

--rm: Elimina automáticamente el contenedor y sus volúmenes anónimos asociados cuando finaliza
Note

Si configuras el flag --rm, Docker también elimina los volúmenes anónimos asociados al contenedor cuando este se elimina. Esto es similar a ejecutar docker rm -v mi-contenedor. Únicamente se eliminan los volúmenes que se especifican sin nombre. Por ejemplo, al ejecutar el siguiente comando, se elimina el volumen /foo, pero no /bar:

$ docker run --rm -v /foo -v awesome:/bar busybox top

Los volúmenes heredados a través de --volumes-from se eliminan con la misma lógica: si el volumen original se especificó con un nombre, no se elimina.

Añadir entradas al archivo hosts del contenedor (--add-host)

Puedes añadir otros hosts al archivo /etc/hosts de un contenedor utilizando uno o más flags --add-host. Este ejemplo añade una dirección estática para un host llamado my-hostname:

$ docker run --add-host=my-hostname=8.8.8.8 --rm -it alpine

/ # ping my-hostname
PING my-hostname (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=37 time=93.052 ms
64 bytes from 8.8.8.8: seq=1 ttl=37 time=92.467 ms
64 bytes from 8.8.8.8: seq=2 ttl=37 time=92.252 ms
^C
--- my-hostname ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 92.209/92.495/93.052 ms

Puedes envolver una dirección IPv6 entre corchetes:

$ docker run --add-host my-hostname=[2001:db8::33] --rm -it alpine

El flag --add-host admite un valor especial host-gateway que se resuelve en la dirección IP interna del host. Esto es útil cuando deseas que los contenedores se conecten a los servicios que se ejecutan en la máquina host.

Se acostumbra a utilizar host.docker.internal como el nombre de host que hace referencia a host-gateway. Docker Desktop resuelve automáticamente este nombre de host, consulta Explorar guías de redes en Docker Desktop y Configurar la IP de la puerta de enlace del host.

El siguiente ejemplo muestra cómo funciona el valor especial host-gateway. El ejemplo ejecuta un servidor HTTP que sirve un archivo desde el host al contenedor a través del nombre de host host.docker.internal, que se resuelve en la IP interna del host.

$ echo "hello from host!" > ./hello
$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
$ docker run \
  --add-host host.docker.internal=host-gateway \
  curlimages/curl -s host.docker.internal:8000/hello
hello from host!

El flag --add-host también acepta un separador :, por ejemplo:

$ docker run --add-host=my-hostname:8.8.8.8 --rm -it alpine

Controladores de registros (Logging drivers) (--log-driver)

El contenedor puede tener un controlador de registros diferente al del demonio de Docker. Utiliza la opción --log-driver=<DRIVER> con el comando docker run para configurar el controlador de registros del contenedor.

Para conocer los controladores de registro admitidos y cómo utilizarlos, consulta Configurar controladores de registro.

Para desactivar el registro de un contenedor, establece el flag --log-driver en none:

$ docker run --log-driver=none -d nginx:alpine
5101d3b7fe931c27c2ba0e65fd989654d297393ad65ae238f20b97a020e7295b
$ docker logs 5101d3b
Error response from daemon: configured logging driver does not support reading

Establecer ulimits en el contenedor (--ulimit)

Dado que la configuración de los ajustes de ulimit en un contenedor requiere privilegios adicionales no disponibles en el contenedor predeterminado, puedes establecerlos utilizando el flag --ulimit. Especifica --ulimit con un límite flexible (soft) y un límite estricto (hard) en el formato <tipo>=<límite flexible>[:<límite estricto>]. Por ejemplo:

$ docker run --ulimit nofile=1024:1024 --rm debian sh -c "ulimit -n"
1024
Note

Si no proporcionas un valor de límite estricto, Docker utiliza el valor del límite flexible para ambos valores. Si no proporcionas ningún valor, estos se heredan de los ulimits predeterminados establecidos en el demonio.

Note

La opción as está obsoleta. En otras palabras, no se admite el siguiente script:

$ docker run -it --ulimit as=1024 fedora /bin/bash

Opciones admitidas para --ulimit:

OpciónDescripción
coreTamaño máximo de los archivos core creados (RLIMIT_CORE)
cpuLímite de tiempo de CPU en segundos (RLIMIT_CPU)
dataTamaño máximo del segmento de datos (RLIMIT_DATA)
fsizeTamaño máximo de archivo (RLIMIT_FSIZE)
locksNúmero máximo de bloqueos de archivos (RLIMIT_LOCKS)
memlockEspacio de direcciones máximo bloqueado en memoria (RLIMIT_MEMLOCK)
msgqueueBytes máximos en colas de mensajes POSIX (RLIMIT_MSGQUEUE)
niceAjuste máximo de prioridad nice (RLIMIT_NICE)
nofileNúmero máximo de descriptores de archivos abiertos (RLIMIT_NOFILE)
nprocNúmero máximo de procesos disponibles (RLIMIT_NPROC)
rssTamaño máximo del conjunto residente (RLIMIT_RSS)
rtprioPrioridad máxima de programación en tiempo real (RLIMIT_RTPRIO)
rttimeTiempo máximo de ejecución en tiempo real (RLIMIT_RTTIME)
sigpendingNúmero máximo de señales pendientes (RLIMIT_SIGPENDING)
stackTamaño máximo de la pila (RLIMIT_STACK)

Docker envía los valores a la llamada al sistema (syscall) correspondiente del sistema operativo y no realiza ninguna conversión de bytes. Ten esto en cuenta al establecer los valores.

Para el uso de nproc

Ten cuidado al configurar nproc con el flag ulimit ya que Linux utiliza nproc para establecer el número máximo de procesos disponibles para un usuario, no para un contenedor. Por ejemplo, inicia cuatro contenedores con el usuario daemon:

$ docker run -d -u daemon --ulimit nproc=3 busybox top

$ docker run -d -u daemon --ulimit nproc=3 busybox top

$ docker run -d -u daemon --ulimit nproc=3 busybox top

$ docker run -d -u daemon --ulimit nproc=3 busybox top

El cuarto contenedor falla y reporta un error "[8] System error: resource temporarily unavailable". Esto falla porque el invocador configuró nproc=3, lo que provoca que los tres primeros contenedores agoten la cuota de tres procesos establecida para el usuario daemon.

Detener contenedor con señal (--stop-signal)

El flag --stop-signal envía la señal de llamada al sistema al contenedor para que finalice. Esta señal puede ser un nombre de señal en el formato SIG<NOMBRE>, por ejemplo SIGKILL, o un número entero sin signo que coincida con una posición en la tabla de llamadas al sistema del kernel, por ejemplo 9.

El valor predeterminado está definido por STOPSIGNAL en la imagen, o SIGTERM si la imagen no tiene definido ningún STOPSIGNAL.

Opciones de seguridad opcionales (--security-opt)

OpciónDescripción
--security-opt="label=user:USER"Establece la etiqueta de usuario para el contenedor
--security-opt="label=role:ROLE"Establece la etiqueta de rol para el contenedor
--security-opt="label=type:TYPE"Establece la etiqueta de tipo para el contenedor
--security-opt="label=level:LEVEL"Establece la etiqueta de nivel para el contenedor
--security-opt="label=disable"Desactiva el confinamiento de etiquetas para el contenedor
--security-opt="apparmor=PROFILE"Establece el perfil de AppArmor que se aplicará al contenedor
--security-opt="no-new-privileges=true"Evita que los procesos del contenedor obtengan nuevos privilegios
--security-opt="seccomp=unconfined"Desactiva el confinamiento de seccomp para el contenedor
--security-opt="seccomp=builtin"Utiliza el perfil seccomp predeterminado (integrado) para el contenedor. Esto se puede utilizar para habilitar seccomp para un contenedor que se ejecuta en un demonio con un perfil predeterminado personalizado establecido, o con seccomp desactivado ("unconfined").
--security-opt="seccomp=profile.json"Archivo JSON de llamadas al sistema permitidas en seccomp que se utilizará como filtro seccomp
--security-opt="systempaths=unconfined"Desactiva el confinamiento para las rutas del sistema (rutas enmascaradas, rutas de solo lectura) para el contenedor

El flag --security-opt te permite invalidar el esquema de etiquetado predeterminado para un contenedor. Especificar el nivel en el siguiente comando te permite compartir el mismo contenido entre contenedores.

$ docker run --security-opt label=level:s0:c100,c200 -it fedora bash
Note

No se admite la traducción automática de etiquetas MLS.

Para desactivar por completo el etiquetado de seguridad de un contenedor, puedes utilizar label=disable:

$ docker run --security-opt label=disable -it ubuntu bash

Si deseas una política de seguridad más estricta sobre los procesos dentro de un contenedor, puedes especificar una etiqueta de type personalizada. El siguiente ejemplo ejecuta un contenedor al que solo se le permite escuchar en puertos de Apache:

$ docker run --security-opt label=type:svirt_apache_t -it ubuntu bash
Note

Tendrías que escribir una política que defina el tipo svirt_apache_t.

Para evitar que los procesos de tu contenedor obtengan privilegios adicionales, puedes utilizar el siguiente comando:

$ docker run --security-opt no-new-privileges -it ubuntu bash

Esto significa que los comandos que elevan privilegios como su o sudo ya no funcionan. También provoca que los filtros de seccomp se apliquen más tarde, después de que se hayan descartado los privilegios, lo que puede significar que tengas un conjunto de filtros más restrictivo. Para más detalles, consulta la documentación del kernel.

On Windows, you can use the --security-opt flag to specify the credentialspec option. The credentialspec must be in the format file://spec.txt or registry://keyname.

Detener contenedor con tiempo de espera (--stop-timeout)

El flag --stop-timeout establece el número de segundos a esperar a que el contenedor se detenga después de enviar la señal de llamada al sistema predefinida (ver --stop-signal). Si el contenedor no finaliza una vez transcurrido el tiempo de espera, se le termina abruptamente por la fuerza con una señal SIGKILL.

Si estableces --stop-timeout en -1, no se aplica ningún tiempo de espera y el demonio espera indefinidamente a que el contenedor finalice.

El demonio determina el valor predeterminado, que es de 10 segundos para contenedores Linux y de 30 segundos para contenedores Windows.

Especificar la tecnología de aislamiento para el contenedor (--isolation)

Esta opción es útil en situaciones en las que estás ejecutando contenedores Docker en Windows. La opción --isolation=<value> establece la tecnología de aislamiento de un contenedor. En Linux, la única opción admitida es default, que utiliza espacios de nombres de Linux. Estos dos comandos son equivalentes en Linux:

$ docker run -d busybox top
$ docker run -d --isolation default busybox top

En Windows, --isolation puede tomar uno de estos valores:

ValorDescripción
defaultUtiliza el valor especificado por la opción --exec-opt del demonio de Docker o el valor predeterminado del sistema (ver más abajo).
processAislamiento del espacio de nombres con kernel compartido.
hypervAislamiento basado en particiones del hipervisor Hyper-V.

El aislamiento predeterminado en los sistemas operativos Windows Server es process, y hyperv en los sistemas operativos Windows cliente, como Windows 10. El aislamiento de procesos tiene un mejor rendimiento, pero requiere que la imagen y el host utilicen la misma versión del kernel.

En Windows Server, asumiendo la configuración predeterminada, estos comandos son equivalentes y dan como resultado un aislamiento de tipo process:

PS C:\> docker run -d microsoft/nanoserver powershell echo process
PS C:\> docker run -d --isolation default microsoft/nanoserver powershell echo process
PS C:\> docker run -d --isolation process microsoft/nanoserver powershell echo process

Si has configurado la opción --exec-opt isolation=hyperv en el demonio de Docker, o estás ejecutando contra un demonio basado en Windows cliente, estos comandos son equivalentes y dan como resultado un aislamiento de tipo hyperv:

PS C:\> docker run -d microsoft/nanoserver powershell echo hyperv
PS C:\> docker run -d --isolation default microsoft/nanoserver powershell echo hyperv
PS C:\> docker run -d --isolation hyperv microsoft/nanoserver powershell echo hyperv

Especificar límites estrictos de memoria disponible para contenedores (-m, --memory)

Estos parámetros siempre establecen un límite superior para la memoria disponible para el contenedor. Linux establece esto en el cgroup y las aplicaciones del contenedor pueden consultarlo en /sys/fs/cgroup/memory/memory.limit_in_bytes.

En Windows, esto afecta a los contenedores de forma diferente según el tipo de aislamiento que utilices.

  • Con el aislamiento process, Windows reporta la memoria completa del sistema host, no el límite, a las aplicaciones que se ejecutan dentro del contenedor.

    PS C:\> docker run -it -m 2GB --isolation=process microsoft/nanoserver powershell Get-ComputerInfo *memory*
    
    CsTotalPhysicalMemory      : 17064509440
    CsPhyicallyInstalledMemory : 16777216
    OsTotalVisibleMemorySize   : 16664560
    OsFreePhysicalMemory       : 14646720
    OsTotalVirtualMemorySize   : 19154928
    OsFreeVirtualMemory        : 17197440
    OsInUseVirtualMemory       : 1957488
    OsMaxProcessMemorySize     : 137438953344
  • Con el aislamiento hyperv, Windows crea una máquina virtual de utilidad que es lo suficientemente grande como para contener el límite de memoria, más el sistema operativo mínimo necesario para alojar el contenedor. Ese tamaño se reporta como "Memoria física total".

    PS C:\> docker run -it -m 2GB --isolation=hyperv microsoft/nanoserver powershell Get-ComputerInfo *memory*
    
    CsTotalPhysicalMemory      : 2683355136
    CsPhyicallyInstalledMemory :
    OsTotalVisibleMemorySize   : 2620464
    OsFreePhysicalMemory       : 2306552
    OsTotalVirtualMemorySize   : 2620464
    OsFreeVirtualMemory        : 2356692
    OsInUseVirtualMemory       : 263772
    OsMaxProcessMemorySize     : 137438953344

Configurar parámetros del kernel con espacio de nombres (sysctls) en tiempo de ejecución (--sysctl)

La opción --sysctl establece parámetros del kernel con espacio de nombres (sysctls) en el contenedor. Por ejemplo, para activar el reenvío de IP en el espacio de nombres de red de los contenedores, ejecuta este comando:

$ docker run --sysctl net.ipv4.ip_forward=1 someimage
Note

No todos los sysctls tienen espacio de nombres. Docker no admite el cambio de sysctls dentro de un contenedor si estos también modifican el sistema host. A medida que el kernel evolucione, esperamos ver más sysctls con espacio de nombres.

Sysctls admitidos actualmente

Espacio de nombres IPC:

  • kernel.msgmax, kernel.msgmnb, kernel.msgmni, kernel.sem, kernel.shmall, kernel.shmmax, kernel.shmmni, kernel.shm_rmid_forced.
  • Sysctls que comienzan con fs.mqueue.*
  • Si utilizas la opción --ipc=host, estos sysctls no están permitidos.

Espacio de nombres de red:

  • Sysctls que comienzan con net.*
  • Si utilizas la opción --network=host, el uso de estos sysctls no está permitido.