Cómo detener y terminar un contenedor Docker
Este artículo cubre siete puntos clave sobre cómo detener y terminar contenedores Docker.
Cubriremos los comandos pause
y stop
, cómo detener y apagar completamente,
cómo forzar una parada y apagado, cómo borrar en masa contenedores parados, las opciones signal
y timeout
, y cómo resolver `permission denied'.
1. Comando Stop Docker Container
La forma básica del comando para detener o terminar un contenedor Docker en ejecución es la siguiente.
docker container stop [OPCIONES] CONTENEDOR [CONTENEDOR...].
Dado que los contenedores Docker están basados en procesos Unix, este comando les da tiempo a dejar de ejecutarse enviando una señal SIGTERM
al contenedor Docker correspondiente.
. Luego mata ese proceso enviando una señal SIGKILL
.
La señal SIGTERM
indica al proceso que esperaremos a que salga de forma segura antes de matarlo.
SIGKILL es el equivalente a un cierre forzado en otros sistemas operativos.
Veamos de nuevo el comando stop
, donde CONTAINER
es el nombre o ID del contenedor que quieres parar.
Este comando te permite detener uno o más contenedores a la vez.
En [OPTIONS]
puedes añadir las opciones que quieras, como la opción --time
.
Las opciones que utilizaremos más a menudo serán tratadas en las siguientes secciones.
Un contenedor detenido con el comando stop
puede ser reiniciado con el comando start
.
El comando se muestra a continuación, y puedes añadir opciones como -a
, -i
, y otras que vimos en el post Ejecutando contenedores Docker.
$ docker container start [OPCIONES] CONTENEDOR [CONTENEDOR...].
Veamos un ejemplo sencillo de apagar y reiniciar un contenedor `nginx' en ejecución.
Primero, (1) miramos el nombre o ID de este contenedor, y con eso, (2) ejecutamos el comando stop
.
Ten en cuenta que (3) un contenedor parado no será buscado en la consulta ls
sin la opción --all
.
Luego (4) lo reiniciamos con el comando start
, y (5) verificamos.
$ docker container ls # (1)
container id image command
6f3e40d12122 nginx "/docker-entrypoint...."
$ docker container stop 6f3e # (2)
6f3e
$ docker container ls # (3)
$ docker container start 6f3e # (4)
6f3e
$ docker container ls # (5)
container id image command
6f3e40d12122 nginx "/docker-entrypoint...."
2. Comando Pausar Contenedor Docker
A veces puede ser necesario pausar un contenedor en ejecución. Esto se hace típicamente cuando los recursos del sistema son limitados y los recursos se están agotando. Cuando pausas un contenedor Docker, le devuelves temporalmente los recursos que tenía asignados.
El comando para pausar un contenedor es el siguiente
$ docker container pause [OPCIONES] CONTENEDOR [CONTENEDOR...]
Esto es similar al comando stop
que vimos en la Sección 1.
Cuando ejecutas el comando anterior, el demonio Docker envía una señal `SIGSTOP' al contenedor correspondiente, deteniendo temporalmente sus procesos.
Para reanudar el contenedor en pausa, ejecuta el siguiente comando
$ docker container unpause CONTENEDOR [CONTENEDOR...]
Este comando envía una señal SIGCONT
al contenedor Docker en pausa, haciendo que reanude su trabajo.
He aquí un ejemplo
$ docker container ls # check container ID
container id image ... status
6f3e40d12122 nginx ... Up 11 seconds
$ docker container pause 6f32 # Pause the container
6f3e
$ docker container ls # Verify container pause
container id image ... status
6f3e40d12122 nginx ... Up 26 seconds (Paused)
$ docker container unpause 6f3e # Restart the container
6f3e
$ docker container ls # Confirm container redo
6f3eCONTAINER ID IMAGE ... STATUS
6f3e40d12122 nginx ... Up 44 seconds
Los contenedores en estado Paused
se consultan con el comando docker container ls
,
La entrada STATUS
dirá (Paused)
.
Si ejecutas el comando unpause
en este estado, lo verás funcionando de nuevo.
3. Detener y matar todos los contenedores Docker
Docker no proporciona una opción separada para detener y matar todos los contenedores en bloque. Sin embargo, puedes parar todos tus contenedores usando dos comandos docker juntos como este
$ docker container stop $(docker container ls -aq)
La opción -a
en el comando docker container ls
que usamos aquí es la opción --all
, que pregunta por contenedores en todos los estados,
La opción -q
es la opción --quiet
, que sólo imprime los IDs de los contenedores.
Esta lista de IDs se pasa como argumento al comando stop
usando la sintaxis de shell script $()
.
En la práctica esto se parece a
$ docker container ls -aq # check target container IDs
6f3e40d12122
7d392cc25008
$ docker container stop $(docker container ls -aq) # Stop the entire container
6f3e40d12122
7d392cc25008
$ docker container ls # Confirm full container stop
container id image command
Esta es una forma fácil de detener todos los contenedores, pero puede detener inesperadamente contenedores que no deberían estar ejecutándose. Así que úsalo con cuidado.
4. Eliminar comando después de detener un contenedor
Cuando Docker reorganizó su estructura de comandos, eliminó la posibilidad de matar y eliminar un contenedor al mismo tiempo. Por lo tanto, es mejor utilizar los siguientes dos comandos espalda con espalda.
$ docker container stop [container-id]
$ docker container rm [container-id]
El comando docker container rm
se utiliza para eliminar un contenedor Docker detenido,
Para más información, consulta el post sobre eliminación de contenedores.
Sin embargo, si realmente quieres hacer esto con un solo comando, puedes usar el comando
Puedes usar la opción --force
del comando docker rm
, que es el comando heredado de Docker.
$ docker rm -f [container-id]
Este comando enviará inmediatamente una señal SIGKILL
a ese contenedor, forzándolo a apagarse.
Recuerda que borrar un contenedor también borra todos los datos dentro de ese contenedor, así que hazlo siempre con cuidado y reflexión.
5. Usando el comando kill y la opción --signal para forzar el cierre de un contenedor
Cuando se detiene y termina un contenedor, el comando docker container stop
es siempre la primera opción, ya que mata de forma segura todos los procesos.
Sin embargo, cuando un contenedor se encuentra en un estado que no responde, o ha sido creado con una imagen incorrecta y es difícil de manipular, es necesario forzar su apagado.
Docker proporciona un comando separado para matar un contenedor.
Este es el comando kill
.
$ docker container kill [OPTIONS] CONTAINER [CONTAINER...]
Este comando envía una señal SIGKILL
a uno o más contenedores, matándolos inmediatamente.
Si quieres enviar una señal distinta de SIGKILL
, puedes especificarla con la opción --signal
.
Sin embargo, en el caso de kill
, el proceso ya ignora otras señales, así que no creo que sea razonable esperar una respuesta diferente.
Si utilizas el comando kill
, puedes verte forzado a cerrar el proceso inmediatamente, con la consiguiente pérdida inesperada de datos, etc.
Por lo tanto, deberías hacer una copia de seguridad o prepararte para esto.
6. Establecer un Tiempo de Espera de Parada del Contenedor
En la Sección 1, mencioné que cuando ejecutas el comando docker container stop
, éste espera a que el contenedor envíe una señal SIGTERM
para detener el proceso de forma segura.
El valor por defecto para este tiempo que docker espera es de 10 segundos.
Aunque 10 segundos no es mucho tiempo, si el proceso de apagar un contenedor es lo suficientemente complicado como para tardar más de 10 segundos, Docker lo matará a la fuerza con una señal SIGKILL
.
Esto puede llevar a una pérdida inesperada de datos, etc.
Por lo tanto, a veces deberías poder darle más tiempo.
La opción --time
del comando stop
hace precisamente eso.
$ docker container stop -t 30 my_container
Si ejecutaste un comando como el anterior, tu contenedor debería tener 30 segundos para completar el proceso de apagado, después de lo cual será forzado a apagarse.
7. Qué hacer si se produce un error de permiso denegado
Puedes encontrarte con el mensaje de error permission denied
mientras apagas un contenedor.
Como dice el mensaje, esto ocurre porque el usuario actual no tiene permisos suficientes para manipular el contenedor Docker.
Docker requiere privilegios de root
o administrador por defecto.
Si eres un usuario doméstico, eres libre de configurar tus permisos, pero si estás trabajando en un entorno empresarial o colaborando, existe la posibilidad de que tus permisos no estén configurados tan altos como deberían.
Esto puede solucionarse ejecutando los comandos docker como root
, o uniéndote al grupo docker
, que permite a los usuarios que no son host utilizar docker.
7.1. Usando la palabra clave sudo
Usar el privilegio root
es fácil. Utiliza la palabra clave sudo
de la siguiente manera.
Necesitarás conocer la contraseña de tu cuenta host.
$ sudo docker container stop [container-id]
7.2. Añadir al grupo de usuarios docker
Aquí hay una manera de conceder permisos docker al usuario actual sin tener que utilizar la palabra clave sudo
en cada comando.
Ejecute el siguiente comando, cierre la sesión y vuelva a iniciarla como el usuario actual, y la configuración del grupo se aplicará.
$ sudo usermod -aG docker $USER
El comando anterior añade el usuario actualmente conectado ($USER
) al grupo llamado docker
(-aG
: append Group),
(usermod
: modificar usuario) para cambiar las propiedades del usuario.
Este método también requiere una contraseña para el comando sudo
.
Estas son dos formas de obtener permisos Docker y solucionar el problema de permission denied
.
8. Reflexiones finales
En este post, hemos cubierto cómo detener, pausar, matar, detener y eliminar un contenedor Docker, forzar la muerte, establecer un timeout
, y solucionar problemas de permisos,
y solucionar problemas de permisos.
Esperemos que esto te ayude en tu proceso de desarrollo actual.
