Compose: Cómo `docker-compose up --force-recreate` sin reutilizar volúmenes anteriores

Creado en 2 oct. 2015  ·  23Comentarios  ·  Fuente: docker/compose

Con docker-compose 1.4.2 y docker 1.8.2
Puede ver a continuación el primer volumen e583c6a8 ... 5a93788a0 se reutiliza

 $ sudo docker-compose up -d --force-recreate
   Recreating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data:/home/transmission/.config/transmission-daemon:rw",
   "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data:/home/transmission/Downloads:rw"
   "Source": "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data",
   "Source": "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data",

 $ sudo docker-compose up -d --force-recreate
   Recreating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data:/home/transmission/.config/transmission-daemon:rw",
   "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data:/home/transmission/Downloads:rw"
   "Source": "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data",
   "Source": "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data",

Me veo obligado a stop luego rm para crear algunos volúmenes nuevos

 $ sudo docker-compose stop 
   Stopping remotetransmission_torrent_1... done

 $ sudo docker-compose rm
   Going to remove remotetransmission_torrent_1
   Are you sure? [yN] y
   Removing remotetransmission_torrent_1... done

 $ sudo docker-compose up -d --force-recreate
   Creating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "Source": "/mnt/docker/volumes/c5bb9a8f7b68c762c42e9c0ee92afbca3aa0d7ff9d09aaf45fd260f6fc663ec9/_data",
   "Source": "/mnt/docker/volumes/9dcce8440bafc8893e07352111d1aefb625c36df10da6dc4eaa593220266ea31/_data",

_
¿Existe una forma mejor que el método stop/rm ?

areup kindocs kinquestion

Comentario más útil

Esta política parece violar las mejores prácticas de Docker y nos ha causado _ toneladas_ de dolores de cabeza en la resolución de problemas por qué la recreación de contenedores tenía un estado de fuga. Cuando le digo a Docker que vuelva a crear, eso no significa "conservar algunos datos en las ejecuciones del contenedor, sino reiniciar los procesos en los contenedores". Significa pavimentar la tierra y empezar de nuevo. Si quisiera guardar los volúmenes, los montaría explícitamente. Yo _nunca_ espero que los volúmenes auto-montados de ningún tipo persistan en las ejecuciones de contenedores.

Todos 23 comentarios

stop/rm es la forma correcta. Los datos en volúmenes pueden ser importantes, por lo que queremos que sea difícil eliminarlos accidentalmente.

Probablemente podríamos documentar esto un poco mejor.

Esta política parece violar las mejores prácticas de Docker y nos ha causado _ toneladas_ de dolores de cabeza en la resolución de problemas por qué la recreación de contenedores tenía un estado de fuga. Cuando le digo a Docker que vuelva a crear, eso no significa "conservar algunos datos en las ejecuciones del contenedor, sino reiniciar los procesos en los contenedores". Significa pavimentar la tierra y empezar de nuevo. Si quisiera guardar los volúmenes, los montaría explícitamente. Yo _nunca_ espero que los volúmenes auto-montados de ningún tipo persistan en las ejecuciones de contenedores.

La persistencia de datos entre ejecuciones es realmente la única razón para usar volúmenes. Si no desea datos persistentes, ¿por qué los pone en un volumen?

No estoy configurando un volumen. Mi docker-compose.yml no tiene ninguna configuración de volúmenes y no paso nada a docker-compose.yml para adjuntar ningún volumen.

Mando:

docker-compose up --force-recreate --abort-on-container-exit --build foo

docker-compose.yml:

version: '2'
services:
  foo:
    build:
      context: .
      dockerfile: src/integration/foo/Dockerfile
    ports:
      - "3306:3306"
      - "33060:33060"

Dockerfile:

FROM mysql:5.7

COPY schema/foo/migration.sql /data/db_schema.sql
COPY src/integration/foo/create_test_db.sh /docker-entrypoint-initdb.d/create_test_db.sh
ENV MYSQL_ALLOW_EMPTY_PASSWORD true

EXPOSE 3306 33060

create_test_db.sh:

#!/bin/bash
set -e
mysql --no-defaults -u root -e "drop database if exists agent_state; create database foo"
mysql --no-defaults -u root foo < "/data/db_schema.sql"

Si ejecuto lo anterior, escribo algunas cosas en la base de datos, luego SIG_INT, luego ejecuto el comando nuevamente, los datos que puse en la base de datos se conservan durante la ejecución.

Eso es un problema con la imagen de MySQL. Crea un volumen en la base
imagen. Puede solucionar el problema utilizando un MySQL diferente
imagen o posiblemente forzándolo a usar una ruta diferente para los datos.

El 19 de octubre de 2016 a las 6:36 p.m., "Micah Zoltu" [email protected] escribió:

No estoy configurando un volumen. Mi docker-compose.yml no tiene ninguna
configuración de volúmenes y no paso nada a docker-compose.yml a
adjunte cualquier volumen.

Mando:

docker-compose up --force-recreate --abort-on-container-exit --build foo

docker-compose.yml:

versión 2'
servicios:
foo:
construir:
contexto:.
dockerfile: src / integration / foo / Dockerfile
puertos:
- "3306: 3306"
- "33060: 33060"

Dockerfile:

DESDE mysql: 5.7

COPIA esquema / foo / migration.sql /data/db_schema.sql
COPIA src / integration / foo / create_test_db.sh /docker-entrypoint-initdb.d/create_test_db.sh
ENV MYSQL_ALLOW_EMPTY_PASSWORD verdadero

EXPONER 3306 33060

create_test_db.sh:

! / bin / bash

set -e
mysql --no-defaults -u root -e "eliminar la base de datos si existe agent_state; crear la base de datos foo"
mysql --no-defaults -u root foo <"/data/db_schema.sql"

Si ejecuto lo anterior, escribo algunas cosas en la base de datos, luego SIG_INT, luego ejecuto el
comando de nuevo, los datos que puse en la base de datos se conservan durante la ejecución.

-
Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/docker/compose/issues/2127#issuecomment -254986952,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AAa_RG_pJj0i-OSCfcBlG__8ToFDtGKMks5q1sWlgaJpZM4GHruC
.

Mmm, esto viola mi comprensión de los contenedores Docker. ¿Cómo se monta un volumen sin que yo proporcione una ruta en el host? Tengo entendido que los contenedores de la ventana acoplable son efímeros a menos que monte explícitamente un volumen.

Un volumen no necesita una ruta de host. Hay tres tipos de volúmenes:

  • montajes de enlace de host ( -v /host:/container )
  • volúmenes con nombre ( -v name:/container , creados con docker volume create )
  • volúmenes anónimos ( -v /container , o VOLUME dentro de un Dockerfile )

La imagen de mysql usa un volumen anónimo. En tiempo de ejecución, puede decirle al contenedor que use un volumen diferente para esa ruta en el contenedor, pero si no lo hace, el volumen anónimo todavía está allí.

Los volúmenes anónimos no son buenos. Son los más antiguos de los tres, y gran parte de su comportamiento es material heredado que solo se conserva por razones de compatibilidad con versiones anteriores.

Al menos alguna opción de línea de comando a la "--recreate-volume" estaría bien ...

Bien, chicos, este es el caso en el que pensar:

1) Quiero volver a montar mi directorio público de Rails en el contenedor nginx, para que nginx pueda servir algunas cosas estáticas directamente.
2) Asigno un volumen "anónimo" (no montado en el host, sin nombre) a / usr / local / app / app / public y lo comparto con nginx a través de "volume_from"
3) el contenido "público" a menudo se cambia en las compilaciones de imágenes, no solo archivos de nivel superior, sino también algunos archivos en subdirectorios (esto es importante)

Actualmente, si vuelvo a crear contenedores, termino con una versión anterior de "público": el contenido de la imagen simplemente se ignora. Sí, se supone que Docker copia los archivos que

Por lo tanto, me veo obligado a realizar la secuencia "stop-rm-up" (no tan conveniente en producción), oa usar un directorio separado como un volumen compartido, y llamar explícitamente a 'rsync' en el inicio del contenedor de la aplicación para completarlo / actualizarlo.

Si hubiera una forma de permitir que el volumen anónimo vaya junto con el contenedor principal, sería una gran mejora.

No use volúmenes para código (o activos estáticos). Los volúmenes son para los datos que desea conservar entre implementaciones, que es lo contrario de lo que desea aquí. Cree la imagen nginx con los activos estáticos o utilice el proxy de algún contenedor de servidor web que los contenga.

¡Gracias por el mirador! Todavía no pensaba desde esta perspectiva.

Parece ser uno de los problemas conceptuales con la arquitectura Docker (aún en evolución). Vimos la evolución del concepto de volúmenes de datos hasta ahora (por ejemplo, de "contenedores de datos" a "volúmenes con nombre") y probablemente aún no esté terminado.

Si consulta https://docs.docker.com/engine/tutorials/dockervolumes/#/data -volumes, verá que la mayoría de los beneficios descritos (omitir AUFS, compartir) no están necesariamente conectados a la persistencia de datos ( para qué volúmenes fueron diseñados originalmente).

Por lo tanto, no es de extrañar que la gente (incluyéndome a mí) esté tratando de utilizar los volúmenes de diversas formas más allá de su propósito original. Por ejemplo, para compartir datos efímeros o controlados por imágenes de un contenedor a otro, sin muchas copias explícitas.

Tal vez algún día descubramos la forma estándar consistente de hacerlo. :) Hasta ahora, es posible utilizar algunas soluciones alternativas bastante simples descritas anteriormente. No es ideal, pero aceptable, siempre que las expectativas arquitectónicas se establezcan correctamente.

Una vez más, gracias por tu respuesta, aclaración y por el gran trabajo que estás haciendo.

Me encontré con este problema hoy, gracias por las excelentes explicaciones aquí a todos, definitivamente me ha ayudado a comprender el problema.

Un punto importante de confusión para mí fue entender que la etiqueta VOLUME en un archivo docker hace que se cree un volumen anónimo consistente. Es posible que me lo haya perdido en la documentación, pero no pude encontrar ninguna mención.

@dnephin

Como mencioné @ hleb-rubanau. ¿Ejecutar un solo contenedor con Rails y Nginx es la solución? (Como esto: https://docs.docker.com/engine/admin/multi-service_container/?)

¿Debo romper las mejores prácticas ("Cada contenedor debe tener una sola preocupación
") solo para porciones de activos? :(

Para los interesados, terminé con lo siguiente:

1) En mis configuraciones, ahora siempre uso volúmenes montados en enlace (también conocidos como montados en host). Los volúmenes anónimos y con nombre tienen demasiada lógica especial / no obvia / condicional / inconsistente / implícita para tener en cuenta. Sí, es fácil comprender los aspectos específicos del ciclo de vida y la gestión de cada tipo, pero descubrí que es más fácil para mí pensar en la arquitectura cuando no me preocupan todas esas diferencias irrelevantes. Para FS distribuido, Gluster funciona bien (aún está montado en enlace desde la perspectiva de Docker).

2) volumen compartido es bind-montado uno, y no es el directorio donde se almacenan los activos en la imagen. Al principio (en el punto de entrada) estoy ejecutando rsync local, de modo que los activos del directorio de la imagen se copian / rsynced a la ruta de almacenamiento compartido montado en enlace.

Gracias @ hleb-rubanau

De todos modos, no estoy seguro de si algunas herramientas de orquestación como RancherOS admiten esas configuraciones de volumen o si es la forma correcta de escalar. Al final, es más difícil implementar con Docker ...

Prefiero usar volúmenes anónimos y limpiar a los huérfanos en algún momento.

Esta es mi pila de rieles de producción: https://github.com/brunocascio/AR-MTB/blob/master/docker-compose.prod.yml

Esto también me causó una gran confusión cuando estaba probando la imagen de jenkins / jenkins y no estaba respetando mis cambios de los archivos en / usr / share / jenkins / ref porque ya los había copiado.

Esa es una experiencia de usuario bastante inesperada: docker compose está creando un volumen "oculto" para todos los efectos. Si usa docker run normales, obtendrá un nuevo volumen cada vez. Es un volumen oculto en el sentido de que nada en el docker-compose up habla de él, por lo que, a menos que sepa en detalle lo que hace la imagen, debe ir investigando.

Como mínimo, deberíamos imprimir un mensaje que diga "no volver a crear el volumen x" para que otras personas en el futuro no tengan que perder el tiempo preguntándose qué está sucediendo.

Hola @dnephin ,

Llamo a sudo rm -rf /var/lib/docker/volumes/aa_dbdatavol y ahora ya no puedo docker-compose up my postgres docker-compose .

Obteniendo este error

Creando red "aa_default" con el controlador predeterminado
Creando aa_postgres_1
ERROR: para postgres no se puede crear un contenedor para el servicio postgres: no existe tal archivo o directorio
ERROR: Se encontraron errores al abrir el proyecto.
Respuesta de error del demonio: No existe tal contenedor: aa_postgres_1

Como puede tener alguna idea para solucionarlo, por favor comparta. ¡Gracias!

https://github.com/docker/compose/issues/2127#issuecomment -347152650

Simplemente volver a crear la carpeta solucionará mi problema.
/var/lib/docker/volumes/aa_dbdatavol/_data

Muchas gracias a tu respuesta funcionó perfectamente, la primera vez. Muchos gracias.

@dnephin dijo:

La persistencia de datos entre ejecuciones es realmente la única razón para usar volúmenes. Si no desea datos persistentes, ¿por qué los pone en un volumen?

para compartir archivos entre contenedores. ¿Existe una mejor manera de hacerlo sin usar volúmenes?

¿Qué quieres decir con "compartir archivos"?

¿Espera que un contenedor escriba en un archivo y el otro contenedor vea esas escrituras? Un sistema de archivos generalmente no es una buena interfaz entre dos servicios, pero si ese es el caso, podría hacer que uno de los servicios "administre" el sistema de archivos escribiendo actualizaciones en el volumen.

Si "compartir" es solo que dos contenedores leen algunos de los mismos archivos, entonces no hay necesidad de un volumen. Agregue el archivo a ambos contenedores con COPY .

Estoy usando Docker version 18.06.1-ce, build e68fc7a y puedo usar el siguiente comando para recrear volúmenes anónimos:

docker-compose up -d --build --force-recreate --renew-anon-volumes db

Parece que la bandera --renew-anon-volumes se agregó recientemente

Estoy usando Docker version 18.06.1-ce, build e68fc7a y puedo usar el siguiente comando para recrear volúmenes anónimos:

docker-compose up -d --build --force-recreate --renew-anon-volumes db

Parece que la bandera --renew-anon-volumes se agregó recientemente

Gracias por dejar esta opción.

¿Fue útil esta página
0 / 5 - 0 calificaciones