Estados de un contenedor Docker: created, running, paused, stopped, exited y cómo transitar entre ellos

DUGLAS MORENODUGLAS MORENO 👁 21
🎧 Escuchá el resumen · 0:59

Introducción

Los contenedores han cambiado la forma en que desarrollamos, probamos y desplegamos aplicaciones. Sin embargo, para manejarlos con confianza es fundamental comprender los distintos estados por los que pasa un contenedor durante su vida útil y los comandos que nos permiten moverlo de uno a otro. En este artículo, dirigido a desarrolladores, DevOps y cualquiera que trabaje con Docker, explicaremos cada estado (created, running, paused, stopped, exited), mostraremos los comandos que provocan las transiciones y incluiremos la salida esperada para que puedas reproducir los ejemplos en tu propia máquina.

Al final sabrás no solo qué significa cada estado, sino también cómo usar los comandos de Docker de forma segura y eficiente, evitando errores comunes que pueden dejar contenedores huérfanos o consumir recursos innecesariamente.

¿Qué es un contenedor en términos de estado?

Un contenedor es una instancia aislada de una imagen. Desde el momento en que Docker crea la instancia hasta que la elimina, el contenedor atraviesa varios estados que reflejan qué está haciendo el proceso principal dentro de él. Estos estados son:

  • created: el contenedor ha sido creado pero su proceso aún no ha comenzado.
  • running: el proceso principal está en ejecución.
  • paused: el proceso está suspendido (se utilizan señales SIGSTOP).
  • stopped: el proceso ha recibido una señal de terminación (SIGTERM) y ha finalizado, pero el contenedor sigue existiendo en el sistema.
  • exited: técnicamente es el mismo que stopped; Docker lo muestra como Exited con un código de salida.

Entender estas diferencias te ayuda a decidir cuándo pausar un contenedor para depurar, cuándo detenerlo para liberar recursos y cuándo eliminarlo definitivamente.

Estado created

Cuando ejecutas docker create o implícitamente al usar docker run sin la opción -d, Docker primero crea el contenedor y luego lo inicia. Si solo usas docker create, el contenedor queda en estado created y no ejecuta ningún proceso.

Ejemplo

# Crear un contenedor sin iniciarlo
docker create --name demo alpine:latest sleep 30

Salida esperada:

ad7f3c2b9e1d4f6a7b8c9d0e1f2a3b4c5d6e7f8g9h0i1j2k3l4m5n6o7p8q9r0s1t2

El string largo es el ID completo del contenedor. Puedes verificar su estado con:

docker ps -a --filter name=demo --format "{{.Names}}	{{.State}}"```

Salida esperada:

demo created


En este punto el contenedor existe en el sistema de archivos de Docker, pero el proceso `sleep 30` no está corriendo.

## Transición de *created* a *running*

Para pasar de *created* a *running* utilizamos `docker start`. Este comando le indica al daemon que arranque el proceso definido en la imagen.

### Ejemplo

```bash
docker start demo

Salida esperada:

demo

Ahora verificamos el estado:

docker ps -a --filter name=demo --format "{{.Names}}	{{.State}}"```

Salida esperada:

demo running


También podemos observar el proceso en tiempo real con `docker top`:

```bash
docker top demo

Salida esperada (puede variar ligeramente):

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                12345               12340               0                   10:15               ?                   00:00:00          sleep 30

Estado running

Este es el estado típico de un contenedor que está haciendo trabajo. El proceso principal responde a señales y consume CPU y memoria según su carga.

Ver detallado

docker inspect demo --format "{{.State.Status}}"```

Salida esperada:

running


## Pausar un contenedor (*running* → *paused*)

La pausa es útil cuando quieres congelar temporalmente el proceso sin terminar el contenedor. Docker envía la señal SIGSTOP a todos los procesos dentro del contenedor, lo que los deja en estado de espera.

### Ejemplo

```bash
docker pause demo

Salida esperada:

demo

Verificación:

docker ps -a --filter name=demo --format "{{.Names}}	{{.State}}"```

Salida esperada:

demo paused


Mientras está pausado, el contenedor sigue consumiendo memoria (el espacio de direcciones del proceso permanece en RAM) pero no utiliza CPU.

## Reanudar desde *paused* a *running*

Para volver a la ejecución normal usamos `docker unpause`.

### Ejemplo

```bash
docker unpause demo

Salida esperada:

demo

Comprobamos el estado nuevamente:

docker ps -a --filter name=demo --format "{{.Names}}	{{.State}}"```

Salida esperada:

demo running


## Detener un contenedor (*running* → *stopped*)

Cuando el trabajo ha terminado o necesitas liberar recursos, detienes el contenedor con `docker stop`. Docker primero envía SIGTERM, espera un periodo de gracia (por defecto 10 segundos) y, si el proceso no ha terminado, envía SIGKILL.

### Ejemplo

```bash
docker stop demo

Salida esperada:

demo

Verificación:

docker ps -a --filter name=demo --format "{{.Names}}	{{.State}}"```

Salida esperada:

demo exited


Observa que el estado muestra *exited* (no stopped). Docker usa este término para indicar que el proceso terminó y muestra el código de salida.

Para ver el código de salida:

```bash
docker inspect demo --format "{{.State.ExitCode}}"```

Salida esperada:

0


Un código de salida `0` indica finalización normal.

## Reiniciar un contenedor detenido (*stopped* → *running*)

Si el contenedor está detenido y quieres volver a ejecutarlo sin perder su sistema de archivos ni sus cambios, usas `docker start` nuevamente.

### Ejemplo

```bash
docker start demo

Salida esperada:

demo

Estado:

docker ps -a --filter name=demo --format "{{.Names}}	{{.State}}"```

Salida esperada:

demo running


## Eliminar un contenedor (*stopped*/*exited* → eliminado)

Cuando ya no necesitas el contenedor, lo eliminas con `docker rm`. Solo puedes eliminar contenedores que no estén en estado *running* (a menos que uses la bandera `-f` para forzar).

### Ejemplo

```bash
docker rm demo

Salida esperada:

demo

Después de la eliminación, el contenedor ya no aparece en docker ps -a.

docker ps -a --filter name=demo --format "{{.Names}}	{{.State}}"```

Salida esperada:

(ninguna línea)


## Transiciones menos comunes

### De *paused* a *stopped*

Si pausas un contenedor y luego lo detienes, Docker primero debe reanudarlo (implícitamente) para enviarle SIGTERM. En la práctica, ejecutar `docker stop` sobre un contenedor pausado funciona igual que sobre uno en ejecución: Docker lo despide, espera el periodo de gracia y luego lo detiene.

Ejemplo:

```bash
docker pause demo
# (asumimos que demo estaba running)
docker stop demo

Salida esperada de cada comando:

demo
# pausa
demo
# stop

Estado final: exited.

De created directamente a stopped

No es posible pasar de created a stopped sin pasar por running, porque el proceso nunca se inicia para recibir una señal de terminación. Si intentas docker stop sobre un contenedor created, Docker devuelve un error.

Ejemplo:

docker create --name test alpine:latest sleep 30
docker stop test

Salida esperada:

Error response from daemon: Cannot stop container test: it is not running

Buenas prácticas

  1. Usa nombres significativos para tus contenedores (--name) para que sea más fácil referenciarlos en los comandos.
  2. Preferir docker run --rm para contenedores de corta vida que no necesitas conservar después de su ejecución.
  3. Cuando necesites depurar, pausa el contenedor con docker pause, inspecciona su sistema de archivos con docker exec (si aún está running) o con docker export/docker import si está detenido.
  4. Libera recursos eliminando contenedores detenidos que no vayas a reutilizar: docker container prune elimina todos los contenedores en estado exited.
  5. Ten cuidado con el periodo de gracia de docker stop. Si tu aplicación necesita más tiempo para terminar tareas críticas, aumenta el timeout con -t <seconds>.
  6. Evita dejar contenedores en pausa por largos períodos; aunque no consumen CPU, siguen ocupando memoria y pueden afectar la capacidad del host.
  7. Documenta los códigos de salida de tus contenedores; un código distinto de cero suele indicar un problema que vale la pena investigar.

Errores comunes

  • Olvidar que docker stop no elimina el contenedor. Muchos creen que al detenerlo desaparece y luego se sorprenden al ver que sigue ocupando espacio.
  • Intentar eliminar un contenedor en ejecución sin -f. Esto genera un error y puede llevar a usar forzadamente la bandera sin comprender las implicaciones.
  • Confundir paused con stopped. Un contenedor pausado sigue consumiendo RAM; si el objetivo es liberar memoria, es mejor detenerlo.
  • Usar docker kill como primera opción. docker kill envía SIGKILL inmediatamente, lo que puede impedir una limpieza adecuada de recursos dentro del contenedor.
  • No revisar los logs antes de eliminar. Un contenedor que salió con código de error puede haber dejado pistas valiosas en docker logs.

Conclusión

Comprender los estados de un contenedor y las transiciones entre ellos es fundamental para administrar eficientemente tus entornos Docker. Hemos recorrido cada estado — created, running, paused, stopped/exited — y mostrado los comandos que los provocan, junto con la salida esperada para que puedas replicarlos en tu máquina.

Con este conocimiento podrás decidir cuándo pausar un contenedor para depurar, cuándo detenerlo para liberar recursos y cuándo eliminarlo definitivamente, evitando errores comunes y optimizando el uso de tu infraestructura.

Te animamos a experimentar con los ejemplos en tu propio entorno, a combinar los comandos según tus flujos de trabajo y a consultar siempre la documentación oficial de Docker para profundizar en opciones avanzadas como políticas de reinicio o límites de recursos.

¡Feliz containerización!


Este artículo fue escrito pensando en desarrolladores y operadores que buscan una guía clara y práctica sobre el ciclo de vida de los contenedores en Docker.

Comentarios (0)

Sé el primero en comentar.

Dejá tu comentario