¿Cómo obtener Docker-compose para recrear siempre contenedores a partir de imágenes nuevas?

199

Las imágenes de mi ventana acoplable se crean en un servidor Jenkins CI y se envían a nuestro Registro privado de Docker. Mi objetivo es aprovisionar entornos con docker-compose que siempre inician el estado original de las imágenes.

Actualmente estoy usando docker-compose 1.3.2 y 1.4.0 en diferentes máquinas, pero también utilizamos versiones anteriores.

Siempre utilicé los docker-compose pull && docker-compose up -dcomandos para recuperar las imágenes nuevas del registro y ponerlas en marcha. Creo que mi comportamiento preferido docker-compose upfuncionó como se esperaba hasta cierto punto en el tiempo, pero desde entonces comenzó a volver a ejecutar contenedores detenidos anteriormente en lugar de iniciar las imágenes creadas originalmente cada vez.

¿Hay alguna manera de deshacerse de este comportamiento? ¿Podría ser así uno que esté conectado en el archivo de configuración docker-compose.yml para no depender de "no olvidar" algo en la línea de comando en cada invocación?

PD. Además de encontrar una manera de lograr mi objetivo, también me encantaría saber un poco más sobre los antecedentes de este comportamiento. Creo que la idea básica de Docker es construir una infraestructura inmutable. El comportamiento actual de docker-compose parece simplemente chocar con este enfoque ... ¿o me pierdo algunos puntos aquí?

Kristof Jozsa
fuente

Respuestas:

233

docker-compose up --force-recreatees una opción, pero si lo está utilizando para CI, comenzaría la compilación con docker-compose rm -fpara detener y eliminar los contenedores y volúmenes (luego seguirlo con pull and up).

Esto es lo que uso:

docker-compose rm -f
docker-compose pull
docker-compose up --build -d
# Run some tests
./tests
docker-compose stop -t 1

La razón por la que se recrean los contenedores es para preservar los volúmenes de datos que podrían usarse (y también es upmucho más rápido).

Si está haciendo CI, no quiere eso, por lo que simplemente eliminar todo debería obtener lo que desea.

Actualización: uso up --buildque se agregó en docker-compose1.7

dnephin
fuente
1
Sí, en realidad esto es lo que hago también en CI. No estoy seguro de por qué no mencioné eso ...
Adrian Mouat
@dnephin docker-compose run -dno existe? ¿Quieres decir que docker-compose up -dno?
Guillaume Vincent
2
si corres docker-compose pullantes docker-compose rm -fpuedes ahorrar aún más tiempo
stephanlindauer
2
¿Qué es la bandera -d al final?
David J. Davis el
3
"-d Modo separado: ejecutar contenedores en segundo plano,"
dnephin
135

La única solución que funcionó para mí fue este comando:

docker-compose build --no-cache

Esto extraerá automáticamente una imagen nueva del repositorio y no usará la versión de caché que está preconstruida con ningún parámetro que haya estado utilizando antes.

davidbonachera
fuente
1
Además, en Windows 10 puede ayudar establecer el servidor DNS en la configuración de Automático a Fijo o de Fijo a Automático.
qräbnö
2
Trabajó para mí en la construcción de OS X con docker-comopse versión 2.
RoboBear
1
Trabajó en OS X Docker.
HelloWorld
55

Según la documentación oficial actual , hay un atajo que detiene y elimina contenedores, redes, volúmenes e imágenes creados por arriba, si ya están detenidos o parcialmente eliminados, etc., también funcionará:

docker-compose down

Luego, si tiene nuevos cambios en sus imágenes o utiliza Dockerfiles:

docker-compose build --no-cache

Finalmente:docker-compose up

En un comando: docker-compose down && docker-compose build --no-cache && docker-compose up

Victor Timoftii
fuente
2
docker-compose build --no-cachesolo es necesario si hay cambios en Dockerfiles.
Victor Timoftii
De hecho, Víctor. ¡Gracias! Pensé que también era necesario después de actualizar un módulo / aplicación que se ejecuta cuando se inicia el contenedor. Para estos casos, antes de ejecutar docker-compose up, es necesario reconstruir los servicios con docker-compose build.
ivanleoncz
18

Puede pasar --force-recreatea docker compose up, que debe usar contenedores nuevos.

Creo que el razonamiento detrás de la reutilización de contenedores es preservar cualquier cambio durante el desarrollo. Tenga en cuenta que Compose hace algo similar con los volúmenes, que también persistirá entre la recreación del contenedor (un contenedor recreado se adjuntará a los volúmenes de su predecesor). Esto puede ser útil, por ejemplo, si tiene un contenedor Redis utilizado como caché y no desea perder el caché cada vez que realiza un pequeño cambio. En otras ocasiones es simplemente confuso.

No creo que haya ninguna forma de forzar esto desde el archivo Compose.

Podría decirse que choca con los principios de infraestructura inmutable. El contraargumento es probablemente que no usas Compose en producción (todavía). Además, no estoy seguro de estar de acuerdo en que infra inmutable es la idea básica de Docker, aunque sin duda es un buen caso de uso / punto de venta.

Adrian Mouat
fuente
Gracias por la respuesta. Creo que sería realmente útil forzarlo en el nivel de configuración, por ejemplo. para aplicarlo a un contenedor de base de datos y deshabilitar la recreación de forma predeterminada para los contenedores de aplicaciones ..
Kristof Jozsa
8
--force-recreateno funciona para mí ... La imagen no se extrae a pesar de que hay una versión más nueva ...
lisak
1
@lisak Nunca dije que sacara nuevas imágenes. No lo hace. Simplemente inicia nuevos contenedores usando cualquier imagen disponible localmente. Deberá ejecutar Docker Pull manualmente.
Adrian Mouat
2
docker-compose up --build

O

docker-compose build --no-cache
flgn
fuente
1
Cuando sea posible, intente proporcionar una explicación adicional en lugar de solo código. Dichas respuestas tienden a ser más útiles ya que ayudan a los miembros de la comunidad y especialmente a los nuevos desarrolladores a comprender mejor el razonamiento de la solución, y pueden ayudar a prevenir la necesidad de abordar las preguntas de seguimiento.
Rajan
-10
$docker-compose build

Si hay algo nuevo, será reconstruido.

Mathias Asberg
fuente