¿Cuál es la diferencia entre los comandos COPYy ADDen un Dockerfile y cuándo usaría uno sobre el otro?
COPY <src> <dest>
La instrucción COPY copiará nuevos archivos
<src>y los agregará al sistema de archivos del contenedor en la ruta<dest>
ADD <src> <dest>
La instrucción ADD copiará nuevos archivos
<src>y los agregará al sistema de archivos del contenedor en la ruta<dest>.
docker
dockerfile
Steve
fuente
fuente

COPYque se ejecute cada vez que se ejecuta, porque no necesariamente tiene acceso al contexto original para obtener el contenido.Respuestas:
Usted debe comprobar el
ADDyCOPYdocumentación para una descripción más detallada de sus comportamientos, pero en pocas palabras, la diferencia principal es queADDse puede hacer algo más queCOPY:ADDpermite<src>ser una URLADDdocumentación establece que:Tenga en cuenta que las mejores prácticas para escribir Dockerfiles sugieren usar
COPYdondeADDno se requiere la magia de . De lo contrario, usted ( ya que tuvo que buscar esta respuesta ) probablemente se sorprenda algún día cuando quiera copiarkeep_this_archive_intact.tar.gzen su contenedor, pero en su lugar, rocíe el contenido en su sistema de archivos.fuente
If <src> is a local tar archive in a recognized compression format (identity, gzip, bzip2 or xz) then it is unpacked as a directory. Resources from remote URLs are not decompressed.Docker ADDCOPYesReferencia directamente desde el código fuente .
fuente
ADDtambién crea directorios no existentes . Así, a pesar de que de alguna manera se desaconseja en todo este hilo, tiene una ventaja sobreCOPY, ya que no tiene que corrermkdiry ahorrar algo de mecanografíaHay algo de documentación oficial sobre ese punto: Mejores prácticas para escribir archivos Docker
fuente
COPY, porque es más transparente. De las mejores prácticas del archivo Docker (15/12/2014):Although ADD and COPY are functionally similar, generally speaking, COPY is preferred. That’s because it’s more transparent than ADD. COPY only supports the basic copying of local files into the container, while ADD has some features that are not immediately obvious.De los documentos de Docker:
Más: Mejores prácticas para escribir Dockerfiles
fuente
Si desea agregar un xx.tar.gz a un
/usr/localcontenedor de entrada, descomprímalo y luego retire el paquete comprimido inútil.Para COPIA:
Para añadir:
ADD admite extracción de alquitrán solo local. Además, COPY usará tres capas, pero ADD solo usa una capa.
fuente
RUN tar -zxvf /tmp/jdk-7u79-linux-x64.tar.gz -C /usr/local && rm /tmp/jdk-7u79-linux-x64.tar.gzCOPYcopia un archivo / directorio de su host a su imagen.ADDcopia un archivo / directorio de su host a su imagen, pero también puede buscar URL remotas, extraer archivos TAR, etc.Úselo
COPYsimplemente para copiar archivos y / o directorios en el contexto de compilación.Utilícelo
ADDpara descargar recursos remotos, extraer archivos TAR, etc.fuente
Desde Docker docs: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy
"Aunque ADD y COPY son funcionalmente similares, en términos generales, se prefiere COPY. Esto se debe a que es más transparente que ADD. COPY solo admite la copia básica de archivos locales en el contenedor, mientras que ADD tiene algunas características (como extracción de alquitrán solo local y soporte remoto de URL) que no son inmediatamente obvios. En consecuencia, el mejor uso para ADD es la extracción automática de archivos tar locales en la imagen, como en ADD rootfs.tar.xz /.
Si tiene varios pasos de Dockerfile que usan diferentes archivos de su contexto, COPIELOS individualmente, en lugar de todos a la vez. Esto garantizará que la memoria caché de compilación de cada paso solo se invalide (obligando a que el paso se vuelva a ejecutar) si cambian los archivos específicamente requeridos.
Por ejemplo:
Resulta en menos invalidaciones de caché para el paso EJECUTAR, que si coloca COPIA. / tmp / antes de eso.
Debido a que el tamaño de la imagen es importante, se desaconseja usar ADD para recuperar paquetes de URL remotas; deberías usar curl o wget en su lugar. De esa manera, puede eliminar los archivos que ya no necesita después de que se hayan extraído y no tendrá que agregar otra capa en su imagen. Por ejemplo, debe evitar hacer cosas como:
Y en cambio, haz algo como:
Para otros elementos (archivos, directorios) que no requieren la capacidad de extracción automática de tar del ADD, siempre debe usar COPY ".
fuente
Fuente: https://nickjanetakis.com/blog/docker-tip-2-the-difference-between-copy-and-add-in-a-dockerile :
fuente
Al crear un Dockerfile, hay dos comandos que puede usar para copiar archivos / directorios en él,
ADDyCOPY. Aunque existen ligeras diferencias en el alcance de su función, esencialmente realizan la misma tarea.Entonces, ¿por qué tenemos dos comandos y cómo sabemos cuándo usar uno u otro?
ESTIBADOR
ADDCOMANDOComencemos notando que el
ADDcomando es anterior aCOPY. Desde el lanzamiento de la plataforma Docker, elADDinstrucción ha sido parte de su lista de comandos.El comando copia archivos / directorios a un sistema de archivos del contenedor especificado.
La sintaxis básica para el
ADDcomando es:Incluye la fuente que desea copiar (
<src>) seguido del destino donde desea almacenarlo (<dest>). Si la fuente es un directorio,ADDcopia todo lo que contiene (incluidos los metadatos del sistema de archivos).Por ejemplo, si el archivo está disponible localmente y desea agregarlo al directorio de una imagen, escriba:
ADDTambién puede copiar archivos desde una URL. Puede descargar un archivo externo y copiarlo en el destino deseado. Por ejemplo:Una característica adicional es que copia archivos comprimidos, extrayendo automáticamente el contenido en el destino dado. Esta característica solo se aplica a los archivos / directorios comprimidos almacenados localmente.
Tenga en cuenta que no puede descargar y extraer un archivo / directorio comprimido de una URL. El comando no desempaqueta los paquetes externos al copiarlos en el sistema de archivos local.
ESTIBADOR
COPYCOMANDODebido a algunos problemas de funcionalidad, Docker tuvo que introducir un comando adicional para duplicar contenido
COPY.A diferencia de su
ADDcomando estrechamente relacionado ,COPYsolo tiene una función asignada. Su función es duplicar archivos / directorios en una ubicación específica en su formato existente. Esto significa que no se trata de extraer un archivo comprimido, sino que lo copia tal como está.La instrucción solo se puede utilizar para archivos almacenados localmente. Por lo tanto, no puede usarlo con URL para copiar archivos externos a su contenedor.
Para usar la
COPYinstrucción, siga el formato de comando básico:Escriba la fuente y dónde desea que el comando extraiga el contenido de la siguiente manera:
Por ejemplo:
¿Qué comando usar? (Mejor práctica)
Teniendo en cuenta las circunstancias en que
COPYse introdujo el comando, es evidente que mantenerloADDera una cuestión de necesidad. Docker lanzó un documento oficial que describe las mejores prácticas para escribir Dockerfiles, que explícitamente desaconseja el uso deADDcomando.La documentación oficial de Docker señala que
COPYsiempre debe ser la instrucción de acceso, ya que es más transparente queADD.Si necesita copiar del contexto de compilación local en un contenedor, siga usando
COPY.El equipo de Docker también desaconseja el uso
ADDpara descargar y copiar un paquete desde una URL. En cambio, es más seguro y más eficiente usar wget o curl dentro de unRUNcomando. Al hacerlo, evita crear una capa de imagen adicional y ahorra espacio.fuente
Nota IMPORTANTE
Tuve que
COPYdescomprimir el paquete de Java en mi imagen acoplable. Cuando comparé el tamaño de la imagen acoplada creado con ADD, era 180 MB más grande que el creado con COPY, tar -xzf * .tar.gz y rm * .tar.gzEsto significa que aunque ADD elimina el archivo tar, todavía se mantiene en algún lugar. ¡Y está haciendo la imagen más grande!
fuente
Dado que Docker 17.05
COPYse usa con el--fromindicador en compilaciones de varias etapas para copiar artefactos de etapas de compilación anteriores a la etapa de compilación actual.de la documentación
fuente
Esta es otra forma de copiar archivos en una imagen. La opción -v crea temporalmente un volumen que usamos durante el proceso de compilación.
Esto es diferente a otros volúmenes porque monta un directorio de host solo para la compilación. Los archivos se pueden copiar usando un comando cp estándar.
Además, como curl y wget, se puede ejecutar en una pila de comandos (se ejecuta en un solo contenedor) y no multiplicar el tamaño de la imagen. ADD y COPY no son apilables porque se ejecutan en un contenedor independiente y los comandos posteriores en aquellos archivos que se ejecutan en contenedores adicionales multiplicarán el tamaño de la imagen:
Con las opciones configuradas así:
Lo siguiente se ejecutará en un contenedor:
fuente
unknown shorthand flag: 'v' in -v