Compose: docker-compose copiar archivo o directorio al contenedor

Creado en 1 ene. 2018  ·  141Comentarios  ·  Fuente: docker/compose

perdemos la posibilidad de copiar un archivo o directorio usando docker-compose. Encuentro esto realmente útil.
Marque muchos +1 en https://github.com/docker/compose/issues/2105 cerrados prematuramente

kinfeature statu0-triage

Comentario más útil

¿De qué sirve insistir dogmáticamente en que es un antipatrón, solo porque en _algunos_ casos_ podría _ eventualmente_ causar problemas? Esto definitivamente tiene un buen uso, ya que podría agregar una línea a un archivo existente, en lugar de tener que crear una carpeta y un archivo adicionales, y luego mover el archivo para agregarlo allí. Esta creación burocrática y sin sentido de archivos diminutos es el verdadero antipatrón, que evita que los usuarios creen archivos de composición acoplable simples y fáciles de mantener.

Si los usuarios quieren hacer cosas dañinas con Docker, encontrarán la manera sin importar lo que haga. Negarse a agregar funciones legítimas solo porque alguien puede hacer un mal uso de ellas algún día es una tontería.

Todos 141 comentarios

¿Cuál es el caso de uso? La mayor parte del uso sugerido que he visto fueron antipatrones.

Puede ver algunos de los muchos casos de uso haciendo clic en el enlace proporcionado. Como puede ver, muchos de los suscriptores lo consideran una función realmente útil en lugar de "antipatrón".

Vaya, ahora veo que sucedió "algo" con el número 2105 porque ya no hay comentarios ...
Quizás proporcioné un enlace incorrecto ...

entonces, encuentro realmente útil copiar algunos archivos de configuración / inicialización al contenedor. Como ejemplo, algunas cosas * .sql para contenedores db, algo de contenido html / js / css para contenedores apache / nginx o incluso un archivo jar para contenedores java. Esto hará que esté disponible / ejecutable "globalmente" no solo en la máquina donde se compuso como en el caso de los volúmenes de montaje. Principalmente, se tratará de una combinación de archivos locales de host y archivos contenidos en contenedores. De hecho, cualquier contenedor puede considerarse inútil sin ninguna configuración o inicialización.

este es el enlace correcto: https://github.com/docker/compose/issues/1664

+1

Esto hará que esté disponible / ejecutable "globalmente" no solo en la máquina donde se compuso como en el caso de los volúmenes de montaje.

El problema con esto es que es increíblemente miope (de ahí el término "anti-patrón"), ya que te obligará a repetir la operación cada vez que los contenedores sean recreados. Sin mencionar el hecho de que se escala muy mal (¿y si tiene 10 contenedores? ¿20? ¿100?)

La solución real a su problema es incluir esos archivos necesarios en su compilación (Dockerfile) y reconstruir cuando sea necesaria una actualización.

por supuesto, si está compuesto incluyendo todo el contenido "compartido" en un contenedor, escalar 10-20-100- contenedores sería mucho más fácil. Todo lo que necesita es sacarlo del repositorio y montar (sí, en este caso montar) solo la configuración específica del nodo. Y aún más, no necesita ejecutar docker-compose en cada nodo.
Claro que podemos usar docker-compose en combinación con build: & Dockerfile, sin embargo, las cosas se vuelven un poco más complejas y la configuración de yaml en docker-compose es mucho más "elegante": o)

Me encuentro con un problema en el que la copia sería útil (al menos como anulación). Principalmente desarrollo en mac, por lo que casi nunca veo un problema con los comandos que se ejecutan como root en el contenedor y se exportan a un volumen montado. Sin embargo, el uso reciente del mismo flujo de trabajo en CentOs ha causado un gran problema porque los archivos propiedad del usuario raíz se agregan al host a través del volumen montado. En estos casos, me gustaría poder copiar los archivos del host al contenedor en lugar de montarlos.

El problema relacionado: # 1532

actualizar

Creo que, en mi caso, puedo usar COPY en el Dockerfile y tener varios archivos de composición de docker, uno de los cuales usa un montaje de volumen.

Caso de uso:
Quiero usar el directorio del sistema de archivos de solo lectura dentro del contenedor. La aplicación crea nuevos archivos en ese directorio, pero debido a que el sistema de archivos es de solo lectura, esto causa errores.

No puedo usar el volumen rw porque el sistema de archivos es de solo lectura.
No puedo usar el volumen ro, porque el efecto será el mismo.

Sería increíble hacer escrituras que persisten solo cuando se ejecuta el contenedor. Puedo hacer envoltorio (https://stackoverflow.com/questions/36362233/can-a-dockerfile-extend-another-one) a solo COPY archivos, pero haciendo esto en componer, similar a volume , sería mejor

Caso de uso: iniciar varios contenedores de docker simultáneamente desde .gitlab-ci.yml que deben escribir en el directorio del repositorio de git.

Si el proceso dentro de un contenedor falla o si el trabajo ci se cancela antes de que el contenedor se haya limpiado después de sí mismo, gitlab-runner no puede eliminar los archivos restantes debido a la falta de permisos. Ahora podría copiar los archivos dentro del contenedor fuera del volumen a otro directorio, pero eso sería un antipatrón, ¿no?

¿Es esto diferente de volumes: - ./folder_on_host/ :/folder_in_container/ ?
Puedo copiar archivos desde el host al contenedor (equivalente a COPY) de esta manera en mi archivo de redacción

@harpratap tienes razón, pero el inconveniente es que / folder_in_container no debe existir o debe estar vacío o de lo contrario se sobrescribirá. Si tiene un script bash como punto de entrada, puede evitar esto enlazando sus archivos en el directorio originalmente previsto después de crear un volumen en / some_empty_location

+1 por tener una función COPIA. Nuestro caso de uso es para poner en marcha rápidamente entornos de desarrollo local y copiar configuraciones para los ajustes de desarrollo.

+1 para COPIA. Esta sería una característica realmente útil.

Caso de uso: en modo de enjambre, tengo un servicio que usa la imagen de mysql. Necesito copiar mi secuencia de comandos de inicialización en /docker-entrypoint-initdb.d/ para que MySQL pueda ejecutarlos.

Aunque es posible crear una imagen encima de mysql, copie los archivos y utilícelos o conéctese a mysql
tarea en enjambre y luego ejecutar manualmente los scripts, es algo innecesario en mi opinión.

+1 para COPIAR / AÑADIR,

Caso de uso:
Fluentd requiere que los archivos de configuración se muevan al contenedor durante el tiempo de ejecución. Estos archivos de configuración son creados en tiempo de ejecución por nuestro motor Jenkins y sin COPY / ADD en la ventana acoplable, simplemente falla.

+1 para COPIA

Supongamos que uno tiene un archivo de configuración compartido en varias máquinas acoplables, con sus archivos Docker en los subdirectorios respectivos bajo el directorio docker-compose. ¿Cómo copia esa configuración compartida en cada imagen? No puedo vincular simbólicamente a ../ desde el contexto de Dockerfile sin obtener COPY failed: Forbidden path outside the build context

En este caso, al ejecutar la compilación de docker-compose, me gustaría copiar los archivos de configuración del contexto de docker-compose antes de ejecutar los pasos de compilación de docker.

Estoy feliz si alguien puede sugerir una solución limpia, por supuesto.

¡Sería bueno tener esta característica!

No comentes con solo +1, es una pérdida de tiempo para todos. Si tiene información adicional que proporcionar, hágalo; de lo contrario, simplemente agregue un pulgar hacia arriba al problema original.

¿De qué sirve insistir dogmáticamente en que es un antipatrón, solo porque en _algunos_ casos_ podría _ eventualmente_ causar problemas? Esto definitivamente tiene un buen uso, ya que podría agregar una línea a un archivo existente, en lugar de tener que crear una carpeta y un archivo adicionales, y luego mover el archivo para agregarlo allí. Esta creación burocrática y sin sentido de archivos diminutos es el verdadero antipatrón, que evita que los usuarios creen archivos de composición acoplable simples y fáciles de mantener.

Si los usuarios quieren hacer cosas dañinas con Docker, encontrarán la manera sin importar lo que haga. Negarse a agregar funciones legítimas solo porque alguien puede hacer un mal uso de ellas algún día es una tontería.

Creo que lo que estás haciendo es en realidad la forma correcta de hacerlo, en este caso.

El problema que se planteó aquí fue más bien, supongamos que el archivo mongo.conf se compartió entre tres imágenes de la ventana acoplable que están orquestadas por un archivo de composición acoplable. ¿Cómo se asegura de que sea el mismo en cada subdirectorio de compilación de Docker?

Si usa enlaces simbólicos, por ejemplo, la ventana acoplable se queja de que el archivo es externo al entorno de compilación, por ejemplo, la compilación de la ventana acoplable carece de un sentido de reproducibilidad ya que las modificaciones fuera de ese directorio podrían alterar la compilación.

Entonces, la única forma de orquestar esto es con una copia de archivo, que actualmente se necesita hacer con un archivo Makefile o un script de shell antes de ejecutar docker-compose, por lo que parecía una idea discutir si esta era una característica que docker-compose podría hacer, ya que seguramente es un caso de uso común.

El problema que está planteando parece ser más sobre la inyección en tiempo de ejecución (tiempo de inicio) de una modificación de archivo local.

Creo que en realidad estás bien en lo que estás haciendo, lo que dijiste anteriormente es cómo se hace. Una imagen de la ventana acoplable siempre se puede construir para aceptar variables de entorno para responder preguntas como dónde está el directorio de configuración y ese directorio de configuración se puede "inyectar" usando un volumen en tiempo de ejecución, pero eso depende del diseño de la imagen de la ventana acoplable, aprovechando variables de entorno y asignaciones de volumen (que son características que Docker admite como modificación de configuración de tiempo de ejecución).

Espero no haber malinterpretado su comentario y que mi respuesta sea útil.

@jpz - De alguna manera borré mi comentario original - ¡Ay! - ¡Lo siento! Gracias, sí, eso es útil.

Mi comentario original fue en la línea de:

Mi caso de uso es que quiero declarar un servicio usando mongo sin tener que crear mi propia imagen personalizada solo para copiar un archivo de configuración como /etc/mongod.conf .

ACTUALIZACIÓN: Usé volumes . Hace uno o dos años, pensé que había intentado esto con una mala experiencia ... pero parece estar bien.

+1 para COPIA

Creé un resumen rápido para esto. Se asume que el servicio de composición de la ventana acoplable se llama phpfpm , sin embargo, puede cambiar esto a lo que desee. siéntete libre de modificar.
https://gist.github.com/markoshust/15efb29aa5eebf8adae402af18b2e674

Hola, me gustaría saber cómo está el progreso de este tema. Ahora, estoy usando Windows 10 Home con Docker-Toolbox. Parece principalmente un error cuando trato de combinar el archivo de montaje como un volumen en el contenedor. Sería bueno tener capacidades de COPIA en docker-compose

COPY / ADD definitivamente sería una característica bienvenida.

Un caso de uso: ejecutar una instancia de Graylog en Docker para fines de desarrollo. Para lanzar una entrada automáticamente, se debe colocar una especificación JSON en / usr / share / graylog / data / contentpacks
Con la función COPIAR / AGREGAR, será tan fácil como una sola línea en YML.

Para que funcione ahora (el 16 de octubre de 2018), es necesario montar un volumen en ese punto Y copiar el contenido original de esa carpeta en el volumen persistente. Lo cual es un inconveniente silencioso.

Me beneficiaría de eso, tengo un conjunto de herramientas que importan una semilla de base de datos en un contenedor y luego ejecuto el importador de base de datos devtools basado en ese archivo. No quiero tener que hacer:

docker cp "${seed_file}" $(docker-compose ps -q devtools):/tmp/seed_file

para poder importar mi semilla. Y no, no compilaré mis imágenes de desarrollo con un esquema fijo, esto va en contra del patrón de desarrollo web al menos. Los contenedores deben ser para la portabilidad de aplicaciones, no para datos.

Tendría mucho más sentido hacer:

docker-compose cp "${seed_file}" devtools:/tmp/seed_file

Con todo, es solo una abreviatura que básicamente hace lo mismo, pero parece mejor aprovechar docker-compose todas partes que mezclar cosas ...

1) esto parece ser un duplicado de # 3593
2) estoy de acuerdo con @ shin- que los casos de uso elaborados siguen un anti-patrón
3) pero concluir el comando cp Docker tiene sentido, en mi opinión

@funkyfuture Si cree que estos casos de uso siguen un antipatrón, sugiera una solución que no lo haga.

¿Qué pasa con la "sección de datos" similar a k8s ?
Por ejemplo:

services:
  service1:
    image: image.name
    data:
      filename1.ini: |
        [foo]
        var1=val1
        [bar]
        var2=val2
      filename2.yml: |
        foo:
          bar: val1

o quizás lo mismo, pero para la sección volumes:

volumes:
  service_config:
    data:
      filename1.ini: |
        [foo]
        var1=val1
        [bar]
        var2=val2

services:
  service1:
    image: image.name
    volumes:
      - service_config:/service/config

@espinilla-

El problema con esto es que es increíblemente miope (de ahí el término "anti-patrón"), ya que te obligará a repetir la operación cada vez que los contenedores sean recreados. Sin mencionar el hecho de que se escala muy mal (¿y si tiene 10 contenedores? ¿20? ¿100?)

El problema real aquí es que algunas personas se apresuran a disolver las características solicitadas porque entra en conflicto con su visión limitada de los escenarios de casos de uso reales.

Aquí estoy buscando una forma de copiar mi archivo de configuración en un contenedor que acabo de obtener de dockerhub. No tengo acceso al Dockerfile original y sería muy conveniente tener esta función (en lugar de intentar construir otra capa en la parte superior, que funcionaría, pero es un inconveniente, no quiero reconstruir cuando cambio algo).

Caso de uso:

Ejecuto una base de datos en un entorno de prueba de integración y quiero que los datos se restablezcan en cada iteración, cuando se inician los contenedores. Incrustar los datos en una imagen personalizada funcionaría, pero montar un volumen es engorroso, porque los datos en el host deben restablecerse.

Mantenemos los datos de forma independiente y sería más conveniente usar la imagen estándar de la base de datos, copiar los datos antes de que comience a ejecutarse. Actualmente, esto no parece ser posible con docker-compose.

Tengo un caso de uso en mente. Quiero basar mi imagen en una imagen estándar, como un servidor Apache genérico. Quiero copiar mi html durante la creación de la imagen. De esa manera puedo actualizar mi imagen base cuando quiera y la directiva de copia asegurará que mi contenido esté incluido en la nueva imagen.

Por cierto, actualmente uso dockerfiles y una directiva de compilación en mi docker-compose.yaml para hacer esto. Sería bueno si no necesitara los archivos de la ventana acoplable.

@tvedtorama -

Caso de uso:

Ejecuto una base de datos en un entorno de prueba de integración y quiero que los datos se restablezcan en cada iteración, cuando se inician los contenedores. Incrustar los datos en una imagen personalizada funcionaría, pero montar un volumen es engorroso, porque los datos en el host deben restablecerse.

Mantenemos los datos de forma independiente y sería más conveniente usar la imagen estándar de la base de datos, copiar los datos antes de que comience a ejecutarse. Actualmente, esto no parece ser posible con docker-compose.

Este problema analiza el deseo de copiar archivos en el momento de la creación de la imagen, no en el tiempo de ejecución. ¿Sugeriría levantar un boleto por separado para discutir los méritos de eso? Puede confundir esta discusión para divagar y discutir la inyección de archivos en tiempo de ejecución (que interpreto de lo que estás hablando).

@ c0ze -

¿Qué pasa con la "sección de datos" similar a k8s ?
Por ejemplo:

...

No estoy completamente al tanto de lo que hace esa configuración, pero sí, parece que sería una solución. Básicamente, cuando tiene secretos (por ejemplo, cuál es el nombre de usuario / pwd / puerto de inicio de sesión a la base de datos), ¿cómo lo inyecto en mis imágenes de la ventana acoplable (clientes y servidores) sin escribir una gran cantidad de código?

Algo como la sección de datos de Kubernetes podría funcionar, ya que sería una fuente única de verdad. De lo contrario, uno puede encontrar que tienen los mismos secretos mantenidos varias veces en múltiples imágenes de docker.

También hay técnica anterior allí, que ayuda a avanzar en la conversación sobre si esta es realmente una buena idea que vale la pena adoptar o no.

Para mí, todo esto comenzó con el deseo de compartir un archivo de configuración invariante en todos los contenedores, y me di cuenta de que no había forma de hacerlo sin un script externo para docker-compose y escribiendo la configuración desde una única fuente de verdad en cada uno de las carpetas de Docker debajo de la carpeta docker-compose. Por supuesto, obtengo el argumento de inmutabilidad para Docker (por ejemplo, el directorio Dockerfile describe completa y completamente cómo construir la imagen), por lo que pedir automatización para copiar cosas en ese directorio parece que va en contra de esos principios.

Supongo que la discusión es qué tan intrusiva se permite que sea docker-compose. ¿Es este un caso de uso lo suficientemente común como para justificar dicha automatización? Si no es así, parece que cargamos los mecanismos de paso de variables de entorno con la responsabilidad de inyectar secretos de afuera hacia adentro de una sola fuente de verdad, tarde (por ejemplo, en tiempo de ejecución). Espero que mis puntos sean lo suficientemente coherentes aquí.

Esto no es de gran importancia para mí, pero creo que vale la pena discutir el caso de uso.

Me sería de gran utilidad. En el trabajo, el software antivirus bloquea la capacidad de Windows 10 para compartir volúmenes con contenedores. Es una organización enorme y es inútil hacer que cambien debido a una política establecida en otro continente.

Hola, mi caso de uso: estoy usando la configuración de Docker-compose de Prometheus de código abierto (otras personas mantienen el repositorio). Tiene configuraciones que se montan en contenedores. PROBLEMA: No puedo componer docker en una máquina remota (como aws docker-machine o dentro de CI / CD runner) porque no puede montar las configuraciones correctamente. En este caso, me gustaría copiarlos / incrustarlos. Para los datos RW hay volúmenes, para RO -?

Tener volúmenes de RO con posibilidad de establecer datos iniciales es la otra opción.

Solución actual: conéctese al host de docker a través de ssh, clone / actualice el repositorio y ejecute docker-compose up. Esto funciona para casos manuales, pero es doloroso para la automatización :(

+1

Caso de uso: tengo una máquina acoplable de desarrollo que ejecuta una base de datos y cada vez que la configuro necesito un volcado reciente de la base de datos para instalar. Efectivamente eso significa:

  1. Extraiga la imagen de la ventana acoplable de la base de datos desde el exterior.
  2. Copie y extraiga ZIP en la imagen en ejecución.
  3. Ejecute db-restore dentro del volumen.
  4. Eliminar el volcado de base de datos.

Ahora, el gran problema es que el paso 2 siempre será diferente para cada desarrollador, porque hay muchas versiones de volcado diferentes de esa base de datos, por lo que lo más fácil sería si cada desarrollador tiene su propio archivo de composición con su ubicación / versión de volcado específica, y luego Haga que la ventana acoplable ensamble la imagen con esa ubicación de archivo específica mientras se compone, que luego también se puede cambiar sobre la marcha cuando se requiere una versión diferente.

Mi caso de uso es simple. No quiero volúmenes ni quiero rodar mi propia imagen. Solo quiero poner una copia defensiva simple de un archivo de configuración en un contenedor después de que se crea y antes de que se inicie.

¿Sigue siendo un problema?
Tengo una aplicación django con un archivo de configuración muy largo. Para mí, sería mucho más fácil crear una imagen de la ventana acoplable y copiar un solo archivo de configuración en cada contenedor.
Pasar todas las configuraciones como ENV es para mí el antipatrón. Requiere mucho código, es difícil de mantener y podría resolverse con un solo comando de copia.

Abrí el # 6643 y me encantaría recibir comentarios sobre cómo se consideraría un anti-patrón. Especialmente, en un entorno en el que es posible que sea necesario agregar / modificar numerosos archivos de configuración sobre la marcha.

@espinilla-

El problema con esto es que es increíblemente miope (de ahí el término "anti-patrón"), ya que te obligará a repetir la operación cada vez que los contenedores sean recreados. Sin mencionar el hecho de que se escala muy mal (¿y si tiene 10 contenedores? ¿20? ¿100?)

¿Cómo funciona docker-compose exec con varios contenedores?

    --index=index     index of the container if there are multiple
                      instances of a service [default: 1]

¿No deberíamos intentar obtener el mismo comportamiento con cp ?

En mi humilde opinión, exec es tan efímero como lo sería cp . Pero siempre lo considero comandos de "desarrollo" de todos modos, los entornos de desarrollo deben ser efímeros, ¿no?

No había visto el comentario sobre muchos desarrolladores aquí diciendo que son miopes al intentar arreglar esto demasiado rápido solicitando esta función. Creo que esto es un poco duro y condescendiente. Si hay algo que he aprendido de mis años de desarrollo es lo siguiente:

No es lo que hace su software, es lo que hace el usuario con él lo que cuenta

Obviamente, entiendo que tienes un papel para evitar que las cosas se vuelvan locas, pero no es porque alguien use incorrectamente una herramienta basada en tu visión que todos comenzarán a hacerlo de esa manera y se desatará el infierno.

Todos los casos especiales que he visto aquí son muy apropiados la mayor parte del tiempo. Y, la mayoría de estos casos especiales no deberían y no ocurrirían en el sistema de producción, son, por ejemplo, como mi caso que expliqué hace un tiempo, para personalizar un entorno de desarrollo y ejecutar archivos especiales en un contenedor que no puede usar un mapeo de volumen. La mayoría de los ejemplos dicen claramente que no quieren hornear en esquemas, datos o archivos de configuración y no pueden usar el mapeo de volumen, así que no veo por qué esto es tanto un inconveniente como usar el término "miope".

Creo que debes ponderar cuidadosamente tus palabras al decir cosas así ...

  1. Realmente no necesito una conferencia sobre lo que puedo decir o escribir. Lamento que la "miopía" te ofenda. Todavía es correcto decir que estas cosas pertenecen al Dockerfile por diseño.
  2. Ya no soy un mantenedor. Por favor, deje de hacerme @---en cosas sobre las que ya no tengo ningún control.
  1. Tengo que decir que estoy del lado de crazycodr aquí ... Descartar casos de uso del mundo real perfectamente válidos como "anti patrón", sin dar alternativas prácticas y realistas útiles es un enfoque poco amigable para los desarrolladores y, honestamente, incluso un poco grosero.
  2. Mantenedor o no, si has participado en la parte de discusión de github, básicamente tienes que vivir con personas comentando tus comentarios. Así es como funciona. Tratar con él...

Vamos a traerlo de vuelta. Pregunta técnica honesta aquí. Con la pila de Docker tenemos una opción de "configuración". Esa es una función nativa de Docker, pero es para servicios, no para contenedores. ¿Cuál es la viabilidad de hacer que algo así funcione a nivel de contenedor en lugar de a nivel de servicio? ¿Cómo implementa la pila de Docker el aprovisionamiento de configuración? ¿Se puede replicar esa implementación específicamente para docker-compose?

Al menos la mitad de los casos de uso mencionados aquí son sobre configuraciones, por lo que muchas personas estarían satisfechas si solo se eliminara esa picazón.

Otro caso de uso simple son cosas como la validación de dominios de Google. Si usa la imagen de wordpress, no puede agregar un archivo que Google buscará. Necesitas crear una imagen completamente nueva para hacerlo.

Además, estos comentarios que dicen que las cosas son "anti-patrón" apenas tienen sentido, apestan a elitismo.

EDITAR: ay, leer más, gracias a Dios, ya no es el mantenedor

Entonces me está diciendo que si quiero copiar un pequeño archivo de configuración en una imagen prediseñada (digamos, nginx o mariadb ), ahora necesito administrar mi propia configuración de construcción de imagen y duplicar el espacio en disco utilizado (imagen original e imagen configurada)?

Esta debería ser una característica.

duplicar el espacio en disco utilizado

no lo es cuando usa Docker.

Me gusta cómo sacas una cosa de lo que dijo, que es lo más insignificante de todo. Esta debería ser una característica. Este problema simplemente crecerá y crecerá debido a que la gente llega aquí a medida que crece la ventana acoplable, ya que es un caso de uso común y la gente solo esperará que exista debido al sentido común, algo que los mantenedores anteriores y actuales parecen no tener.

Me gusta cómo sacas una cosa de lo que dijo, que es lo más insignificante de todo.

un argumento inválido debe notarse como tal.

Creo que lo que pasa aquí es que el argumento "anti-patrón" puede ser válido dada una cierta estrategia comercial (ver el punto @washtubs ). Puede que no estemos de acuerdo con esta estrategia, pero eso no justifica los ataques personales. al final, son los esfuerzos pasados ​​de @ shin-con docker-py que le permitirían implementar una alternativa a docker-compose .

¿Qué argumento "anti-patrón"? No hay ningún argumento. Es solo un "no, porque anti-patrón" sin ninguna lógica detrás, simplemente decirlo sin nada que lo respalde. Es como si las personas que lo dicen pensaran en el peor de los casos en su cabeza, decidieran que ese escenario era un anti-patrón y luego descartaron todo como tal sin siquiera escribir sobre su supuesto escenario anti-patrón.

Es solo elitismo. Muchos comentarios aquí han sido sobre cuán ridículo es el razonamiento para no agregar esto y todos se ignoran.

El sentido común y la lógica no se preocupan por sus sentimientos o elitismo. O tus anti-patrones inventados.

Sí, @robclancy , manténgalo civilizado FFS. Quiero esta función, pero si todo lo que vas a hacer es hablar mierda con los mantenedores, ve a desahogarte en reddit, por favor. La corrección anterior de @funkyfuture está completamente garantizada.

al final, son los esfuerzos pasados ​​de @ shin-con docker-py los que le permitirían implementar una alternativa a docker-compose.

Obviamente, no quiero una bifurcación de docker-compose, si eso es lo que está sugiriendo, especialmente para una mejora tan pequeña. Esa es la única otra forma en que esto va a suceder, y eso sería malo para la comunidad.

Si alguien presentara un PR, ¿se consideraría realmente? ¿O es esto algo que el equipo de docker-compose ha decidido firmemente que no aceptará? ¿Sería algo que consideraría agregar una sección de configuración que sea compatible con las configuraciones de la pila de Docker ?

Esto se ha descarrilado ... 'anti-patrón' sin explicación convierte 'anti-patrón' en una definición muy amplia que es imposible de argumentar. Tampoco hay una dirección clara en qué lado se asienta el "anti-patrón"; docker o docker-compose.

Una definición clara de las respuestas anti-patrón sería fantástica y muy apreciada.

La comunidad seguirá creciendo, por lo que debe existir un conjunto establecido de definiciones.

Quiero usarlo para copiar artefactos generados por una tubería de jenkins que se ejecuta en una pila de composición de Docker. Y luego, el nombre del contenedor puede ser aleatorio, por lo que no puedo usar docker cp .

Hoy debo usar

docker cp $(docker-compose -f docker-compose.development.ci.yml ps -q test):/app/tests_output ./tests_output

¿Es esto diferente de volumes: - ./folder_on_host/ :/folder_in_container/ ?
Puedo copiar archivos desde el host al contenedor (equivalente a COPY) de esta manera en mi archivo de redacción

Estoy tratando de hacer lo mismo. Tengo una carpeta con un archivo csv y me gustaría proporcionarlo a logstash.
Cómo puedo hacer eso. o que carpeta en contenedor?
de momento tengo algo esto:
./path/to/storage:/usr/share/logstash/ data: ro

Cualquier sugerencia sería útil

@ shin- Este boleto ahora tiene 1.5 años. Cuando 160 personas te dicen que estás equivocado, probablemente lo estés.

¿Qué más necesitas para convencerte de que esto debería implementarse?

@isapir , las empresas que no escuchan a sus clientes, tienden a salir del negocio muy pronto. Así que supongo que deberíamos ver algunas alternativas de Docker listas para producción en un futuro próximo.

@ shin- Este boleto ahora tiene 1.5 años. Cuando 160 personas te dicen que estás equivocado, probablemente lo estés.

😆 🤣 💯 🥇 😲 😮

También,

Ya no soy un mantenedor. Por favor, deje de hacerme @---en cosas sobre las que ya no tengo ningún control.

@sfuerte Hay un pequeño proyecto llamado Kubernetes que ya reemplazó a Docker-Compose. Me pregunto si eso hubiera sucedido si la actitud hacia los comentarios de los usuarios hubiera sido más positiva.

Necesitamos una palabra de moda para contrarrestar sus palabras de moda. Es todo con lo que pueden lidiar.

Esta característica sería totalmente pro-pattern . Deberias hacer eso. La diferencia es que, aunque hice esa estupidez, hay muchos comentarios en este número que muestran las ventajas de esto en formas que son claramente casos de uso comunes. Y no hay una sola instancia de anti-pattern .

@ shin- te etiquetan en esto porque comenzaste esta mierda antipattern sin base en la realidad. Así que deja de llorar por algo que tú causaste.

k divertirme

Mi caso es:

  • Durante "dev" quiero que mi código fuente se cree como "volumen" para que se actualice automáticamente durante el desarrollo
  • Cuando la aplicación está lista para su lanzamiento y necesito "implementar", quiero copiar los archivos copiados en lugar de ser volúmenes.

Creo que la forma más fácil de resolver esto es tener 1 archivo de composición para desarrollo y 1 archivo de composición para producción.

El problema aquí es que puedo especificar "volúmenes" en el archivo de la ventana acoplable, pero no puedo especificar "copiar" en el archivo de la ventana acoplable.

¿Alguien está en el mismo caso que yo? ¿Me estoy perdiendo de algo?

@ shin- ¿es esto un anti-patrón? ¿Cómo resolvería este problema?

@hems , en un mundo perfecto, desea que su aplicación se implemente como una imagen de ventana acoplable independiente. Entonces, si está escribiendo una aplicación, el código fuente que pretende implementar probablemente debería ser parte de Dockerfile , por lo que la imagen contiene toda su aplicación. Entonces, en Dockerfile , si quisiera su fuente en / var / www, pondría

COPY my-app-src /var/www

Su fuente no es específica del entorno, por lo que solo pertenece a la imagen de la ventana acoplable. Fácil.

La mayoría de nosotros queremos incluir un archivo de configuración específico del entorno en los contenedores que haga que una imagen existente funcione bien con una configuración particular de composición de Docker. Y queremos poder hacer esto sin hacer un volumen para un archivo pequeño o sin rodar una nueva imagen.

¿Alguien del equipo de docker-compose puede simplemente echar un vistazo serio e imparcial a esto y sacar un veredicto final (con suerte, uno que ignore a todas las personas inmaduras)? Este problema ha estado abierto desde siempre. El resultado es importante, pero personalmente estoy cansado de recibir notificaciones.

COPY my-app-src /var/www

eso es lo que estoy diciendo, en el desarrollo quiero usar mi archivo docker-compose para montar VOLÚMENES en las imágenes y durante la compilación de producción quiero COPIAR archivos en las imágenes, por eso creo que deberíamos poder COPIAR y montar VOLÚMENES usando el archivo docker-compose, por lo que puedo tener 1 archivo de composición para desarrollo y 1 para compilación de producción.

Trabajo en el equipo que mantiene Compose y estoy feliz de participar en esta discusión. Para comenzar, describiré cómo vemos las responsabilidades de Dockerfiles y Compose files.

Los Dockerfiles son la receta para crear imágenes y deben agregar todos los binarios / otros archivos que necesita para que su servicio funcione. Hay un par de excepciones a esto: secretos (es decir, credenciales), configuraciones (es decir, archivos de configuración) y datos de estado de la aplicación (por ejemplo, los datos de su base de datos). Tenga en cuenta que los secretos y las configuraciones son de solo lectura.

Los archivos de composición se utilizan para describir cómo se implementa e interactúa un conjunto de servicios. El formato de composición se usa no solo para un solo motor (es decir: docker-compose ) sino también para entornos orquestados como Swarm y Kubernetes. El objetivo del formato Compose es facilitar la escritura de una aplicación y probarla localmente, luego implementarla en un entorno orquestado con pocos o ningún cambio. Este objetivo limita lo que podemos cambiar en el formato debido a diferencias fundamentales como cómo cada entorno maneja los volúmenes y el almacenamiento de datos.

Reducir las responsabilidades del archivo Dockerfile y Compose de esta manera nos da una buena separación de preocupaciones: qué hay en cada imagen de contenedor (Dockerfile), cómo se implementan e interactúan los servicios (archivo Compose).

Ahora revisaré cada una de las excepciones a lo que almacena en una imagen. En el caso de secretos, no desea que estos se conviertan en imágenes, ya que podrían ser robados y porque pueden cambiar con el tiempo. Los secretos de Docker se utilizan para resolver esto. Estos funcionan de manera ligeramente diferente según el entorno en el que se implemente, pero esencialmente la idea es que puede almacenar credenciales en un archivo que se montará de solo lectura en un directorio tmpfs en el contenedor en tiempo de ejecución. Tenga en cuenta que este directorio siempre será /run/secrets/ y el archivo será el nombre del secreto. Los secretos son compatibles con Swarm, solo motor ( docker-compose ) y Kubernetes.

Para archivos de configuración o datos de arranque, existe Docker Configs . Estos funcionan de manera similar a los secretos, pero se pueden montar en cualquier lugar. Estos son compatibles con Swarm y Kubernetes, pero no con docker-compose . Creo que deberíamos agregar soporte para estos y ayudaría con algunos de los casos de uso enumerados en este número.

Finalmente, hay datos de estado de la aplicación que deben almacenarse externamente. No profundizaré en esto ya que no está relacionado con este problema.

Con ese encuadre, puedo responder un par de preguntas:

  • ¿Agregaremos un campo copy al formato de redacción? No, no creo que lo hagamos, ya que no tiene sentido en entornos orquestados.
  • ¿Agregaremos configs soporte a docker-compose ? Sí, creo que deberíamos.
  • ¿Agregaremos docker-compose cp ? Quizás, todavía no estoy seguro de esto. Básicamente, sería un alias para docker container cp .

Dado eso, hay un par de herramientas que se pueden usar aquí:

  • Compilaciones de varias etapas que le permiten agregar archivos de forma condicional a una imagen utilizando objetivos.
  • Secretos que le permiten pasar credenciales a un servicio en tiempo de ejecución.
  • Configuraciones que le permiten pasar información de configuración a un servicio en tiempo de ejecución.

Creo que esas herramientas resuelven todos los problemas planteados en este hilo.

Este hilo está bastante caliente. Recuerde que hay una persona real detrás de cada identificador de GitHub y que probablemente esté tratando de hacer todo lo posible (incluso si se muestra su frustración). A todos nos apasiona Compose y queremos que el proyecto siga prosperando.

¿Agregaremos un docker-compose cp ? Quizás, todavía no estoy seguro de esto.

Me parece una conveniencia útil como docker-compose exec .

@ chris-crone Increíble respuesta, ¡gracias!

Sé que no hablo por todos , pero tengo la impresión de que el soporte de configs satisface la gran mayoría del interés aquí. ¿Se abrirá un problema para esto?

Y gracias por ofrecer algunos enfoques alternativos. No sabía de compilaciones de varias etapas hasta ahora.

Tengo la impresión de que el soporte de configs satisface la gran mayoría del interés aquí.

Lo dudo, ya que sospecho que la mayoría aquí no está usando Swarm y, afaik, la funcionalidad config requiere eso.

Sí, actualmente se requiere Swarm, pero del comentario de @ chris-crone ...

Estos son compatibles con Swarm y Kubernetes, pero no con docker-compose. Creo que deberíamos agregar soporte para estos y ayudaría con algunos de los casos de uso enumerados en este número.

... Estoy leyendo que esto se puede implementar en docker-compose (sans Swarm)

El objetivo del formato Compose es facilitar la escritura de una aplicación y probarla localmente, luego implementarla en un entorno orquestado con pocos o ningún cambio.

En aplicaciones complejas, es posible que tengamos bastantes archivos de configuración que necesiten ajustes sobre la marcha. En este momento, la forma más eficiente (en términos de tiempo y costo) de hacerlo es llenar la clave de volúmenes (porque ninguna persona en sus cabales creará una imagen diferente mientras prueba múltiples configuraciones ... a menos que tenga un jefe al que le encanta gastar dinero) en horas de desarrollo).

Swarm y config no van a responder realmente a varios de los casos de uso enumerados. La "separación de preocupaciones" tampoco es aplicable, ya que redactar ya hace lo que puede hacer en la ventana acoplable, pero lo simplifica. Una envoltura no es una separación ... solo te pedimos que la extiendas un poco más ...

https://github.com/docker/compose/issues/6643

Vuélvase loco con él ... extienda la funcionalidad de volumen donde cada archivo bajo la nueva clave está vinculado dinámicamente a un volumen singular y asignado a sus respectivas rutas internas ...

Creo que hay dos escenarios aquí que son perfectamente válidos, uno se trata de
entornos de desarrollo. Las personas crean entornos flexibles con fuente
código montado en sus imágenes. El código fuente evoluciona a medida que el desarrollo
ocurre y no puede reconstruir la imagen constantemente o simplemente desperdicia
enormes cantidades de tiempo. Ese es mi escenario exactamente y puedo ver que esto
El escenario se aplica a muchas otras personas.

El segundo es sobre imágenes de producción donde hornea su código fuente
(en caso de que esté trabajando con scripts no compilados) en su imagen (y
por otra parte, no lo estaba, todavía lo estaba montando de mi lado) o simplemente
compile su aplicación y cópiela en la imagen final. En ese punto,
la aplicación se vuelve extremadamente portátil.

¡Creo que todo el mundo lo entiende! La pregunta es, ¿el docker-compose
dev se tomó el tiempo para leer los casos y comprender las necesidades? Existen
no hay anti-patrones aquí en teoría, solo desarrolladores que tienen una necesidad y les gustaría
ser respetado.

Nos encanta docker, docker-compose y todo el ecosistema, lo usamos porque
me encanta y porque lo usamos, tienes trabajos (al menos a algunos de ustedes se les paga
por eso espero).

Algo que aprendí en los últimos años que me gusta traer aquí y
existe lo siguiente y se aplica muy bien a este escenario:

No es lo que hace su software lo que importa, es lo que hacen sus usuarios
con eso que importa

¡Salud y feliz continuidad!

El jueves 6 de junio de 2019 a las 10:55, jadon1979 [email protected] escribió:

El objetivo del formato Compose es facilitar la escritura de una aplicación
y probarlo localmente, luego implementarlo en un entorno orquestado con
pocos o ningún cambio.

En aplicaciones complejas, podemos tener bastantes archivos de configuración que necesitan
ajustar sobre la marcha. En este momento, la forma más eficiente (en términos de tiempo y costo) de
hacer eso es llenar la tecla de volumen (porque ninguna persona cuerda va
para crear una imagen diferente mientras prueba varias configuraciones .. a menos que
tienen un jefe al que le encanta gastar dinero en horas de desarrollo).

Swarm y config realmente no van a responder a varios de los casos de uso
enumerados. La "separación de preocupaciones" tampoco es aplicable, ya que redactar
hace lo que puede hacer en Docker, pero lo simplifica. Un envoltorio no es
separación ... solo te pedimos que la extiendas un poco más ...

6643 https://github.com/docker/compose/issues/6643

Vuélvase hacky con él ... amplíe la funcionalidad de volumen donde cada archivo bajo el
nueva clave se vincula dinámicamente a un volumen singular y se asigna a su
respectivos caminos internos ...

-
Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=ABBR3OMQH62242SM4QN5Y7TPZEQP7A5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43VMDVN5W63 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/ABBR3OMOZFZ47L6ITHPF2TDPZEQP7ANCNFSM4EKAVONA
.

Quiero activar un entorno de Docker Tomcat para ejecutar mi aplicación desde un .war que no se llama ROOT.war . Para hacer esto, tengo que copiarlo en el directorio webapps Tomcat y cambiarle el nombre a ROOT para que se ejecute en los puertos actualmente vinculados 8005/9. Cualquier otra cosa falla debido a problemas de reenlace en los puertos con errores sobre 'acceso ilegal'. Estas son compilaciones de prueba efímeras, por lo que no pueden incluirse en el Dockerfile. Por eso lo quiero en docker-compose

@lavabos

Sé que no hablo por todos, pero tengo la impresión de que el soporte de configuraciones satisface la gran mayoría del interés aquí. ¿Se abrirá un problema para esto?

Si aún no existe un problema para esto, cree uno y vincúlelo aquí. Agregué algo en nuestro rastreador de equipo privado.

@washtubs @funkyfuture

... Estoy leyendo que esto se puede implementar en docker-compose (sans Swarm)

Ya tenemos un soporte secreto rudimentario y las configuraciones podrían implementarse de manera similar.

Definitivamente una característica que falta. El único "antipatrón" es cuando tiene que evitar el hecho de que esto es difícil de hacer por otros medios, como por ejemplo, cambiar el script de punto de entrada del dockerfile o enlazar archivos de montaje en el contenedor.

Lo que desea es un contenedor que se compile una vez, preferiblemente oficialmente) y que se pueda configurar para el caso de uso, en el punto de uso, es decir, docker-compose.

Por lo que puedo ver, lo que la gente de la ventana acoplable no se da cuenta es que el "Dockerfile" es el antipatrón más grande en todo el concepto de la ventana acoplable, particularmente porque todo es completamente ilegible y no se puede mantener. ¡Realmente me hace reír cuando alguien relacionado con Docker lanza la palabra "antipatrón" como si lo supiera!

El Dockerfile en realidad evita la depuración normal y la limpieza que estaría disponible si usara un script de compilación, o algo realmente diseñado para compilar cosas, como ... un administrador de paquetes o make.

Para mí, uso el mismo DockerFile para todos los casos de uso (¡convirtiéndolo en un patrón!), Lo que sugiere que cambie mi DockerFile para cada uso diferente, realmente es anti-patrón.

Y ningún "soporte de configuración" no lo corta en absoluto, imponiendo una estructura donde simplemente no se necesita.

El problema fundamental es que si enlaza mount para decir / etc / nginx, tiene que ser rw para permitir que se ejecuten scripts que ajusten las configuraciones (también conocido como envsubst). Y esto luego realiza cambios en la configuración de entrada (que debe permanecer inmutable) ... No obtienes mucho más antipatrón que un contenedor escribiendo en toda su configuración, por lo que una opción para copiar archivos en el contenedor en el momento de la recreación es la necesaria solución.

En otras palabras, es un directorio de montaje de enlace rw en el contenedor, pero ro en el host. En serio, ¿te mataría permitir esto?

Definitivamente una característica que falta. El único "antipatrón" es cuando tiene que evitar el hecho de que esto es difícil de hacer por otros medios, como por ejemplo, cambiar el script de punto de entrada del dockerfile o enlazar archivos de montaje en el contenedor.

Lo que desea es un contenedor que se compile una vez, preferiblemente oficialmente) y que se pueda configurar para el caso de uso, en el punto de uso, es decir, docker-compose.

Por lo que puedo ver, lo que la gente de la ventana acoplable no se da cuenta es que el "Dockerfile" es el antipatrón más grande en todo el concepto de la ventana acoplable, particularmente porque todo es completamente ilegible y no se puede mantener. ¡Realmente me hace reír cuando alguien relacionado con Docker lanza la palabra "antipatrón" como si lo supiera!

El Dockerfile en realidad evita la depuración normal y la limpieza que estaría disponible si usara un script de compilación, o algo realmente diseñado para compilar cosas, como ... un administrador de paquetes o make.

Para mí, uso el mismo DockerFile para todos los casos de uso (¡convirtiéndolo en un patrón!), Lo que sugiere que cambie mi DockerFile para cada uso diferente, realmente es anti-patrón.

Y ningún "soporte de configuración" no lo corta en absoluto, imponiendo una estructura donde simplemente no se necesita.

El problema fundamental es que si enlaza mount para decir / etc / nginx, tiene que ser rw para permitir que se ejecuten scripts que ajusten las configuraciones (también conocido como envsubst). Y esto luego realiza cambios en la configuración de entrada (que debe permanecer inmutable) ... No obtienes mucho más antipatrón que un contenedor escribiendo en toda su configuración, por lo que una opción para copiar archivos en el contenedor en el momento de la recreación es la necesaria solución.

En otras palabras, es un directorio de montaje de enlace rw en el contenedor, pero ro en el host. En serio, ¿te mataría permitir esto?

Algo como esto:

''

si el archivo entonces sobrescribe

si el directorio entonces sobrescribe / agrega el contenido del destino

con contenido de origen para mantener la estructura de destino original

fuente: archivo : autorización: propietario : grupo

svc:
Copiar:
- './source/filename:/path/ filename: ro : www-data'
- './source/dir:/path/ dir: ro : www-data'

# o
svc:
Copiar:
- fuente: './source/file'
destino: '/ destino'
permiso: ro
propietario: propietario
grupo: grupo
- fuente: './source/directory'
destino: '/ destino'
permiso: ro
propietario: propietario
grupo: grupo```

Caso de uso: Tenemos una solución de contenedor no orquestada en la que tenemos los archivos de composición acoplable de nuestra aplicación, incluidos Certificados SSL, etc.dentro de un repositorio Git y colocándolo en una máquina virtual. Luego, activamos el servicio y queremos mover, por ejemplo, los certificados SSL, archivos de configuración, etc. al volumen del contenedor. Actualmente, esto no es posible sin un Dockerfile adjunto con un comando COPY incluido. No queremos perder el tiempo con los archivos dentro del repositorio de git clonado. Si la aplicación modificara los archivos, tendríamos que limpiar el repositorio cada vez.

@MartinMajewski, luego puede montar el directorio con certificados como volumen y apuntarlo en la configuración de su aplicación.

Caso de uso (y pregunta práctica a la vez):
Tengo postgres imagen con una única variable de entorno que se configurará al inicio: POSTGRES_PASSWORD . Quiero configurarlo a través de Docker Secret. Lo que tengo que hacer es poner mi propio entrypoint.sh que exportará el secreto adjunto a la var env del contenedor en ejecución. Necesito agregar este punto de entrada de alguna manera en mi contenedor en el lanzamiento. Sin Dockerbuild de dos líneas, no puedo. Copia de un solo archivo: no se puede hacer.

PS postgres es un ejemplo. Suponga que no es compatible con _FILE env vars.

Problema de seguimiento interno https://docker.atlassian.net/browse/COMPOSE-89

Caso de uso: Karaf
Usando una imagen base de karaf que no quiero reconstruir cada vez que construyo mi proyecto, quiero poder implementar mi aplicación rápidamente y reconstruir el contenedor para cada construcción. Sin embargo, necesito copiar un _features.xml_ y un _jar_ en el directorio de implementación al iniciar el contenedor.

Mi solución hasta ahora era usar la imagen karaf como imagen base en otro Dockerfile (confiando en overlayfs, que eventualmente se queda sin superposiciones, lo que obliga a eliminar manualmente la imagen) y avast / gradle-docker-compose-plugin. Si bien los comandos init seguramente se pueden pasar como una variable de entorno, el contenido de features.xml no. Debe almacenarse como un archivo en una ubicación específica del contenedor. En este momento, solo puedo usar un montaje de enlace de volumen para hacer esto. ¿Cómo introduzco cosas en ese volumen en una máquina remota? Necesito aún más lógica en mi script de compilación (por ejemplo, org.hidetake.groovy.ssh, que también complica el script de compilación con contraseña secreta / lógica de clave). Si estuviera disponible un cp de docker-compose, podría simplemente agregar el comando de copia necesario al docker-compose.yml. avast / gradle-docker-compose-plugin se encargaría de construir el contenedor y copiar los archivos de mi salida de compilación directamente en el contenedor sin ninguna lógica de acceso al sistema de archivos remoto adicional.

Este Dockerfile se agrega a mi parte de compilación docker-compose.yml del script. En todo caso, este es un antipatrón, porque solo agrega superposiciones a la imagen de la ventana acoplable ascendente con cada compilación (hasta que me veo obligado a eliminar manualmente la imagen, lo que hace que las compilaciones sean mucho más lentas).

FROM myregistry:443/docker/image/karaf-el7:latest

COPY karafinitcommands /usr/local/karaf/etc/

COPY features.xml \
     *.jar \
     /usr/local/karaf/deploy/

Me resulta frustrante que docker cp funcione bien para la copia en tiempo de ejecución, pero docker-compose no tiene un mecanismo equivalente.

Pensé que la idea es vincular el montaje de un directorio local a / usr / local / karaf / deploy y colocar sus archivos allí. No esperaría tener que reconstruir la imagen o usar un archivo acoplable para escuchar esto.

Pensé que la idea es vincular el montaje de un directorio local a / usr / local / karaf / deploy y colocar sus archivos allí. No esperaría tener que reconstruir la imagen o usar un archivo acoplable para escuchar esto.

Ciertamente se puede lograr de esa manera. Vuelva a leer y observe que esto es puramente un problema de conveniencia: el contenedor se reconstruye mediante la compilación de gradle, el siguiente paso lógico es: ¿Cómo muevo los nuevos archivos de compilación al "directorio local" montado en / usr / local / karaf / deploy? En mi caso, un "directorio local" es más exactamente un "directorio de host" donde el host es un host remoto. Así que tengo que agregar rsync o algo más a mi script de compilación solo para obtener archivos allí y asegurarme de que se reemplacen los antiguos y se eliminan los adicionales. Sería innecesario si estuviera disponible docker-compose cp. Podría utilizar mi cliente de docker existente para la conexión de demonio de docker, que configuré a través del reenvío de puertos.

Los volúmenes de Docker se pueden eliminar con cada compilación. No se pueden vincular volúmenes de montaje. Se volverán a llenar solo si están vacíos (mecanismo de protección de persistencia). Por supuesto, vaciar un montaje de enlace en una máquina remota requiere ciertos permisos y lógica de acceso que podrían evitarse con un cp de docker-compose.

De nuevo, se puede realizar una copia en un entorno de ejecución con docker cp. Esa es la parte frustrante.

Ah, está bien, estoy demasiado acostumbrado a mi propia configuración. Utilizo http://github.com/keithy/groan un script bash que auto-implementa los bits y piezas en servidores remotos, luego invocamos a docker.

Caso de uso: compilación y construcción de artefactos de Google Cloud

Artefacto necesario: cliente web (generado automáticamente) reaccionar enlaces graphql. Necesita que el servidor esté en ejecución para crear los archivos necesarios para la compilación del cliente. La imagen del cliente tiene las herramientas para crear los enlaces, dada una dirección de servidor. Así que inicia la imagen del servidor en el fondo y ahora necesita ejecutar el contenedor del cliente apuntando al servidor. Ahora, ¿cómo sacar los archivos generados del contenedor y colocarlos en el directorio de host del "espacio de trabajo"? No se permite el montaje directorios, puesto que ya está en un directorio montado en un contenedor ventana acoplable. Ser capaz de docker-compose cp aliviaría el paso extra doloroso de obtener la identificación del contenedor.

Confiar en $(docker-compose ps -q SERVICE) para apuntar al contenedor correcto hace posible usar cli de docker simple para tales operaciones centradas en contenedores. La introducción de un nuevo comando sin duda lo simplificaría para los pocos casos de uso que lo soliciten, pero no es obligatorio. Para evitar una mayor duplicación de código entre componer y docker CLI, creo que este problema debería cerrarse.

Hay un problema abierto en el que la caché de compilación entre compose y la ventana acoplable simple es diferente, debido a la versión del demonio de la ventana acoplable que usa compose, lo que significa que debe usar componer puro para no romper las cachés en entornos CI (https: // github .com / docker / compose / issues / 883), por lo que hasta que se resuelvan esos problemas, la combinación de comandos simples de la ventana acoplable con comandos de composición rompe las cachés. La configuración de composición especifica todo tipo de configuración horneada, lo que alivia la necesidad de especificar manualmente la configuración duplicada con comandos docker simples.

Confiar en $(docker-compose ps -q SERVICE) para apuntar al contenedor correcto hace posible usar cli de docker simple para tales operaciones centradas en contenedores. La introducción de un nuevo comando sin duda lo simplificaría para los pocos casos de uso que lo soliciten, pero no es obligatorio. Para evitar una mayor duplicación de código entre componer y docker CLI, creo que este problema debería cerrarse.

Esto es mucho más profundo que "Se mencionan pocos casos de uso" porque esos escenarios son bastante comunes y la modificación, creación de imagen, modificación de nuevo, creación de imagen, etc. es un sumidero de tiempo en vez de poder manejar esas cosas a través de docker-compose. El argumento de "puedes hacerlo en el docker cli, así que hazlo allí" prácticamente anula muchas otras cosas que se han agregado a docker-compose.

Este tema ha estado abierto durante casi un año y hay muchas otras discusiones al respecto fuera de este tema. Definitivamente no debería cerrarse a menos que esté realmente resuelto.

@dionjwa # 883 realmente necesita ser investigado (si aún es relevante) ya que docker-compose debe alinearse con la CLI de docker.

@ jadon1979 No estoy tratando de bloquear esta solicitud de función, solo noté que se abrió hace más de 1 año, y ninguno de los mantenedores centrales lo consideró lo suficientemente importante como para introducir un nuevo comando, ni un colaborador propuso un PR para eso.
Solo digo que, de acuerdo con los comentarios sobre esta solicitud de función, y la falta de esfuerzo de desarrollo para ofrecer una "mejor manera", la solución alternativa propuesta para usar una combinación de docker-compose y docker cli, a la que se puede alias fácilmente en su entorno para que sea fácil de usar, es una solución razonable.
Ahora, si alguien abre un PR para ofrecer un nuevo comando cp , me complacerá revisarlo.

Nadie contribuyó porque a todos se les dijo que cada caso de uso era un
anti-patrón. Y cada pocos días publicamos nuevos casos de uso, ninguno
anti-patrones.

El lunes 18 de noviembre de 2019 a las 17:31 Nicolas De loof [email protected]
escribió:

@dionjwa https://github.com/dionjwa # 883
https://github.com/docker/compose/issues/883 realmente necesita ser
investigado (si sigue siendo relevante) ya que docker-compose debe estar alineado con
Docker CLI.

@ jadon1979 https://github.com/jadon1979 No estoy tratando de bloquear esto
solicitud de función, acabo de notar que se abrió hace más de 1 año, y
ninguno de los mantenedores principales lo consideró lo suficientemente importante como para
introdujo un nuevo comando, ni un colaborador propuso un RP para él.
Solo digo que, según los comentarios sobre esta solicitud de función,
y falta de esfuerzo de desarrollo para ofrecer una "mejor manera", la propuesta
solución alternativa para utilizar una combinación de docker-compose y docker cli, que
puede utilizar fácilmente un alias en su entorno para que sea fácil de usar, es un
solución alternativa razonable.
Ahora, si alguien abre un PR para ofrecer un nuevo comando cp, me complacerá
revisalo.

-
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=AAGRIF2NS64IYANNVTGFTULQUL3TZA5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63WKTZD55 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/AAGRIFY7CULCUS3TDDTTHZLQUL3TZANCNFSM4EKAVONA
.

Mi caso de uso no es copiar cosas _en_ ​​un contenedor, sino copiarlas _ fuera_ del contenedor después de que se haya ejecutado. Esto se puede hacer desde la CLI utilizando una solución torpe que produce una funcionalidad posiblemente degradada . Detalles completos a continuación.

Soy ingeniero de DevOps y confío en gran medida en los contenedores como alternativa al infierno de dependencia de los agentes de compilación nativos. Cuando mi sistema de CI prueba un repositorio, comienza compilando desde un Dockerfile dentro del mismo repositorio y ejecutando todas las comprobaciones ( bundle exec rspec , npm test , etc.) _dentro del contenedor_. Si hay artefactos de compilación creados como documentación o resultados de pruebas, simplemente los copio fuera del contenedor con docker cp .

Para las pruebas de integración, comenzamos a usar docker-compose para proporcionar dependencias de servicio (por ejemplo, un servidor de base de datos) al contenedor que ejecuta las pruebas. Desafortunadamente, la "solución alternativa de la CLI de la ventana acoplable" es menos útil en este caso para copiar archivos.

Considere esta configuración: docker-compose-minimal.yml

version: "3"
services:
  artifact-generator:
    image: busybox

Voy a crear el contenedor, ejecutar un comando en ese contenedor, obtener el ID del contenedor e intentar extraer el archivo usando docker cp

$ # Prepare the images and (stopped) containers.  In this case there is only one.
$ docker-compose --file docker-compose-minimal.yml up --no-start
Creating network "docker-compose-cp-test_default" with the default driver
Creating docker-compose-cp-test_artifact-generator_1 ... done
$ # Determine the ID of the container we will want to extract the file from
$ docker-compose --file docker-compose-minimal.yml ps -q artifact-generator
050753da4b0a4007d2bd3514a3b56a08235921880a2274dd6fa0ee1ed315ff88
$ # Generate the artifact in the container
$ docker-compose --file docker-compose-minimal.yml run artifact-generator touch hello.txt
$ # Check that container ID again, just to be sure
$ docker-compose --file docker-compose-minimal.yml ps -q artifact-generator
050753da4b0a4007d2bd3514a3b56a08235921880a2274dd6fa0ee1ed315ff88
$ # OK, that looks like the only answer we're going to get.  Can we use that to copy files?
$ docker cp $(docker-compose --file docker-compose-minimal.yml ps -q artifact-generator):hello.txt ./hello-artifact.txt
Error: No such container:path: 050753da4b0a4007d2bd3514a3b56a08235921880a2274dd6fa0ee1ed315ff88:hello.txt
$ # Nope.  Let's take a look at why this is
$ docker container ls -a
CONTAINER ID        IMAGE                        COMMAND                   CREATED              STATUS                          PORTS               NAMES
9e2cb5d38ba0        busybox                      "touch hello.txt"         About a minute ago   Exited (0) About a minute ago                       docker-compose-cp-test_artifact-generator_run_dd548ee686eb
050753da4b0a        busybox                      "sh"                      2 minutes ago        Created                                             docker-compose-cp-test_artifact-generator_1

Como puede ver, docker-compose ps realmente no tiene conocimiento del ID de contenedor actualizado. Esto es desafortunado. Esto no sería tan malo si hubiera una manera de saber que run_dd548ee686eb estaba relacionado de alguna manera con el docker-compose run que ejecuté, pero no veo la manera de lograrlo.

Hay una solución torpe para esta solución, que es agregar --name al comando de ejecución:

$ docker-compose --file docker-compose-minimal.yml run --name blarg artifact-generator touch hello.txt
$ docker cp blarg:hello.txt ./hello-artifact.txt
$ ls 
docker-compose-minimal.yml  hello-artifact.txt

¡Éxito! ... un poco

El problema aquí es que si tengo varias compilaciones ejecutándose en paralelo, necesito tomarme la molestia de hacer que los --name s sean únicos a nivel mundial. De lo contrario, obtendré colisiones ruidosas en el mejor de los casos y resultados corruptos (sin error, pero se extrajo un archivo incorrecto) en el peor de los casos. Entonces, esto es torpe porque ahora tengo que reinventar la generación de ID de contenedor en lugar de simplemente usar el que Docker ya creó.

Como mínimo, me gustaría saber de alguna manera el ID del contenedor que resulta del comando docker-compose run .

@ndeloof

Confiar en $ (docker-compose ps -q SERVICE) para apuntar al contenedor correcto hace posible usar cli de docker simple para operaciones centradas en contenedores.

Falso, vea la demostración en el comentario anterior.

Tendremos nuevos casos de uso durante años aquí. Espera, me refiero a un nuevo anti
patrones...

El viernes 13 de diciembre de 2019 a las 11:40, Ian, [email protected] escribió:

@ndeloof https://github.com/ndeloof

Confiar en $ (docker-compose ps -q SERVICE) para apuntar al contenedor correcto
hacer posible el uso de cli de Docker simple para tales contenedores centrados
operaciones.

Falso, vea la demostración en el comentario anterior.

-
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=AAGRIF2NFPTKY3QKRIXQ5RTQYONHLA5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43KNZDVN5H7W63 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/AAGRIF3S4UHF5NG3VKYXJB3QYONHLANCNFSM4EKAVONA
.

¿A quién podemos mencionar para llegar a los mantenedores? Este tema no tiene sentido hasta que empiecen a hablar con nosotros. Podría ser simple "no se puede hacer debido a la arquitectura de software actual", lo que sea. Pero dejar inertes estos problemas no es algo que le gustaría ver en esta pieza de soluciones tan popular como Docker ...

Nuestra implementación crea la imagen de Docker con bazel, la carga en nuestro Docker Registry y luego usa los recursos de Terraform docker_container con upload stanzas para copiar archivos de configuración en el contenedor. Necesito migrar este proceso de implementación para usar docker-compose en lugar de Terraform. Me sorprende que docker-compose no proporcione ninguna función para la configuración por contenedor.

Este problema ha estado abierto durante 2 años. ¿Es por eso que Kubernetes está superando a Docker en popularidad? Kubernetes proporciona funciones de configuración y secretos. Equipo de Docker, agregue al menos la funcionalidad de configuración.

tbf docker-compose no es exactamente comparable a k8s y no se recomienda para uso en producción. Está diseñado para desarrollo y pruebas rápidas. Docker Swarm es lo que se puede comparar con k8s y, aunque también es muy simplista, tiene características como configuraciones y secretos.

Si está destinado solo al desarrollo, esa es una razón más para este problema.
Deberia trabajar. Las malas reglas del "anti patrón" ni siquiera deberían ser tan
importante (digo mierda porque está claro por la abundancia de uso normal
casos en los que no es nada parecido a un anti-patrón).

El martes 3 de marzo de 2020 a las 12:56 p. M. David Milum [email protected]
escribió:

tbf docker-compose no es exactamente comparable a k8s, y no se recomienda
para uso en producción. Está diseñado para desarrollo y pruebas rápidas. estibador
swarm es lo que se puede comparar con k8s y aunque también es muy
simplista, tiene características como configuraciones y secretos.

-
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=AAGRIFZTKGRWMZZ5H6DG3FDRFUSEJA5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43VMDVBW63 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/AAGRIF4NTQQSR2QQWPJT6PLRFUSEJANCNFSM4EKAVONA
.

Otro "anti-patrón":

Utilizo docker-compose para la orquestación de contenedores durante el desarrollo local y k8s para la producción.

Según el propio consejo de Docker , he implementado el script wait-for-it.sh para administrar el orden de inicio / cierre del servicio.

Tal como está, a menos que quiera montar un volumen en cada servicio solo para este archivo, esto requiere una copia del script en el directorio que contiene Dockerfile de cada servicio.

En cambio, me gustaría mantener una sola copia del script wait-for-it en un directorio de nivel superior que docker-compose luego copia en cada contenedor cuando se ejecuta localmente, ya que tales preocupaciones se gestionan de otra manera en k8s, lo que significa que no quiero que estas preocupaciones contaminen los Dockerfile s de mis servicios.

Como escribió una vez Emerson: "Una coherencia tonta es el duende de las mentes pequeñas, adorado por pequeños estadistas, filósofos y teólogos".

Quizás es hora de escuchar a tus usuarios ...

@Phylodome, ¿no puedes usar controles de estado del contenedor y docker-compose depends_on ? Así es como aseguro dependencias de inicio de contenedores saludables.

Tengo entendido que wait-for-it.sh es realmente un truco, ya que sus propios servicios deben ser resistentes a las dependencias que van y vienen. El inicio es solo un caso individual de eso.

@ianfixes ¿Se

¿Se pretende que "sus servicios" se refieran a los servicios de docker-compose en sí mismos, o "nuestros" servicios, como en los servicios escritos por nosotros que usamos docker-compose?

Los servicios que cree como desarrollador deben ser resistentes. Esto es de acuerdo con estos documentos: https://docs.docker.com/compose/startup-order/

El problema de esperar a que una base de datos (por ejemplo) esté lista es en realidad solo un subconjunto de un problema mucho mayor de los sistemas distribuidos. En producción, su base de datos podría dejar de estar disponible o mover hosts en cualquier momento. Su aplicación debe ser resistente a este tipo de fallas.

Para manejar esto, diseñe su aplicación para intentar restablecer una conexión a la base de datos después de una falla. Si la aplicación reintenta la conexión, eventualmente podrá conectarse a la base de datos.

La mejor solución es realizar esta verificación en el código de su aplicación, tanto al inicio como siempre que se pierda una conexión por cualquier motivo. Sin embargo, si no necesita este nivel de resistencia, puede solucionar el problema con un script contenedor:

Y continúa mencionando varios guiones de espera.

Podría hacer varias cosas. Pero debido a que esto es solo para el desarrollo local, y debido a que tengo otras estrategias para manejar las verificaciones del servicio de producción en k8s, preferiría la implementación local más simple y menos molesta, no los consejos genéricos de personas que no conocen los detalles de por qué ' Me gustaría hacer esto (por ejemplo, problemas con el montaje de volumen para realizar el desarrollo de la interfaz de usuario a través del servidor de desarrollo de Webpack).

En cualquier caso, es solo otro en la larga lista de casos de uso para esta posible característica que debe dejarse a discreción del usuario.

Escucho ira dirigida hacia mí y entiendo por qué sería frustrante escuchar "consejos" no solicitados para su enfoque. Pero ni siquiera estoy seguro de cómo disculparme; Cité el texto de la URL a la que usted mismo se refirió como "consejo del propio Docker", que dice _explícitamente_ que el script de espera es una forma de "solucionar el problema". Por lo que vale, lo siento de todos modos.

No escuchas enojo. Estás escuchando el tono exasperado de alguien que, al buscar en Google lo que debería ser una característica bastante obvia, se topó con un hilo de cien comentarios en el que un conjunto de mantenedores patrocinaba y rechazaba continuamente las súplicas de la comunidad de una característica completamente válida.

No compartí mi experiencia aquí porque quería una disculpa. Lo compartí simplemente para agregar a la larga lista de pruebas de que a los usuarios de Docker les gustaría flexibilidad adicional al usar compose .

Por supuesto, como cualquier herramienta, esa flexibilidad viene acompañada del potencial de abuso. Pero ese mismo potencial, si no peores potenciales, existe cuando sus usuarios deben encontrar soluciones para resolver sus casos de uso específicos que podrían resolverse mucho más simplemente agregando esta función.

Además, pedir disculpas a tus usuarios es un mal aspecto.

No soy mantenedor ni colaborador de este proyecto, y me disculpo por cualquier confusión. Parece que la poca ayuda que pensé que podía ofrecer fue indeseada e inútil, y lamento haber hecho perder su tiempo.

Quiero esta función para un contenedor Go que es parte de mi aplicación distribuida. Dado que el archivo .env debe incluirse en la raíz de la aplicación Go, necesitaré crear un .env separado para él ... Mientras que, si tuviera esta función, podría tener mi archivo .env nivel superior y copiarlo en el contenedor Go cuando lo construya. Significaría menos cosas de las que necesito realizar un seguimiento ...

Mi solución podría ser crear este archivo a través del Dockerfile del contenedor Go o simplemente hacer un archivo .env para ese contenedor. Pero aún así, cada vez que agregue una nueva var env, tendré que actualizarla, posiblemente, en dos lugares. Buen caso de uso aquí. O simplemente podría usar un script de shell para cp el archivo para mí ...

+1 para la función COPIA

ya lo logramos en Kubernetes con sidecar, y hay MUCHOS casos de uso. Esto NO es un anti-patrón, solo una de las características que mantienen el docker-compose atrás.

Tal vez me esté perdiendo algo, pero ahora mismo, cuando estamos construyendo nuestra aplicación durante 5 minutos, todo ese tiempo la carpeta de construcción está "en proceso de cambio" y la aplicación no se inicia debido a una inconsistencia.
Preferiría _copiar_ una carpeta de compilación en un contenedor, por lo que cuando sea el momento de iniciar el contenedor, se hará cargo del interno. De esa manera, la aplicación solo está fuera de línea durante aproximadamente un segundo, cuando se detiene / inicia el contenedor.

¿Cómo es esto un anti-patrón cuando docker ya lo admite? Tendría sentido que docker-compose siga lo más cerca posible de la usabilidad de la ventana acoplable; no hacerlo es en sí mismo un anti-patrón.

El problema con esto es que es increíblemente miope (de ahí el término "anti-patrón"), ya que te obligará a repetir la operación cada vez que los contenedores sean recreados. Sin mencionar el hecho de que se escala muy mal (¿y si tiene 10 contenedores? ¿20? ¿100?)

Creo que eso depende del desarrollador. Simplemente copiar un único archivo de configuración local tiene una sobrecarga insignificante. No culpes al cuchillo.


PD Mi caso de uso; Quiero agregar una configuración a un contenedor Nginx en un proyecto sin Dockerfiles.

Quién sabe más.
Necesitaba configurar un nuevo proyecto y busqué nuevos
herramientas, Lando es mucho mejor que esto, es una locura. Ojalá lo usara
cuanto antes.
Es más rápido, más fácil de entender, mejor soporte y
no tiene (ex) mantenedores / contribuyentes condescendientes.

@ chris-crone con respecto a tu comentario ...

Para archivos de configuración o datos de arranque, existe Docker Configs. Estos funcionan de manera similar a los secretos, pero se pueden montar en cualquier lugar. Estos son compatibles con Swarm y Kubernetes, pero no con docker-compose. Creo que deberíamos agregar soporte para estos y ayudaría con algunos de los casos de uso enumerados en este número.

¿Docker-compose está interesado en implementar el soporte de configuración para la paridad con las configuraciones de enjambre?

Si hay un boleto para esto (o si necesito hacer uno que también está bien), me gustaría suscribirme y cancelar la suscripción de este incendio de basura. Personalmente cerraría esto y vincularía a eso, pero ese soy yo.

@harpratap tienes razón, pero el inconveniente es que / folder_in_container no debe existir o debe estar vacío o de lo contrario se sobrescribirá. Si tiene un script bash como punto de entrada, puede evitar esto enlazando sus archivos en el directorio originalmente previsto después de crear un volumen en / some_empty_location

+1 por tener una función COPIA. Nuestro caso de uso es para poner en marcha rápidamente entornos de desarrollo local y copiar configuraciones para los ajustes de desarrollo.

Exactamente. No todos escalamos de la misma manera. Mi empresa utiliza SALT para crear los archivos .conf necesarios para una variedad de aplicaciones. Una compilación, con lo básico, luego docker-compose para crear las instancias individuales en función de sus partes únicas: dirección MAC, IP, puerto, licencias, módulos, etc. PODRÍA hacerse desde una línea de comandos, pero mucho más fácil y menos propenso a errores de docker-compose.

Tengo un caso de uso. Tenemos una compilación de prueba que requiere que se configure SSL. Los certificados son generados por un servicio en el docker-compose ... Luego agrego esos certificados a los contenedores del cliente ... si monto, pierdo los certificados existentes y no puedo ponerlos en la compilación de la ventana acoplable porque no todavía no existe.

En consecuencia, tengo que ejecutar 2 docker-compose: 1 para iniciar los servicios para crear los certificados y luego otro para crear los servicios y ejecutar las pruebas. Sucio.

He visto muchos problemas aquí, donde los usuarios han sugerido muchos casos de uso para una característica, pero son rechazados porque un mantenedor piensa que es un anti-patrón, o la gente no lo usaría o alguna otra historia. .

Si bien puede parecer un patrón anti para una persona, estoy seguro de que las 1000 personas que solicitan la función, que piensan lo contrario, también deben ser escuchadas. Si se necesita ayuda para desarrollar la función, creo que muchas personas pueden echar una mano.

Mi caso de uso: además de las configuraciones, tengo algunas bibliotecas (RPM) que necesito instalar en 5 de mis contenedores de aplicaciones Rails (Debian). Diferentes versiones de Ruby / Rails, por lo que no puedo usar la misma imagen base, por lo que debería poder almacenar los archivos en una sola ubicación y copiarlos en un contenedor al compilar, porque no quiero descargar 1.5GB de datos mientras construye.

@gauravmanchanda

Mi caso de uso: además de las configuraciones, tengo algunas bibliotecas (RPM) que necesito instalar en 5 de mis contenedores de aplicaciones Rails (Debian). Diferentes versiones de Ruby / Rails, por lo que no puedo usar la misma imagen base, por lo que debería poder almacenar los archivos en una sola ubicación y copiarlos en un contenedor al compilar, porque no quiero descargar 1.5GB de datos mientras construye.

¿Ha mirado compilaciones de varias etapas para esto? Creo que sería una solución más sólida.

Las compilaciones de varias etapas le permiten utilizar el mismo Dockerfile para varias imágenes. Esto le permite factorizarlos e incluir solo los bits que necesita en cada imagen.

Un buen ejemplo de uno es el que usamos para construir Docker Compose . Esto se construye usando Debian o Alpine pero nos permite factorizar código común.

En nuestra configuración, aumentamos aproximadamente una docena de simuladores con docker-compose. Por lo demás, los simuladores son iguales, pero un archivo de inicio es diferente para cada objetivo y este archivo se consume en el inicio (se elimina cuando el servidor está en funcionamiento). ¿Realmente está sugiriendo que deberíamos crear alrededor de una docena de imágenes casi idénticas solo porque un archivo es diferente? Eso no tiene sentido en mi opinión.

Con Docker, la marca --copy-service se puede usar para lograr esto. ¿Hay alguna alternativa que podamos usar con docker-compose?

Hola @megaeater ,

aumentamos alrededor de una docena de simuladores con docker-compose. Por lo demás, los simuladores son iguales, pero un archivo de inicio es diferente para cada objetivo y este archivo se consume en el inicio (se elimina cuando el servidor está en funcionamiento).

Este es un caso de uso interesante; Algunas preguntas: ¿Estos simuladores (o partes de ellos) se ejecutan alguna vez en producción (es decir, no en la máquina del desarrollador o en un CI)? Si el código está abierto (o un sistema similar lo está), ¿podría vincularme a él para que pueda echarle un vistazo?

También sería interesante saber por qué querría una copia en lugar de un montaje de enlace o un volumen para estos archivos.

¿Realmente está sugiriendo que deberíamos crear alrededor de una docena de imágenes casi idénticas solo porque un archivo es diferente? Eso no tiene sentido en mi opinión.

Las imágenes se basan en capas exactamente por esta razón: todas las imágenes harán referencia a las mismas capas, excepto la capa que incluye los diferentes archivos.

El problema con cosas como una copia en la creación de un contenedor es que hace que tomar el mismo código y ejecutarlo en producción sea difícil (es decir, requerir una reescritura lógica importante) porque el patrón será frágil o imposible en entornos orquestados.

Esto no quiere decir que nunca debamos implementar algo como esto en Compose. Más bien, cuando un cambio significa que los usuarios no podrán reutilizar algo que funciona localmente en producción, nos gusta hacer una pausa y ver si hay una forma más sólida de lograr el mismo objetivo.

Gracias por el comentario @ chris-crone

No estamos ejecutando Docker en producción, es solo para fines de desarrollo. El problema con el uso del volumen (si lo entiendo correctamente) es que el simulador (tercero) tiene este script de inicio que elimina el archivo al inicio. La ejecución del script se detiene si falla la eliminación, por lo que necesitaríamos montarlo como rw. Y si se permite la eliminación de archivos, necesitaríamos tener un mecanismo para crear un directorio temporal para suministrar estos archivos para que los originales no se eliminen. Por lo tanto, necesitaríamos tener algún tipo de scripts extraños para aumentar la composición además de docker-compose.

@ chris-crone Gracias por los enlaces. Echaré un vistazo y veré si funciona para nosotros 👍

Hola @ chris-crone, intenté usar compilaciones de múltiples etapas, y nos ayudó a mantener las bibliotecas / configuraciones en una sola ubicación y copiarlas, pero ahora hay problemas con .dockerignore se ignoran, sin importar dónde Lo coloco.

Funciona cuando solo estoy usando Docker con la nueva opción DOCKER_BUILDKIT , pero no funciona cuando uso docker-compose, probé COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose build , pero aún así no funcionó. ¿Algunas ideas?

Me preguntaba si había una opción para especificar dónde buscar .dockerignore en redactar, cuando me encontré con este problema https://github.com/docker/compose/issues/6022 , que nuevamente, fue cerrado, porque 1 colaborador cree que esto no es útil.

¡¡Esto es bastante frustrante si soy honesto !!

Esto es fundamental en MacOS, porque lograr que los ciclos de desarrollo estén lo más cerca posible de la producción es de suma importancia; obviamente para las prácticas adecuadas de Entrega Continua. por ejemplo, compile el contenedor, pero luego enlace el montaje de su nueva versión del software en el que está trabajando actualmente en el contenedor para ahorrar en tiempos de ciclo de compilación. Desafortunadamente, las monturas de unión son extremadamente costosas, siendo de 3 a 5 veces más lentas.

Como ejemplo, el tiempo de inicio de Tomcat es de aproximadamente 3 segundos para mi aplicación en un contenedor. Agregue un montaje de enlace de ~ / .bash_history y son 4s. Agregue un montaje de enlace de mi aplicación y generalmente es de 18 a 20 años. En Linux, el rendimiento del montaje de enlaces es como el de un sistema de archivos local, pero no en MacOS. Escale eso a 100 veces por día y eso es significativo.

Eso sin incluir la lentitud que continúa al acceder a la aplicación por primera vez; hasta que los archivos de código se almacenen en caché. Para mí, eso significa 3 minutos, incluido el retraso en la conexión a Internet de la base de datos de Oracle monolítica para cambiar una pequeña frase a otra cosa y ver si todavía se ve bien. Maldito covid-19, jajaja.

Idealmente, me gustaría poder ejecutar Docker-compose nuevamente y "actualizar" mi aplicación en el contenedor en ejecución, y pedirle a Tomcat que vuelva a cargar. Podría usar el administrador de tomcat para cargar el cambio, pero también tenemos una aplicación de back-end que no usa un contenedor administrado de ningún tipo, por lo que tendríamos que usar una solución diferente a eso.

Sería bueno si docker-compose también estuviera orientado al desarrollo, no solo a una implementación de producción.

Este caso de uso es relevante para la discusión: https://github.com/docker/compose/issues/3593#issuecomment -637634435

@ chris-crone

@gauravmanchanda

Mi caso de uso: además de las configuraciones, tengo algunas bibliotecas (RPM) que necesito instalar en 5 de mis contenedores de aplicaciones Rails (Debian). Diferentes versiones de Ruby / Rails, por lo que no puedo usar la misma imagen base, por lo que debería poder almacenar los archivos en una sola ubicación y copiarlos en un contenedor al compilar, porque no quiero descargar 1.5GB de datos mientras construye.

¿Ha mirado compilaciones de varias etapas para esto? Creo que sería una solución más sólida.

Las compilaciones de varias etapas le permiten utilizar el mismo Dockerfile para varias imágenes. Esto le permite factorizarlos e incluir solo los bits que necesita en cada imagen.

Un buen ejemplo de uno es el que usamos para construir Docker Compose . Esto se construye usando Debian o Alpine pero nos permite factorizar código común.

Las compilaciones de varias etapas son geniales, pero tienen sus propios problemas, por lo que tienes que ejecutar todas las etapas dentro del mismo contexto, lo que no siempre es posible. Además, hasta donde yo sé, no puede usar fácilmente COPY --from con imágenes definidas en otro Dockerfile y compiladas con docker-compose build (supongo que podría hacerlo compilándolas y etiquetándolas manualmente).

COPY en sí mismo es muy limitado ya que solo puede importar desde su contexto de compilación. docker cp puede copiar desde cualquier lugar a cualquier lugar, excepto que no puede copiar entre la imagen y el contenedor (algo así como COPY --from ).

Mi propio caso de uso es un poco diferente (aparte de copiar archivos de configuración de solo lectura, los montajes de volumen local no son la mejor idea cuando se implementa en otra máquina) y diría que lo que estoy haciendo ahora es un antipatrón ... . Tengo potencialmente varias imágenes diferentes que, en la compilación, generan paquetes de activos JS + HTML + compilados y minificados (piense en pequeñas aplicaciones angulares) y un solo servidor nginx que sirve a todas (nb, construido a partir de una imagen personalizada debido a complementos).

Actualmente, lo que tengo que hacer es copiar los paquetes de "implementación" de las imágenes de "compilación" al inicio. Idealmente, esto debería hacerse en la creación del contenedor o en la compilación, pero esto último requeriría crear otra imagen encima del "nginx modificado".

Imagine el siguiente diseño del proyecto (los subproyectos pueden vivir en repositorios separados y no conocerse entre sí):

app1/
  src/
    ...
  Dockerfile
app2/
  src/
    ...
  Dockerfile
app3/
  src/
    ...
  Dockerfile
nginx/
  ...
  Dockerfile
docker-compose.yml

Cada uno de los archivos app{1,2,3}/Dockerfile contiene un objetivo / etapa build que construyen la aplicación en /usr/src/app/dist . nginx/Dockerfile tiene una sola etapa y crea una imagen similar a nginx/nginx , pero con todos los complementos necesarios (sin configuraciones).

docker-compose.yml:

version: '3.8'
services:
  app1-build:
    build:
      context: app1/
      target: build
    image: app1-build
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        rm -vfr /dist-volume/app1 \
        && cp -vr /usr/src/app/dist /dist-volume/app1 \
        && echo "Publishing successful"
    volumes:
      - 'dist:/dist-volume'

  app2-build:
    build:
      context: app2/
      target: build
    image: app2-build
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        rm -vfr /dist-volume/app3 \
        && cp -vr /usr/src/app/dist /dist-volume/app3 \
        && echo "Publishing successful"
    volumes:
      - 'dist:/dist-volume'

  #... same thing for app3-build

  nginx:
    build:
      context: nginx/
    image: my-nginx
    volumes:
      - 'dist:/var/www'
      - # ... (config files etc)

volumes:
  dist:

Ahora, esto obviamente no es ideal, cada imagen de creación de aplicaciones se ejecuta innecesariamente y termina rápidamente, las imágenes implementadas residen en un volumen compartido (supongo que esto tiene un impacto negativo en el rendimiento, pero no pude verificarlo todavía). Si copy o copy_from fuera una opción de composición de docker, lo mismo podría escribirse como:

version: '3.8'
services:
  # assuming the images have default entrypoint and cmd combination that immediately returns with success.
  app1-build:
    build:
      context: app1/
      target: build
    image: app1-build

  #... same thing for app2-build app3-build

  nginx:
    build:
      context: nginx/
    image: my-nginx
    copy:
      - from: app1-build  # as image or service, both have their pros and cons, service would mean an image associated with this service
         source: /usr/src/app/dist
         destination: /var/www/app1
      - from: app2-build
         source: /usr/src/app/dist
         destination: /var/www/app2
      - from: app3-build
         source: /usr/src/app/dist
         destination: /var/www/app3
    volumes:
      - # ... (config files etc)

Mi caso de uso no está en el paso de compilación ni en el paso de inicio. Estoy recuperando archivos generados dentro de un contenedor o todos los contenedores de un servicio, estos contenedores se ejecutan en un motor Docker remoto. Hasta ahora me encuentro haciendo algo como docker-compose ps -qa <service> | xargs -i docker cp {}:<there> <here> . Solo desearía poder mantener la ventana acoplable-componer de forma única en mi script.

@ chris-crone

También sería interesante saber por qué querría una copia en lugar de un montaje de enlace o un volumen para estos archivos.

¿Disfrutas de la autoflagelación? Si es así, recomiendo ejecutar una aplicación usando un montaje de enlace en MacOS. 🤣 Vea mi publicación anterior para obtener más detalles.

Esto no quiere decir que nunca debamos implementar algo como esto en Compose. Más bien, cuando un cambio significa que los usuarios no podrán reutilizar algo que funciona localmente en producción, nos gusta hacer una pausa y ver si hay una forma más sólida de lograr el mismo objetivo.

@ chris-crone Creo que este es un gran sentimiento, porque con demasiada frecuencia la gente se mete en la implementación de anti-patrones para Docker, como no administrar la configuración y los datos de manera efímera.

Me pregunto si de alguna manera podríamos hacer que Docker y Apple trabajen juntos para solucionar los problemas de rendimiento con los montajes de enlace. Para mí, al menos, no tendría más necesidad de una opción docker compose cp, porque estaría usando bind mounts para el desarrollo. En este momento, aunque es demasiado doloroso usar monturas de enlace. Puedo cambiar a una máquina virtual con Linux, porque mi Mac solo bytes.

@megaeater

No estamos ejecutando Docker en producción, es solo para fines de desarrollo. El problema con el uso del volumen (si lo entiendo correctamente) es que el simulador (tercero) tiene este script de inicio que elimina el archivo al inicio. La ejecución del script se detiene si falla la eliminación, por lo que necesitaríamos montarlo como rw. Y si se permite la eliminación de archivos, necesitaríamos tener un mecanismo para crear un directorio temporal para suministrar estos archivos para que los originales no se eliminen. Por lo tanto, necesitaríamos tener algún tipo de scripts extraños para aumentar la composición además de docker-compose.

Hmm ... Si pudiera interactuar con el proveedor del simulador, creo que es la mejor manera de solucionar este problema. Quizás podría solucionar esto con un script de punto de entrada para el simulador que mueve los archivos según sea necesario; concedido que esto sería complicado.

@gauravmanchanda

Nos ayudó a mantener las bibliotecas / configuración en una sola ubicación y copiarlas, pero ahora hay problemas con .dockerignore se ignoran, sin importar dónde lo coloque.
Funciona cuando solo estoy usando Docker con la nueva opción DOCKER_BUILDKIT , pero no funciona cuando uso docker-compose, probé COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose build , pero aún así no funcionó. ¿Algunas ideas?

¡Me alegro de que las compilaciones de varias etapas hayan ayudado! ¿Qué versión de Docker y de docker-compose estás usando? Probaría con la última versión y vería si el problema persiste. Debe respetar el archivo .dockerignore.

@Marandil , parece que docker build no está manejando la estructura de su proyecto (es decir, la estructura del directorio), que es el problema. Es posible que pueda usar algo como docker buildx bake (https://github.com/docker/buildx) para resolver este caso de uso. Tenga en cuenta que se está trabajando en buildx, por lo que aún no es súper estable, pero su objetivo es resolver algo de lo que está golpeando.

@itscaro , ¡gracias por tu aporte! Lo que hacemos internamente para generar cosas en contenedores es usar docker build para generar el resultado de una imagen FROM scratch . Esto solo funciona en los casos en que necesita la salida de un solo contenedor.

@TrentonAdams hemos estado trabajando para mejorar el rendimiento del sistema de archivos para Docker Desktop, pero es complicado. El problema subyacente es atravesar el límite de la VM. Los bits de intercambio de archivos se han reescrito recientemente (puede habilitar la nueva experiencia usando la opción "Usar gRPC FUSE para compartir archivos" en las preferencias) y esto debería resolver algunos de los problemas de alto uso de CPU que la gente había estado viendo. Tenemos algo de documentación sobre el ajuste del rendimiento aquí y aquí .

@ chris-crone

@Marandil , parece que docker build no está manejando la estructura de su proyecto (es decir, la estructura del directorio), que es el problema. Es posible que pueda usar algo como docker buildx bake (https://github.com/docker/buildx) para resolver este caso de uso. Tenga en cuenta que se está trabajando en buildx, por lo que aún no es súper estable, pero su objetivo es resolver algo de lo que está golpeando.

Gracias, miraré docker buildx bake . Parece prometedor, pero no pude encontrar ninguna buena referencia ni documentación al respecto, y las páginas de docs.docker.com son bastante simples (consulte https://docs.docker.com/engine/reference/commandline/buildx_bake /). Hasta ahora encontré https://twitter.com/tonistiigi/status/1290379204194758657 haciendo referencia a un par de ejemplos (https://github.com/tonistiigi/fsutil/blob/master/docker-bake.hcl, https: // github .com / tonistiigi / binfmt / blob / master / docker-bake.hcl), que puede ser un buen punto de partida, pero difícilmente una buena referencia.

@TrentonAdams hemos estado trabajando para mejorar el rendimiento del sistema de archivos para Docker Desktop, pero es complicado. El problema subyacente es atravesar el límite de la VM. Los bits de intercambio de archivos se han reescrito recientemente (puede habilitar la nueva experiencia usando la opción "Usar gRPC FUSE para compartir archivos" en las preferencias) y esto debería resolver algunos de los problemas de alto uso de CPU que la gente había estado viendo. Tenemos cierta documentación sobre el ajuste del rendimiento aquí y aquí.

@ chris-crone Infierno sí, ¡muchas gracias! Hay una mejora de 3-4 s con la nueva opción, y el uso de "caché" me da el mismo rendimiento que ejecutar fuera del contenedor, así que esto es ENORME para mí. Veo tiempos tan bajos como 2800ms de tiempo de inicio para nuestra aplicación, por lo que ya no son 11-18. ¡HURRA! No necesito nada más que almacenar en caché, porque de todos modos solo estoy recreando los contenedores cada vez.

@ chris-crone ¿Hay algún lugar en el que deba publicar material de rendimiento para ayudar con el ajuste del rendimiento y los comentarios en MacOS? Me pregunto por qué un contenedor recién iniciado con montaje de enlace sería lento cuando no se usa cached . ¿Debe haber algo extraño en el que vaya y venga verificando cada archivo al inicio si están sincronizados, incluso cuando es nuevo?

Caso de uso: ejecuto un contenedor y modifica un archivo (específicamente, Keycloak modifica su archivo de configuración según las variables de entorno, etc.). Quiero una copia de ese archivo en mi disco local para poder verificar el resultado de esa modificación y realizar un seguimiento de mi progreso a lo largo del tiempo a medida que modifico los scripts del contenedor. Actualmente, necesito encontrar el nuevo ID de contenedor cada vez para poder usar docker cp .

Caso de uso:
desarrollo en docker.
Necesito volver a propagar mi archivo de bloqueo a la máquina host o se sobrescribirá cuando el contenedor monte la carpeta del proyecto.

Caso de uso: necesito copiar un archivo que contiene una clave secreta. La aplicación que se ejecuta dentro del contenedor lee ese archivo en la memoria y lo elimina del disco.

Caso de uso: estoy ejecutando pruebas unitarias de c ++ en un contenedor docker. Quiero simplemente copiar el código a una imagen existente en cada ejecución.

1) Hacer esto con un dockerfile separado COPY significa que el código se escribe en una imagen nueva e innecesaria y necesito eliminar esa imagen para asegurar que la siguiente ejecución cree una nueva imagen con el código más reciente.

2) Hacer esto con docker-compose volumes yaml config significa que Docker usa el código fuente como root:rooteliminando totalmente mi IDE de hacer ediciones hasta que lo devuelva!)

@ shin- ¿estoy siguiendo un anti-patrón al ejecutar pruebas unitarias en un contenedor? ¿Cuál es la forma no anti-patrón en la que resolvería esto?

.... Me quedo con la opción 1, ya que es la menos dolorosa. ¡Pero veo que docker-compose admitir una configuración de copia es una mejora tan impresionante! ¡al menos para este flujo de trabajo!

@soulseekah ¿No es mejor usar secretos en la redacción para ese caso de uso?

Encontré una solución que funciona para mí:

  1. Crea el Dockerfile con
    COPY a_filename .
  2. Construye la imagen usando el Dockerfile
    docker build -t myproject:1.0 .
  3. Edite el docker-compose para usar la imagen que acaba de crear
version: "3.7"
services:
  app:
    image: myproject:1.0
    ports:
      - 3000:3000
    networks:
       - mynetwork
       - internal
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: not_so_secret_password # don't do this 
      # https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/
      MYSQL_DB: appdb
    deploy:
      resources:
        limits:
          cpus: '0.75'
          memory: 100M

No es una solución perfecta, pero funciona en mi caso de uso.

@soulseekah ¿No es mejor usar secretos en la redacción para ese caso de uso?

Desafortunadamente, eso requiere enjambre la última vez que lo intenté :(

@soulseekah ¿No es mejor usar secretos en la redacción para ese caso de uso?

Desafortunadamente, eso requiere enjambre la última vez que lo intenté :(

@soulseekah ¿ Quizás usar la solución que yo uso (arriba de ti)?

@ChristophorusReyhan, el problema con esa solución se indica en el comentario de @zoombinis :

Hacer esto con una COPIA de dockerfile separada significa que el código se escribe en una imagen nueva e innecesaria y necesito eliminar esa imagen para asegurar que la próxima ejecución cree una nueva imagen con el código más reciente.

Si bien es una solución funcional, puede dar lugar a un mantenimiento no deseado. Por ejemplo, para limpiar la imagen no deseada _ mientras también conserva las imágenes que le interesan_:

docker-compose up && docker-compose down --rmi local

Pero asegúrese de que todas las imágenes que le interesan tengan una etiqueta personalizada y que la imagen de prueba / ficticia no

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