cómo hacer que docker-compose use la última imagen del repositorio

81

No sé qué estoy haciendo mal, pero simplemente no puedo docker-compose upusar la última imagen de nuestro registro sin antes eliminar por completo los contenedores antiguos del sistema. Parece que componer está usando la imagen iniciada anteriormente, aunque la extracción de docker-compose ha obtenido una imagen más nueva.

Miré ¿Cómo hacer que docker-compose siempre vuelva a crear contenedores a partir de imágenes nuevas? que parecía ser similar a mi problema, pero ninguna de las soluciones proporcionadas allí funciona para mí, ya que estoy buscando una solución que pueda usar en el servidor de producción y allí no quiero eliminar todos los contenedores antes de iniciarlos de nuevo (¿posible pérdida de datos?). Me gustaría componer solo para detectar la nueva versión de las imágenes cambiadas, extraerlas y luego reiniciar los servicios con esas nuevas imágenes.

Creé un proyecto de prueba simple para esto en el que el único objetivo es obtener una versión nr para aumentar en cada nueva construcción. La versión nr se muestra si navego hasta el servidor nginx que se crea (esto funciona como se esperaba localmente).

versión de docker: 1.11.2 versión de docker-compose: 1.7.1 SO: probado en CentOS 7 y OS X 10.10 usando docker-toolbox

Mi docker-compose.yml:

version: '2'
services:
  application:
    image: ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev
    volumes:
      - /var/www/html
    tty: true

  nginx:
    build: nginx
    ports:
      - "80:80"
    volumes_from:
      - application
    volumes:
      - ./logs/nginx/:/var/log/nginx
  php:
    container_name: buildchaintest_php_1
    build: php-fpm
    expose:
      - "9000"
    volumes_from:
      - application
    volumes:
      - ./logs/php-fpm/:/var/www/logs

en nuestro servidor jenkins ejecuto lo siguiente para compilar y etiquetar la imagen

cd $WORKSPACE && PROJECT_VERSION=$(cat VERSION)-dev
/usr/local/bin/docker-compose rm -f
/usr/local/bin/docker-compose build
docker tag ourprivate.docker.reg:5000/ourcompany/buildchaintest ourprivate.docker.reg:5000/ourcompany/buildchaintest:$PROJECT_VERSION
docker push ourprivate.docker.reg:5000/ourcompany/buildchaintest

esto parece estar haciendo lo que se supone que debe hacer, ya que obtengo una nueva etiqueta de versión en nuestro repositorio cada vez que se completa la compilación y la versión nr se ha modificado.

Si ahora corro

docker-compose pull && docker-compose -f docker-compose.yml up -d

en una carpeta en mi computadora, donde el contenido es solo el docker-compose.yml y los Dockerfiles necesarios para construir los servicios nginx y php, el resultado que obtengo no es el número de versión más reciente como se ha etiquetado en el registro o se muestra en docker-compose.yml (0.1.8), pero la versión anterior, que es 0.1.7. Sin embargo, el resultado del comando de extracción sugeriría que se obtuvo una nueva versión de la imagen:

Pulling application (ourprivate.docker.reg:5000/ourcompany/buildchaintest:latest)...
latest: Pulling from ourcompany/buildchaintest
Digest: sha256:8f7a06203005ff932799fe89e7756cd21719cccb9099b7898af2399414bfe62a
Status: Downloaded newer image for docker.locotech.fi:5000/locotech/buildchaintest:0.1.8-dev

Solo si corro

docker-compose stop && docker-compose rm -f

y luego ejecuto el docker-compose upcomando para que la nueva versión aparezca en la pantalla como se esperaba.

¿Es este comportamiento previsto de docker-compose? es decir, ¿debería hacer siempre una docker-compose rm -fantes de ejecutar de upnuevo, incluso en servidores de producción? ¿O estoy haciendo algo en contra de la corriente aquí, por eso no está funcionando?

El objetivo es que nuestro proceso de compilación compile y cree versiones etiquetadas de las imágenes necesarias en un docker-compose.yml, las envíe a nuestro registro privado y luego, para el "paso de lanzamiento a producción", simplemente copie el docker-compose. yml al servidor de producción y ejecute a docker-compose pull && docker-compose -f docker-compose.yml up -dpara que la nueva imagen comience en producción. Si alguien tiene consejos sobre esto o puede señalar un tutorial de mejores prácticas para este tipo de configuración, también sería muy apreciado.

Jens Wegar
fuente
1
docker-compose up -d --force-recreateno funcionó?
BMitch
Para evitar el riesgo de pérdida de datos al eliminar o recrear contenedores, utilice un host o un volumen con nombre. Parece que ya está utilizando volúmenes de host para los otros contenedores. Un volumen con nombre vacío se inicializará con el contenido del volumen de la imagen cuando lo use por primera vez.
BMitch
--force-recreated no funcionó, no :( Estoy usando volúmenes para el almacenamiento de datos, por lo que la parte de pérdida de datos tal vez no sea tan relevante. Pero todavía estoy confundido por tener que hacer una rm de docker-compose antes reiniciar los contenedores. ¿No debería el comando up,, especialmente con force-recreate, encargarse de notificar una nueva imagen y usarla en su lugar? Se siente mal que tenga que forzar una eliminación en un servidor de producción
Jens Wegar
Si --force-recreateno está recreando los contenedores, es posible que deba presentar un informe de error en docker-compose. Tenga en cuenta que usar una nueva imagen sería recrear el contenedor, lo que lo eliminaría. Y si no elimina ningún volumen específico del contenedor en el proceso, puede obtener una lista bastante larga de datos que nunca volverá a usar docker volume ls -f dangling=true. Entonces, su solución es la primera mitad de lo que Docker-compose debería hacer por usted.
BMitch
¡Ok, gracias! Tendré que jugar un poco más para asegurarme de que entiendo el proceso (todavía soy un novato cuando se trata de Docker), pero parece que docker-compose rm -f antes de compilar es lo que tendré que hacer entonces.
Jens Wegar

Respuestas:

65

Para asegurarse de que está utilizando la última versión para su :latestetiqueta de su registro (por ejemplo, Docker Hub), también debe extraer la última etiqueta nuevamente. en caso de que cambie, el diff se descargará y se iniciará cuando docker-compose upvuelva a hacerlo .

así que este sería el camino a seguir:

docker-compose stop
docker-compose rm -f
docker-compose pull   
docker-compose up -d

pegué esto en una imagen que ejecuto para iniciar la composición de docker y asegurarme de que las imágenes se mantengan actualizadas: https://hub.docker.com/r/stephanlindauer/docker-compose-updater/

Stephanlindauer
fuente
27
docker-compose pull && docker-compose up -des suficiente. Verifica automáticamente si los contenedores en ejecución están desactualizados y, si ese es el caso, los recrea con las imágenes más recientes
Mindaugas Varkalys
@MindaugasVarkalys, su comentario debería haber sido la respuesta aceptada, señor. Funciona a las mil maravillas.
Yuriy Pozniak
36

Para obtener las imágenes más recientes, use docker-compose build --pull

Utilizo el siguiente comando que es realmente 3 en 1

docker-compose down && docker-compose build --pull && docker-compose up -d

Este comando detendrá los servicios, extrae la última imagen y luego inicia los servicios.

Abhishek Galoda
fuente
Tal vez debería agregar docker-compose pullpara actualizar imágenes para servicios con image: en lugar de build: in docker-compose.ymlo ¿ docker-compose build --pullhará esto?
oceanBT
Obtengo nginx uses an image, skippingcuando uso docker-compose build --pull Por lo tanto, no se actualizan las imágenes.
Antonio Araujo
23

Para cerrar esta pregunta, lo que parecía haber funcionado es efectivamente

docker-compose stop
docker-compose rm -f
docker-compose -f docker-compose.yml up -d

Es decir, retire los contenedores antes de ejecutar de upnuevo.

Lo que hay que tener en cuenta al hacerlo así es que los contenedores de volumen de datos también se eliminan si se ejecuta rm -f. Para evitar que especifique explícitamente cada contenedor para eliminar:

docker-compose rm -f application nginx php

Como dije en mi pregunta, no sé si este es el proceso correcto. Pero esto parece funcionar para nuestro caso de uso, así que hasta que encontremos una mejor solución, seguiremos con esta.

Jens Wegar
fuente
¿Qué sucede si desea volver a la versión anterior del contenedor? ¿Enjuagar, repetir?
EightyEight
1
No lo he probado pero eso sí, asumo tanto. Dado que la versión del contenedor debe definirse en docker-compose.yml (por ejemplo, myimage: 2.0.1), si desea revertir, actualizaría docker-compose.yml a la versión a la que desea revertir (por ejemplo, 2.0 .0) y luego repita el mismo proceso de enjuague nuevamente.
Jens Wegar
Si quiero revertir, simplemente revierto el compromiso, dejo que docker hub se compile y luego espere a que el actualizador lo recoja. probablemente no sea el sistema más elaborado, pero funciona para mis proyectos de tiempo libre.
stephanlindauer
Eliminar todo no parece una solución sino más bien dudosa.
PierrickM hace
3

He visto que esto ocurre en nuestro sistema de producción de Docker 7-8. Otra solución que funcionó para mí en producción fue ejecutar

docker-compose down
docker-compose up -d

esto elimina los contenedores y parece hacer 'up' para crear nuevos a partir de la última imagen.

Esto todavía no resuelve mi sueño de bajar + subir por CADA contenedor cambiado (en serie, menos tiempo de inactividad), pero funciona para forzar 'arriba' para actualizar los contenedores.

Danku
fuente
docker-compose downafaik también elimina cualquier contenedor de volumen de datos vinculado a los contenedores en ejecución. Entonces, no hay problema si los volúmenes de datos solo contienen cosas que se pueden volver a crear desde un contenedor en ejecución. Pero debe tener cuidado si los volúmenes contienen datos que desea conservar.
Jens Wegar
downelimina, por defecto y el documento actual: contenedores, redes y redes por defecto. Doc dice "Las redes y los volúmenes definidos como externos nunca se eliminan". Funciona para mí con volúmenes con nombre (y supongo que eso también es cierto para las redes con nombre).
arminfro
3

Opción downresolver este problema

Ejecuto mi archivo de redacción:

docker-compose -f docker/docker-compose.yml up -d

luego borro todo con down --rmi all

docker-compose -f docker/docker-compose.yml down --rmi all

Stops containers and removes containers, networks, volumes, and images
created by `up`.

By default, the only things removed are:

- Containers for services defined in the Compose file
- Networks defined in the `networks` section of the Compose file
- The default network, if one is used

Networks and volumes defined as `external` are never removed.

Usage: down [options]

Options:
    --rmi type          Remove images. Type must be one of:
                        'all': Remove all images used by any service.
                        'local': Remove only images that don't have a custom tag
                        set by the `image` field.
    -v, --volumes       Remove named volumes declared in the `volumes` section
                        of the Compose file and anonymous volumes
                        attached to containers.
    --remove-orphans    Remove containers for services not defined in the
                        Compose file
Slavik Muz
fuente
2

Pasé medio día con este problema. La razón fue que asegúrese de verificar dónde se registró el volumen.

volúmenes: - api-data: / src / patterns

Pero el caso es que en este lugar estaba el código que cambiamos. Pero al actualizar la ventana acoplable, el código no cambió.

Por lo tanto, si está verificando el código de otra persona y por alguna razón no está actualizando, verifique esto.

Y así, en general, este enfoque funciona:

docker-compose abajo

compilación de docker-compose

docker-compose up -d

user8928128
fuente
0

La documentación de docker-compose para el comando 'up' establece claramente que actualiza el contenedor en caso de que se cambie la imagen desde que se realizó el último 'up':

Si existen contenedores para un servicio y la configuración o la imagen del servicio se modificó después de la creación del contenedor, docker-compose up recoge los cambios deteniendo y recreando los contenedores (preservando los volúmenes montados).

Entonces, al usar 'detener' seguido de 'tirar' y luego 'subir', esto debería evitar problemas de pérdida de volúmenes para los contenedores en ejecución, excepto, por supuesto, para los contenedores cuyas imágenes se han actualizado.

Actualmente estoy experimentando con este proceso e incluiré mis resultados en este comentario en breve.

Paul Pritchard
fuente
0

Si la configuración de composición de la ventana acoplable está en un archivo, simplemente ejecute:

docker-compose -f appName.yml down && docker-compose -f appName.yml pull && docker-compose -f appName.yml up -d
njeru
fuente
-3

Estoy usando el siguiente comando para obtener las últimas imágenes

sudo docker-compose down -rmi all

sudo docker-compose up -d

illum1n4ti
fuente