skip to Main Content

For the sake of simplicity, let’s say I have the following structure in the source image:

files/
    folder1/
        file1
        file2
    folder2/
        file1
        file2

I want to have a result where only the directory structure is copied to my other image during build. The result should therefore look like this:

files/
    folder1/
    folder2/

How can this be achieved?

Background: You might ask why I want to do this. Well, in reality the directory structure is much more complex and I need to maintain consistency between both source and destination image. And as there are significant amounts of data in the source image I cannot simply copy over everything and then remove the files (as this would take a lot of time).

2

Answers


  1. Chosen as BEST ANSWER

    Actually Pádraig Galvin and KamilCuk pointed to what I wanted to achieve. This how I did it in the end:

    # Some dummy image that would hold data in real life
    FROM alpine:latest AS some_image
    RUN mkdir -p /my/dir/structure/is/deep
    
    # Export the folder structure
    FROM some_image AS source
    RUN find /my -type d > dir_export.txt
    
    # Import to destination image
    FROM alpine:latest AS destination
    COPY --from=source ./dir_export.txt /.
    RUN xargs mkdir -p < /dir_export.txt
    RUN rm /dir_export.txt
    

    It gives the same structure in "some_image" and "destination":

    / # tree my
    my
    └── dir
        └── structure
            └── is
                └── deep
    

  2. How can this be achieved?

    Dynamic programming:

    1. get the list of directories
    2. create them

    So something along:

    (cd dir1 && find . -depth -type d) | (cd dir2 && xargs mkdir -p)
    

    The specifics, programming language, the representation of "the list of directories", quoting and anything may change – the algorithm stays.

    You can do it better by zero separated list:

    (cd dir1 && find . -depth -type d -print0) | (cd dir2 && xargs -0 mkdir -p)
    

    And you can prepend docker to it:

    docker exec image1 sh -c 'cd dir1 && find . -depth -type d -print0' | docker exec -i image2 sh -c 'cd dir2 && xargs -0 mkdir -p'
    

    Or you could save the list to a file and then use it in dockerfile:

    # on host
    $ docker run -ti --rm image1 sh -c 'cd dir1 && find . -depth -type d -print0' > dirlist.bin
    
    # in Dockerfile
    COPY dirlist.bin ./
    RUN cd dir2 && xargs -0 mkdir -p <dirlist.bin
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search