Docker COPY files using glob pattern?
There is a solution based on multistage-build feature:
FROM node:12.18.2-alpine3.11
WORKDIR /app
COPY ["package.json", "yarn.lock", "./"]
# Step 2: Copy whole app
COPY packages packages
# Step 3: Find and remove non-package.json files
RUN find packages \! -name "package.json" -mindepth 2 -maxdepth 2 -print | xargs rm -rf
# Step 4: Define second build stage
FROM node:12.18.2-alpine3.11
WORKDIR /app
# Step 5: Copy files from the first build stage.
COPY --from=0 /app .
RUN yarn install --frozen-lockfile
COPY . .
# To restore workspaces symlinks
RUN yarn install --frozen-lockfile
CMD yarn start
On Step 5
the layer cache will be reused even if any file in packages
directory has changed.
How to copy multiple files in one layer using a Dockerfile?
COPY README.md package.json gulpfile.js __BUILD_NUMBER ./
or
COPY ["__BUILD_NUMBER", "README.md", "gulpfile", "another_file", "./"]
You can also use wildcard characters in the sourcefile specification. See the docs for a little more detail.
Directories are special! If you write
COPY dir1 dir2 ./
that actually works like
COPY dir1/* dir2/* ./
If you want to copy multiple directories (not their contents) under a destination directory in a single command, you'll need to set up the build context so that your source directories are under a common parent and then COPY
that parent.
docker copy all files in directory with given extention
I don't think you can do this with docker cp command
To do this you can mount the directory inside the docker and then you can run the regular cp command with regex to copy it to another directory.
Mount:
docker run -d --name containerName -v myvol2:/app imageName:tag
Inside Container:
cp app/*.pdf /destination
dockerfile copy list of files, when list is taken from a local file
Not possible in the sense that the COPY
directive allows it out of the box, however if you know the extensions you can use a wildcard for the path such as COPY folder*something*name somewhere/
.
For simple requirements.txt
fetching that could be:
# but you need to distinguish it somehow
# otherwise it'll overwrite the files and keep the last one
# e.g. rename package/requirements.txt to package-requirements.txt
# and it won't be an issue
COPY */requirements.txt ./
RUN for item in $(ls requirement*);do pip install -r $item;done
But if it gets a bit more complex (as in collecting only specific files, by some custom pattern etc), then, no. However for that case simply use templating either by a simple F-string, format()
function or switch to Jinja, create a Dockerfile.tmpl
(or whatever you'd want to name a temporary file), then collect the paths, insert into the templated Dockerfile
and once ready dump to a file and execute afterwards with docker build
.
Example:
# Dockerfile.tmpl
FROM alpine
{{replace}}
# organize files into coherent structures so you don't have too many COPY directives
files = {
"pattern1": [...],
"pattern2": [...],
...
}
with open("Dockerfile.tmpl", "r") as file:
text = file.read()
insert = "\n".join([
f"COPY {' '.join(values)} destination/{key}/"
for key, values in files.items()
])
with open("Dockerfile", "w") as file:
file.write(text.replace("{{replace}}", insert))
Using regex in Docker COPY for digits
Dockerfile COPY
uses shell globs, not regular expressions. The actual implementation uses the Go filepath.Match
syntax. That syntax doesn't allow some of the combinations that regular expressions do: you can match any single digit [0-9]
, or any number of characters *
, but not any number of digits.
Depending on how strict you want to be about what files you'll accept and how consistent the filename format is, any of the following will work:
COPY database-[0-9][0-9].[0-9].[0-9].zip ./database.zip
COPY database-*.*.*.zip ./database.zip
COPY database-*.zip ./database.zip
In all cases note that the pattern can match multiple files in the build context. If the right-hand side of COPY
is a single file name (not ending with /
) but the glob matches multiple files you will get a build error. In this case that's probably what you want.
COPY files in current local directory only and do not include subdirectories in Docker?
The Dockerfile COPY
syntax supports shell globs but doesn't support any sort of matching on file type. You can copy all things with a given name *.py
but not "only files". For the actual glob syntax it delegates to the Go path/filepath
module which supports only the basic *
, ?
, and [a-z]
characters as "special".
You aren't limited to a single file in a COPY
command, though, as @JoachimSauer notes in a comment, and you don't have to spell out the destination directory or filename on the right-hand side. A relative path like .
is relative to the current WORKDIR
. So here I might write
WORKDIR /app
COPY run_myapp.py requirements.txt .
Related Topics
Curl: (7) Failed to Connect to Port 80, and 443 - on One Domain
Redirect Stderr and Stdout to Separate Files in Bash
Syntax With Pound and Percent Sign After Shell Parameter Name
How to Add a Footer to the Bottom of Each Page of a Postscript or PDF File in Linux
How to Download PHP Script from a Web Page with Wget
How Is the Address of the Text Section of a Pie Executable Determined in Linux
Disabling Apache Logging to Access.Log
How to Prevent a Linux User Space Pthread Yielding in Critical Code
Assembly: Read Integer from Stdin, Increment It and Print to Stdout
Set Environment Variable with Space in Linux
Force a Shell Script to Fflush
How to Write Shell Command Within Pharo Smalltalk
Understanding Buffers/Cache in Linux 'Free -M'