Docker COPY/ADD kopiert keine Unterschiede mehr?

Docker COPY/ADD kopiert keine Unterschiede mehr?

Ich habe lange Zeit eine App mit Docker und einem Zwischencontainer erstellt, z. B. würde ich einen Build erstellen, myapp:basein den alle Kerndateien kopiert wurden:

FROM ubuntu:17.10
ADD app /app

Nun kann der Hauptcontainer myapp:releaseeinfach mit diesem erstellt werden

 FROM myapp:base 
 ADD app /app

Möglicherweise werden einige Dateien im appVerzeichnis geändert, und ich hätte am Ende eine kleine zusätzliche Ebene.

Vor kurzem hat dieses Finale jedoch ADDzu einer viel größeren Schicht geführt, und ich vermute, dass es mit einem Docker-Update zusammenhängt (ich verwende Docker-Version 18.02.0-ce, Build fc4de44).

Hat sich etwas daran geändert, wie Docker herausfindet, was anders ist? Wie kann ich zu einem effizienten Build zurückkehren, das nur eine kleine Anzahl aktualisierter Dateien in einer Ebene enthält?

Schritte zum Reproduzieren:

# make a dummy dir with a 64kb file in it

mkdir -p files
truncate -s 64k files/64k.file

# base container has a copy of the files

cat << EOF > Dockerfile.base
FROM ubuntu:16.04
COPY files/ /root/
EOF

# derived container should just have any updates

cat << EOF > Dockerfile.derived
FROM q899941:base
COPY files/ /root/
EOF

# build them....

docker build --file Dockerfile.base -t  q899941:base .
docker build --file Dockerfile.derived -t  q899941:derived .

# now let's review the layers

docker history q899941:derived

Ich erhalte dieses Ergebnis

IMAGE               CREATED                  CREATED BY                                      SIZE  
4e1eb5168d55        Less than a second ago   /bin/sh -c #(nop) COPY dir:8e20ede288278c71e…   65.5kB
022626ac5cf0        Less than a second ago   /bin/sh -c #(nop) COPY dir:8e20ede288278c71e…   65.5kB
0458a4468cbc        5 weeks ago              /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B    
<missing>           5 weeks ago              /bin/sh -c mkdir -p /run/systemd && echo 'do…   7B    
<missing>           5 weeks ago              /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$…   2.76kB
<missing>           5 weeks ago              /bin/sh -c rm -rf /var/lib/apt/lists/*          0B    
<missing>           5 weeks ago              /bin/sh -c set -xe   && echo '#!/bin/sh' > /…   745B  
<missing>           5 weeks ago              /bin/sh -c #(nop) ADD file:a3344b835ea6fdc56…   112MB

Die oberste Ebene ist 64 KB groß, obwohl sich keine Dateien geändert haben.

Antwort1

Es scheint, dies ist einbekanntes Problem, aber nicht eines, das genügend Leute interessiert!

Ich habe schließlich eine einfache Sache gemacht, die in einem derKommentareim Fehlerbericht:

#clean up any previous attempt...

docker rm -f uniquename 2> /dev/null

# now take your base container, mount the updated dir as /src 
# then rsync from /src to the target dir - only updated files will
# actually be written, and we use --delete to ensure removed files are
# taken out...

docker run --name uniquename \
    -v ~/repo/mycode:/src \
    ${REPO}/${IMAGE}:${BASE} \
        rsync -ar --no-owner --no-group \
        --exclude-from '/src/.dockerignore' --delete \
        /src/ /app/

# we can commit that updated container with a tag 

docker commit uniquename ${REPO}/${IMAGE}:${NEW_TAG}

Noch etwas: Diese Lösung schien die vorhandene zu löschen CMD, die den Standardstartbefehl für meine Container bereitstellte. Nachdem ich diese Diff-Ebene hinzugefügt hatte, hatte ich also eine weitere Docker-Datei, um einen Container aus dem obigen „Diff“-Build mit dem CMDhinzugefügten wieder zu erstellen.

verwandte Informationen