¿Cómo puedo incluir archivos desde fuera del contexto de compilación de Docker usando el comando "AGREGAR" en el archivo Docker?
De la documentación de Docker:
La ruta debe estar dentro del contexto de la compilación; no puede AGREGAR ../something/something, porque el primer paso de una compilación de docker es enviar el directorio de contexto (y subdirectorios) al demonio de docker.
No quiero reestructurar todo mi proyecto solo para acomodar a Docker en este asunto. Quiero mantener todos mis archivos Docker en el mismo subdirectorio.
Además, parece que Docker aún no admite (y puede que nunca lo haga ) los enlaces simbólicos: el comando ADD de Dockerfile no sigue los enlaces simbólicos en el host # 1676.
Lo único que se me ocurre es incluir un paso previo a la compilación para copiar los archivos en el contexto de compilación de Docker (y configurar mi control de versiones para ignorar esos archivos). ¿Hay una mejor solución para eso?
FROM
para continuar desde allí. No cambiaría la estructura del proyecto para acomodar Docker (ni ninguna herramienta de compilación).Respuestas:
La mejor manera de evitar esto es especificar el Dockerfile independientemente del contexto de compilación, usando -f.
Por ejemplo, este comando le dará acceso al comando ADD a cualquier cosa en su directorio actual.
Actualización : Docker ahora permite tener el Dockerfile fuera del contexto de compilación (corregido en 18.03.0-ce, https://github.com/docker/cli/pull/886 ). Entonces también puedes hacer algo como
fuente
dockerfile:
propiedad en labuild:
sección del archivo de composición docs.docker.com/compose/compose-file/#/compose-file-referenceADD
un archivo que está fuera del directorio de contexto? Eso es lo que intento hacer, pero no creo que el uso-f
haga que los archivos externos se puedan agregar.build: context: .., dockerfile: dir/Dockerfile
. ¡Ahora mi contexto de compilación es el directorio principal!A menudo me encuentro utilizando la
--build-arg
opción para este propósito. Por ejemplo, después de poner lo siguiente en el Dockerfile:Solo puedes hacer:
Pero tenga en cuenta la siguiente advertencia de la documentación de Docker :
Advertencia: no se recomienda utilizar variables de tiempo de compilación para pasar secretos como claves github, credenciales de usuario, etc. Los valores de las variables de tiempo de compilación son visibles para cualquier usuario de la imagen con el comando docker history.
fuente
En Linux, puede montar otros directorios en lugar de simularlos
Consulte /superuser/842642 para obtener más detalles.
No sé si hay algo similar disponible para otros sistemas operativos. También intenté usar Samba para compartir una carpeta y volver a montarla en el contexto de Docker, que también funcionó.
fuente
Pasé un buen rato tratando de descubrir un buen patrón y cómo explicar mejor lo que está sucediendo con esta función de soporte. Me di cuenta de que la mejor manera de explicarlo era la siguiente ...
Entonces, dicho esto, aquí hay un ejemplo del Dockerfile que necesita reutilizar un archivo llamado
start.sh
Dockerfile
Se
ALWAYS
cargará desde su ruta relativa, teniendo el directorio actual de sí mismo comolocal
referencia a las rutas que especifique.Archivos
Teniendo en cuenta esta idea, podemos pensar en tener múltiples copias para los Dockerfiles que compilan elementos específicos, pero todos necesitan acceso al
start.sh
.Teniendo en cuenta esta estructura y los archivos anteriores, aquí hay un docker-compose.yml
docker-compose.yaml
shared
directorio de contexto es elruntime
directorio.context
.dockerfile
.El
docker-compose.yml
es el siguienteall-service
se establece como contexto, el archivo compartidostart.sh
se copia allí y el Dockerfile especificado por cada unodockerfile
.¡Salud!
fuente
a/b/c
, a continuación, ejecutar sídocker build .
enc
no le permitirá el acceso../file-in-b
. Pero, creo que el malentendido general en esto (o al menos el mío fue) es que el contexto se define por la ubicación establecida por el primer argumento del comando de compilación, no por la ubicación del Dockerfile. Entonces, como se indica en la respuesta aceptada: froma
:docker build -f a/b/c/Dockerfile .
significa que en el Dockerfile.
ahora está la carpetaa
Si lee la discusión en el número 2745, no solo Docker nunca admitirá enlaces simbólicos, sino que nunca admitirá agregar archivos fuera de su contexto. Parece ser una filosofía de diseño que los archivos que entran en la construcción de Docker deberían ser explícitamente parte de su contexto o ser de una URL donde presumiblemente también se implementa con una versión fija para que la construcción sea repetible con URL o archivos bien conocidos enviados con el contenedor acoplable.
Solo es mi opinión, pero creo que debería reestructurarse para separar el código y los repositorios de Docker. De esa manera, los contenedores pueden ser genéricos y extraer cualquier versión del código en tiempo de ejecución en lugar de en tiempo de compilación.
Alternativamente, use docker como su artefacto fundamental de implementación de código y luego coloque el dockerfile en la raíz del repositorio de código. si sigue esta ruta, probablemente tenga sentido tener un contenedor acoplable principal para obtener detalles más generales del nivel del sistema y un contenedor secundario para la configuración específica de su código.
fuente
Creo que la solución más simple sería cambiar el "contexto" en sí.
Entonces, por ejemplo, en lugar de dar:
que establece el directorio actual como contexto, digamos que desea el directorio principal como contexto, solo use:
fuente
make build
y extrae todos los archivos necesarios si se actualizaron y luego llama a la construcción de acoplador apropiada ... Necesito hacer un trabajo extra, pero funciona a la perfección porque tengo el control total.También puede crear un tarball de lo que la imagen necesita primero y usarlo como contexto.
https://docs.docker.com/engine/reference/commandline/build/#/tarball-contexts
fuente
tar zc /dir1 /dir2 |docker build -
. Esto fue muy útil en mi caso.Usando docker-compose, logré esto creando un servicio que monta los volúmenes que necesito y confirmando la imagen del contenedor. Luego, en el servicio posterior, confío en la imagen previamente comprometida, que tiene todos los datos almacenados en ubicaciones montadas. Luego tendrá que copiar estos archivos a su destino final, ya que los directorios montados en el host no se comprometen al ejecutar un
docker commit
comandofuente
Tuve este mismo problema con un proyecto y algunos archivos de datos que no pude mover dentro del contexto de repositorio por razones de HIPPA. Terminé usando 2 Dockerfiles. Uno construye la aplicación principal sin las cosas que necesitaba fuera del contenedor y las publica en un repositorio interno. Luego, un segundo dockerfile extrae esa imagen y agrega los datos y crea una nueva imagen que luego se implementa y nunca se almacena en ningún lugar. No es ideal, pero funcionó para mis propósitos de mantener la información confidencial fuera del repositorio.
fuente
Una solución fácil podría ser simplemente montar el volumen (usando el indicador -v o --mount) en el contenedor cuando lo ejecute y acceda a los archivos de esa manera.
ejemplo:
para más información, consulte: https://docs.docker.com/storage/volumes/
fuente
docker run
es demasiado tarde.Como se describe en este problema de GitHub, la compilación realmente sucede
/tmp/docker-12345
, por lo que una ruta../relative-add/some-file
relativa es relativa a/tmp/docker-12345
. Por lo tanto, buscaría/tmp/relative-add/some-file
, lo que también se muestra en el mensaje de error. *No está permitido incluir archivos desde fuera del directorio de compilación, por lo que esto da como resultado el mensaje "Ruta prohibida".
fuente
Una manera rápida y sucia es configurar el contexto de construcción tantos niveles como sea necesario, pero esto puede tener consecuencias. Si está trabajando en una arquitectura de microservicios que se ve así:
Puede establecer el contexto de compilación en el
Code
directorio principal y luego acceder a todo, pero resulta que con una gran cantidad de repositorios, esto puede hacer que la compilación tarde mucho tiempo.Una situación de ejemplo podría ser que otro equipo mantiene un esquema de base de datos
Repo1
y el código de su equipo enRepo2
depende de esto. Desea reducir esta dependencia con algunos de sus propios datos semilla sin preocuparse por los cambios de esquema o contaminar el repositorio del otro equipo (dependiendo de cuáles sean los cambios, es posible que tenga que cambiar sus scripts de datos semilla, por supuesto). El segundo enfoque es hacky pero evita el problema de las compilaciones largas:Cree un script sh (o ps1)
./Code/Repo2
para copiar los archivos que necesita e invoque los comandos del acoplador que desee, por ejemplo:En el archivo docker-compose, simplemente configure el contexto como
Repo2
root y use el contenido del./db/schema
directorio en su dockerfile sin preocuparse por la ruta. Tenga en cuenta que correrá el riesgo de comprometer accidentalmente este directorio con el control de origen, pero las acciones de limpieza de secuencias de comandos deberían ser bastante fáciles.fuente
En mi caso, mi Dockerfile está escrito como una plantilla que contiene marcadores de posición que estoy reemplazando con un valor real usando mi archivo de configuración.
Por lo tanto, no pude especificar este archivo directamente, pero lo canalizo en la construcción de Docker de esta manera:
Pero debido a la tubería, el
COPY
comando no funcionó. Pero la forma anterior lo resuelve-f -
(diciendo explícitamente que el archivo no se proporciona). Prescindiendo solo de-
la-f
bandera, no se proporcionan el contexto Y el Dockerfile, lo cual es una advertencia.fuente
El truco consiste en reconocer que puede especificar el contexto en el comando de compilación para incluir archivos del directorio principal si especifica la ruta de Docker, cambiaría mi Dockerfile para que se vea así:
Entonces mi comando de compilación puede verse así:
Desde el directorio del proyecto
Del proyecto / acoplador
fuente