¿Cómo puedo reiniciar automáticamente mis contenedores Docker con container auto-delete?

Tengo un VPS de uso general y estoy acoplando las aplicaciones en él. Habrá alrededor de 5-6 contenedores en él, y muy poco más, por lo que la caja se puede reconstruir trivialmente según sea necesario.

Para cada aplicación tengo un script de inicio. Un contenedor de WordPress se ve así:

#!/bin/bash# Get the host IP addressexport DOCKER_HOSTIP=`ifconfig docker0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1`echo "Connecting to database on Docker host ${DOCKER_HOSTIP}"docker run \    --add-host=docker:${DOCKER_HOSTIP} \    --network dockernet \    --network-alias jonblog \    --detach \    --restart always \    --rm \    jonblog

Sin embargo, eso devuelve un error:

Opciones en conflicto :restart restart y --rm

Hay varios tickets de Docker que dicen que esto es sensato, pero no lo entiendo. Creo que mi significado es claro: si un contenedor no se está ejecutando (por ejemplo, en el arranque), entonces quiero iniciarlo. Si muere, espero que se elimine el contenedor y se cree uno nuevo a partir de la imagen base. Los contenedores deben ser inmutables de todos modos: cualquier estado que desee conservar, como archivos multimedia y registros, se escribirá en volúmenes.

Así que pensé que debería dejar el --restart marque y, a continuación, use un administrador de procesos para detener e iniciar contenedores de Docker. ¿Podría usar Monit aquí? Esperaba poder hacer algo como:

CHECK PROCESS jonblog MATCHING jonblog  START PROGRAM = "/root/docker/jonblog/host-start.sh"  STOP PROGRAM = "docker stop jon-blog"

Sin embargo, eso verifica la tabla de procesos del sistema, y no docker ps, y por lo tanto no encontrará algo que coincida con la cadena especificada. ¿Puedo llevarlo al ejecutivo docker ps periódicamente, y coinciden con las líneas en la salida?

Me encantaría usar otra herramienta si resulta sólida. Por ejemplo, encuentro que Supervisor es un poco pesado, pero si es más capaz de trabajar con Docker, estoy dispuesto a usarlo.

Aclaración sobre --rm

La razón por la que quiero --rm es que durante el proceso de dockerización, detengo el contenedor que se está ejecutando actualmente, load una nueva versión de la imagen y vuelva a ejecutar el script anterior. Esto significa que Docker está siendo notificado de un restart política para cada contenedor. Descubrí que después de reiniciar la caja, tendría 15 o más versiones ligeramente diferentes de la aplicación ejecutándose simultáneamente, lo cual no es la intención.

Supongo que podría usar docker update --restart never en contenedores viejos para evitar que esto suceda, pero luego, cuando mi contenedor se detiene, me quedo con él tirado, y tan pronto como lo haga, se eliminará automáticamente. Podría limpiar periódicamente los viejos usando algún tipo de trabajo cron, pero eso se siente un poco hacky dado que Docker puede hacerlo por mí.

Buscando una variedad de respuestas

Un comentario muy útil ha sugerido que debería analizar Minikube, que aparentemente simplifica la configuración de Kubernetes, incluso en la medida en que una persona con la habilidad adecuada puede estar en funcionamiento en cinco minutos.

Todavía me gustaría ver propuestas de soluciones más livianas, por lo que tengo una variedad de respuestas para elegir. Como se indicó, me gustaría saber la respuesta a si un supervisor de procesos como Monit funcionaría.

En la parte superior de mi cabeza, podría escribir un bucle de shell para escribir docker ps a un archivo cada cinco segundos durante un minuto, y luego ejecútelo en un Cron cada minuto. Luego podría escanear ese archivo usando grep y el Monit CHECK PROGRAM comprobación del sistema. Eso es un poco hacky, pero es algo que puedo entender fácilmente si hay un problema con él. Cualquier avance en esa sugerencia?

Tengo una respuesta que es adecuada para mi comprensión actual de Docker. Me aconsejaron en los comentarios que probara Minikube, y aunque, sin duda, esto se puede girar rápidamente, temía que esto fuera una madriguera de aprendizaje que me quedara atrapado en el alquitrán durante semanas. Uno de mis principios de ingeniería es saber cuándo se ha alcanzado un límite cognitivo para rellenar nueva información.

Por lo tanto, me propuse resolver este problema de una manera simple. Tenía dos opciones:

  1. Use la función de eliminación automática de contenedores en Docker y configure mi propio sistema de reinicio
  2. Usar la directiva de reinicio de Docker y configurar mi propio sistema de eliminación de contenedores

Comencé con el primero de ellos, con la idea de que el supervisor de procesos Monit sería bueno de usar, en parte porque es liviano y en parte porque estoy familiarizado con él. Sin embargo, comenzó a parecer la solución incorrecta, ya que estaría solucionando el problema central de que no puede obtener limpiamente una lista de procesos del contenedor Docker.

De hecho, la segunda opción era mucho más limpia, y esto se amplificó por el hecho de que la limpieza de contenedores detenidos no es en realidad una prioridad, es solo mantener las cosas ordenadas. Por supuesto, usé Docker para esto; aquí está el Dockerfile:

# Docker build script for Docker TidyFROM alpine:3.6RUN apk updateRUN apk add docker# See this for BusyBox cron schedules# https://gist.github.com/andyshinn/3ae01fa13cb64c9d36e7COPY bin/docker-tidy.sh /etc/periodic/daily/RUN chmod +x /etc/periodic/daily/docker-tidy.sh# Start Cron in the foregroundENTRYPOINT ["crond", "-l", "2", "-f"]

Y aquí está bin/docker-tidy.sh:

#!/bin/sh## With thanks to:# http://www.doublecloud.org/2015/05/simple-script-to-list-and-remove-all-stopped-docker-containers/docker rm -v $(docker ps -a -q -f status=exited)

Finalmente, un inconveniente de mi solución es que si el host se reinicia antes de una limpieza de contenedores detenida, esos contenedores también parecen reiniciarse. Por lo tanto, restablezco la política de reinicio en esos contenedores antes de iniciar otros nuevos.

Por ejemplo, así es como inicio el contenedor Docker Tidy en sí, en el host. En la práctica, he ordenado el código de cambio de política en su propio script, pero esto dará la idea general:

#!/bin/bash# Removes the restart policy from previous containersCONTAINER_LABEL=docker-tidy-instancedocker ps --all --filter label=$CONTAINER_LABEL --quiet | xargs --no-run-if-empty docker update --restart nodocker run \    --label $CONTAINER_LABEL \    --volume /var/run/docker.sock:/var/run/docker.sock \    --detach \    --restart always \    docker-tidy

Ve a jugar con Minikube, puedes tener eso en unos cinco minutos.

Es justo, @Michael. ¿Puedo hacer eso con Monit (sobre la base de que estoy algo familiarizado con él)? Miré la página de manual, pero esa es una lectura monstruosa, y perdí las ganas de vivir al atravesar eso. Sin embargo, me pregunto, a partir de los documentos, si la verificación del programa funcionaría: si puedo introducir un parámetro en la ruta del ejecutable, puede devolver éxito/error dependiendo de si el contenedor con nombre se está ejecutando.

Probablemente haya una forma más orientada a Docker de hacer esto, pero mi búsqueda no está mostrando nada particularmente interesante.

Honestamente, si está reconstruyendo contenedores con tanta frecuencia, debería usar algo como Kubernetes para administrar las cosas.

Tienes razón @Michael, y profundizaré en eso cuando tenga tiempo. El sub de Docker en Reddit me informa que Kube es una gran empresa (aunque valiosa). Buscaré algo más fácil por ahora, que tengo la oportunidad de asimilar.

(Un comentario aquí hace cinco minutos, ahora eliminado, decía que solo necesito ‘reiniciar’. Sí, esto funcionaría, pero entonces tendría que renunciar a rm rm - puedo tener uno u otro, pero no ambos, dado el error que mostré en la pregunta. Vea la edición de aclaración sobre por qué creo que se requiere `rm rm’).

No hay una buena manera de diferenciar entre las circunstancias en las que desea que se reinicie el contenedor y las circunstancias en las que desea que se elimine el contenedor. Esto es algo que debe manejar usted mismo fuera de Docker.