Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dockerfile COPY and keep folder structure

I'm trying to create a Dockerfile that copies all package.json files into the image but keeps the folder structure.

This what I have now:

FROM node:15.9.0-alpine as base
WORKDIR /app/
COPY ./**/package.json ./
CMD ls -laR /app

Running with: sudo docker run --rm -it $(sudo docker build -q .) But it only copies 1 package.json and puts it in the base dir (/app)

Here is the directory I'm testings on:

├── Dockerfile
├── t1
│   └── package.json
└── t2
    └── ttt
        ├── b.txt
        └── package.json

And i would like it to look like this inside the container:

├── Dockerfile
├── t1
│   └── package.json
└── t2
    └── ttt
        └── package.json
like image 403
CY-OD Avatar asked May 19 '26 22:05

CY-OD


2 Answers

After a lot of searching around, I managed to find a solution that works for me

I ended up creating a tar of all the package.json files

tar --exclude node_modules -cf package.json.tar  */package.json

And using the docker add command to unpack that tar inside the image

ADD package.json.tar .

The add command will detect that the input is a tar file, and will extract it inside the image.

The down side of using this approach is you have to run the tar command sometime before you build the image.

like image 55
CY-OD Avatar answered May 22 '26 13:05

CY-OD


The Dockerfile COPY directive is documented as using the Go filepath.Match function for glob expansion. That only supports the basic glob characters *, ?, [a-z], but not extensions like ** that some shells support.

Since COPY only takes a filename glob as input and it likes to flatten the file structure, I don't think there's a way to do the sort of selective copy you're describing in a single command.

Instead you need to list out the individual files you want to copy. COPY will create directories as needed, but that means you need to repeat paths on both sides of COPY.

COPY t1/package*.json t1/
COPY t2/ttt/package*.json t2/ttt/

I can imagine some hacky approaches using multi-stage builds; have an initial stage that copies in the entire source tree but then deletes all of the files except package*.json, then copies that into the actual build stage. I'd contemplate splitting my repository into smaller modules with separate Dockerfiles per module first.

like image 38
David Maze Avatar answered May 22 '26 11:05

David Maze