429

I'm trying to copy a number of files and folders to a docker image build from my localhost.

The files are like this:

folder1/
    file1
    file2
folder2/
    file1
    file2

I'm trying to make the copy like this:

COPY files/* /files/

However, all of the files from folder1/ and folder2/ are placed in /files/ directly, without their folders:

files/
    file1
    file2

Is there a way in Docker to keep the subdirectory structure as well as copying the files into their directories?

wizzwizz4
  • 5,472
  • 2
  • 27
  • 55
user1220022
  • 9,839
  • 17
  • 39
  • 55

4 Answers4

613

Remove star from COPY, with this Dockerfile:

FROM ubuntu
COPY files/ /files/
RUN ls -la /files/*

Structure is there:

$ docker build .
Sending build context to Docker daemon 5.632 kB
Sending build context to Docker daemon 
Step 0 : FROM ubuntu
 ---> d0955f21bf24
Step 1 : COPY files/ /files/
 ---> 5cc4ae8708a6
Removing intermediate container c6f7f7ec8ccf
Step 2 : RUN ls -la /files/*
 ---> Running in 08ab9a1e042f
/files/folder1:
total 8
drwxr-xr-x 2 root root 4096 May 13 16:04 .
drwxr-xr-x 4 root root 4096 May 13 16:05 ..
-rw-r--r-- 1 root root    0 May 13 16:04 file1
-rw-r--r-- 1 root root    0 May 13 16:04 file2

/files/folder2:
total 8
drwxr-xr-x 2 root root 4096 May 13 16:04 .
drwxr-xr-x 4 root root 4096 May 13 16:05 ..
-rw-r--r-- 1 root root    0 May 13 16:04 file1
-rw-r--r-- 1 root root    0 May 13 16:04 file2
 ---> 03ff0a5d0e4b
Removing intermediate container 08ab9a1e042f
Successfully built 03ff0a5d0e4b
HaaLeo
  • 7,842
  • 3
  • 38
  • 51
ISanych
  • 19,380
  • 4
  • 31
  • 51
  • 106
    But what if I need just some files like `COPY files/*1 /files/`? – Pavel Agarkov Jan 09 '18 at 11:51
  • 1
    Will this also overwrite existing files in that directory? – chander Jan 03 '19 at 20:39
  • 2
    @chander, yes, existing files will be overwritten – ISanych Jan 04 '19 at 12:43
  • 13
    It's important to note that the secret sauce here is that there is ONE source directory, and ONE target directory specified. Any other combination copies the contents of the source directory(ies) to the target directory. – Marcin May 26 '19 at 18:03
  • I wasn't able to see the output of `RUN ls -la /files/*` directly from the console output of `docker build`. So I instead went ssh to the container directly to do `ls` directly on the host, with `docker exec -it /bin/bash` – somenickname Jul 16 '19 at 22:57
  • `RUN find .` to list files in subdirectories – Joe Phillips Jan 30 '20 at 14:39
  • 2
    This did not work for me with when building from ibmcom/websphere-liberty:kernel-java8-ibmjava-ubi on macos. Neither the rest of solutions in this post did though. – Georgios F. Mar 30 '20 at 11:18
77

Alternatively you can use a "." instead of *, as this will take all the files in the working directory, include the folders and subfolders:

FROM ubuntu
COPY . /
RUN ls -la /
Sparkz0629
  • 797
  • 5
  • 4
  • 1
    will that include hidden files and dirs like '.git' directory? – Bruno Negrão Zica Aug 20 '19 at 21:57
  • 17
    @BrunoNegrãoZica, you could use .dockerignore file to specify what files/folders you would like to be ignored during copy operation. It's late, but hope it would be helpful for someone else – Hellaren Oct 02 '19 at 02:16
  • 3
    `COPY . ./` worked for me instead of `COPY . /` with Docker Desktop 4.0.1 – smoq Nov 03 '21 at 19:34
62

To merge a local directory into a directory within an image, do this. It will not delete files already present within the image. It will only add files that are present locally, overwriting the files in the image if a file of the same name already exists.

COPY ./local-path/. /image-path/
Cameron Hudson
  • 2,236
  • 1
  • 16
  • 30
  • 1
    This is the best solution because in one command you can copy an entire filesystem's worth of changes into an image layer. I keep a `/resources` directory in my source repo that mirrors the parts of the image filesystem to be added/overwritten. Then just add it all in one shot: `COPY resources/./ /` – ryanhos Dec 23 '21 at 21:39
  • This is the correct answer. – wvxvw May 08 '22 at 12:07
3

If you want to copy a source directory entirely with the same directory structure, Then don't use a star(*). Write COPY command in Dockerfile as below.

COPY . destinatio-directory/ 
  • 1
    OP specifically asked about a directory within the current directory and not the contents of the current directory. `COPY files/ /files/` without a wildcard is the answer. – TheZeke Feb 26 '21 at 22:08