Victor
Victor

Reputation: 3698

ADD and COPY to merge the contents of a dir with the one already on the build

I am trying to assemble an image with some files that are stored along with my dockerfile. What I expect with COPY or ADD is a merge behavior. However, the file hierarchy is overwritten if I use theses instructions. As such, files from the parent image are no longer available if they were within the path. (huge issue if for instance I was to save some file on /etc/mycoolstuff/filehere)

When this happens I am not able to use apt-get any more

I also saw some advice to convert my files to a tar packaged, but nothing different was observed.

For clarity, this was one of the issues(builds if I change the order, but it ends broken anyway cause child images will not be able to use apt any longer):

ADD     build/image-base.tgz /
RUN     apt-get clean -y && \
            apt-get update && \
            apt-get install unzip -y --no-install-recommends && \
            apt-get install gosu -y --no-install-recommends && \
            apt-get clean -y && \
            apt-get autoclean -y && \
            apt-get autoremove -y && \
            rm -rf /var/lib/apt/lists/*

Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial/InRelease Temporary failure resolving 'archive.ubuntu.com'
Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial-updates/InRelease Temporary failure resolving 'archive.ubuntu.com'
Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial-backports/InRelease Temporary failure resolving 'archive.ubuntu.com'
Failed to fetch http://security.ubuntu.com/ubuntu/dists/xenial-security/InRelease Temporary failure resolving 'security.ubuntu.com'
Failed to fetch http://ppa.launchpad.net/webupd8team/java/ubuntu/dists/xenial/InRelease 
Temporary failure resolving 'ppa.launchpad.net'
Some index files failed to download. They have been ignored, or old ones used instead.

Upvotes: 6

Views: 9226

Answers (4)

Peter L
Peter L

Reputation: 3361

I'm using Azure DevOps Pipelines (windows agent) as well as Docker Desktop for Windows and find the merge happens automatically. Perhaps you should update your Docker version or try again to see if the merge is indeed happening as desired.

Upvotes: 1

evgeniy.klemin
evgeniy.klemin

Reputation: 188

Docker has multi-stage builds since 17.05: Use multi-stage builds

FROM busybox as builder
ADD build/image-base.tgz /tmproot/

FROM alpine:latest  
...
COPY --from=builder /tmproot /
...

Another example:

FROM busybox as builder
COPY src/etc/app /tmproot/etc/app
COPY src/app /tmproot/usr/local/app

FROM alpine:latest  
...
COPY --from=builder /tmproot /
...

Upvotes: 4

Victor
Victor

Reputation: 3698

After some digging I was able to find a workaround with COPY and a RUN to achieved the behavior I was looking for.

COPY    build/image-base.tgz /

RUN     tar -xvf image-base.tgz --no-overwrite-dir 

Unfortunately this creates a new layer and the base tar will remain there. It is not a bit issue if it is just some text config files.

A weird way to get around the COPY instruction was to use wget, and untar afterwards, so we can delete the tar file. wget will do the trick if we are on a build environment where artifacts are stored and URLs created for them...in that scenario we just need one RUN, keeping the house clean.

Upvotes: 3

Ricardo Branco
Ricardo Branco

Reputation: 6079

What are you trying to achieve? Do you really want to overwrite the root directory? Then you better build images from scratch. To do this, your Dockerfile must begin with FROM scratch

An official Docker tutorial on the subject, with scripts for multiple distros:

https://docs.docker.com/engine/userguide/eng-image/baseimages/

Upvotes: 2

Related Questions