2403

I am trying to build a backup and restore solution for the Docker containers that we work with.

I have Docker base image that I have created, ubuntu:base, and do not want have to rebuild it each time with a Docker file to add files to it.

I want to create a script that runs from the host machine and creates a new container using the ubuntu:base Docker image and then copies files into that container.

How can I copy files from the host to the container?

Flip
  • 6,233
  • 7
  • 46
  • 75
user3001829
  • 24,412
  • 5
  • 17
  • 21
  • 20
    If you don't want to rebuild, why not "[docker commit](http://docs.docker.io/reference/commandline/cli/#commit)" ? That saves your image. – Berend de Boer Apr 28 '14 at 22:24
  • 73
    Just a remark on a notion nobody has addressed: in general, treat containers as "ephemeral". There ARE use cases to copy files into/from a running container (testing, prototyping). But if you find yourself in a position where you can't rebuild what you need using Dockerfiles and/or compose, then you may be in a bad place. You generally don't want to be backing up containers as if they were OS or even VM objects. Generally speaking :-) – Scott Prive Oct 16 '17 at 18:04
  • Possible duplicate of [Copying files from Docker container to host](https://stackoverflow.com/questions/22049212/copying-files-from-docker-container-to-host) – Shubham Nov 30 '18 at 05:49
  • @BerenddeBoer's link is now outdated, here's the new URL: https://docs.docker.com/engine/reference/commandline/commit/ – Aaron Aug 21 '20 at 02:45
  • Adding to @ScottPrive point: containers are designed for high availability, so in their case "backup" is another replica running simultaneously on another host and/or in another data center (one should have more than one host and ideally also multiple DC's in a single k8s cluster). – mirekphd Nov 12 '22 at 09:09
  • You could refer this blog post - https://jhooq.com/docker-copy-file-localhost-to-container/ – Rahul Wagh Apr 26 '23 at 13:20

51 Answers51

3927

The cp command can be used to copy files.

One specific file can be copied TO the container like:

docker cp foo.txt container_id:/foo.txt

One specific file can be copied FROM the container like:

docker cp container_id:/foo.txt foo.txt

For emphasis, container_id is a container ID, not an image ID. (Use docker ps to view listing which includes container_ids.)

Multiple files contained by the folder src can be copied into the target folder using:

docker cp src/. container_id:/target
docker cp container_id:/src/. target

Reference: Docker CLI docs for cp

In Docker versions prior to 1.8 it was only possible to copy files from a container to the host. Not from the host to a container.

MikeiLL
  • 6,282
  • 5
  • 37
  • 68
Henrik Sachse
  • 51,228
  • 7
  • 46
  • 59
  • 2
    also note this can be on the host vm or main OS and works either host to container or vm to host (or main os) – Adam Tuliper Nov 16 '15 at 06:06
  • 1
    Is there a way to do this from within a dockerfile? – cph2117 Jun 29 '16 at 21:07
  • 14
    In a Dockerfile you can use the ADD keyword to add files during build time. – Henrik Sachse Jun 30 '16 at 17:49
  • 11
    @h3nrik [`COPY` preferred over `ADD`](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#/add-or-copy) when applicable. – Franklin Yu Aug 02 '16 at 17:06
  • 1
    Note: You might have to use absolute paths. – Zelphir Kaltstahl Oct 11 '16 at 13:51
  • 26
    use `docker cp` to copy from container to host works well, but when use it to copy files from host to container, no effect... anybody know why ? docker version: Docker version 1.10.3, build cb079f6-unsupported – Ace.Yin Nov 29 '16 at 05:28
  • 7
    Can i copy multiple files using docker cp from host to container? – Yogesh D Dec 01 '16 at 21:57
  • 1
    @Ace.Yin I thought I had the same issue, but it was just a wrong use of cp. See [this](http://stackoverflow.com/a/32576340/777285) to copy the _content_ of a directory. It's also explained in [the docs](https://docs.docker.com/engine/reference/commandline/cp/#extended-description) of course. – Arnaud P Apr 07 '17 at 08:18
  • 1
    Worth noting (at least at Docker 18.09.1) that "filesystem operations against a running Hyper-V container are not supported". – duct_tape_coder Mar 20 '19 at 20:00
  • 2
    `docker cp foo.txt mycontainer:/` to keep filename the same ("foo.txt") inside container – Tarasovych Dec 04 '19 at 09:56
  • `sudo docker cp 6eae0949649c:/app/output.txt output.txt` shows `open /home/rajan/Desktop/bashapp/output.txt: permission denied`. Any solution? – Rajan Raju Jul 05 '21 at 05:35
  • @Ace.Yin For me when I did `docker cp foo.txt container_id:/foo.txt` ,it got copied to root directory. When I opened shell it was open in another directory specified in dockerfile's working directory. So beware, it copied to absolute path and not relative to working directory specified in dockerfile – Zincfan Oct 12 '21 at 15:43
  • also, it's worth mentioning about changing the owner of the copied files. use `chown` before using the files. It's one of the prominent issues when you copy files from windows machines. – Diablo May 31 '22 at 15:15
  • Heads up: if you see 'must specify at least one container source', you probably forgot the `:` in `container_id:` – stevec Nov 21 '22 at 14:46
  • How to copy `Directory` from host to container? – Satish Jan 23 '23 at 15:26
219
  1. Get container name or short container id:

    $ docker ps
    
  2. Get full container id:

    $ docker inspect -f   '{{.Id}}'  SHORT_CONTAINER_ID-or-CONTAINER_NAME
    
  3. Copy file:

    $ sudo cp path-file-host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE
    

EXAMPLE:

$ docker ps

CONTAINER ID      IMAGE    COMMAND       CREATED      STATUS       PORTS        NAMES

d8e703d7e303   solidleon/ssh:latest      /usr/sbin/sshd -D                      cranky_pare

$ docker inspect -f   '{{.Id}}' cranky_pare

or

$ docker inspect -f   '{{.Id}}' d8e703d7e303

d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5

$ sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
solidleon
  • 2,363
  • 2
  • 12
  • 5
  • 14
    For me the host's mounting path didn't contain `aufs` but a `devicemapper`. Easiest way to check the containers mounting path (while it is running) is to run the command `mount`. – derenio Oct 03 '14 at 07:54
  • 3
    I tried the above solution. It copied the files into the docker specific directory. However, when I use bash for docker container, the files dont show up there. Is there something I am missing ? – AppleBud Dec 30 '14 at 12:30
  • 2
    The new path is /var/lib/docker/devicemapper/mnt/<>/rootfs/ – mcuadros Jan 14 '15 at 10:28
  • 4
    For me, on Docker 1.4.1 (current latest), it's `/var/lib/docker/aufs/diff//` – user193130 Jan 22 '15 at 08:24
  • 1
    Why not just use `docker inspect -f '{{.Volumes}}' gitlab_app_7.10` to get the answer from docker itself? – Blaisorblade May 11 '15 at 13:09
  • 1
    @AppleBud I had a similar problem with the file not showing up in the container when I used this method. This was because the target location was in a volume. So I had to use `docker inspect` to find the location of the volumes to copy the file directly into there instead. Then it showed up in the container. The volumes were under `/var/lib/docker/vfs/dir/` – Richard Corfield May 20 '15 at 10:01
  • 1
    You can use `docker inspect -f '{{.Mounts}}' d8e703d7e303` – Ste Aug 24 '15 at 14:17
  • 9
    what about for poor MacOS users? The mount directory is in `/var/lib` for me. `find / -name docker` was not helpful either. – prayagupa Dec 01 '16 at 18:47
171

The cleanest way is to mount a host directory on the container when starting the container:

{host} docker run -v /path/to/hostdir:/mnt --name my_container my_image
{host} docker exec -it my_container bash
{container} cp /mnt/sourcefile /path/to/destfile
Makan
  • 2,508
  • 4
  • 24
  • 39
Ben Davis
  • 13,112
  • 10
  • 50
  • 65
166

Typically there are three types:

  1. From a container to the host

    docker cp container_id:./bar/foo.txt .
    

Also docker cp command works both ways too.

dev1

  1. From the host to a container

    docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
    
  2. Second approach to copy from host to container:

    docker cp foo.txt mycontainer:/foo.txt
    

dev2

  1. From a container to a container mixes 1 and 2

    docker cp container_id1:./bar/foo.txt .
    
    docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
    

dev3

Ali Hallaji
  • 3,712
  • 2
  • 29
  • 36
  • 13
    docker cp works both ways. No need to exec, cat, and redirect. docker cp host_file.txt container:/path/ – tbm Mar 27 '19 at 19:15
  • 1
    And if the requirements is to copy more than just one file, tar comes pretty handy, something like the following: `tar -czvf tmp.tar.gz *.* && docker exec -i container_id2 sh -c 'cat > ./bar/tmp.tar.gz && tar -xzvf tmp.tar.gz' < ./tmp.tar.gz` – stackguy Apr 06 '21 at 21:44
  • This is actually gold! – Mina Abd El-Massih Aug 18 '22 at 07:13
  • When copying a whole directory: the command described by @stackguy may have a performance advantage, but for the sake of simplicity, you could also use the -r or -a flags : `docker cp -a ...` – Wild Pottok Aug 25 '23 at 06:56
130

The following is a fairly ugly way of doing it but it works.

docker run -i ubuntu /bin/bash -c 'cat > file' < file
Zong
  • 6,160
  • 5
  • 32
  • 46
Erik
  • 1,325
  • 1
  • 8
  • 3
  • 7
    This works great! But don't forget to commit the change: `docker commit \`docker ps -l -q\` ubuntu-with-file`. Else the change will be lost (use whatever name you want instead of `ubuntu-with-file`) – Michael_Scharf Sep 26 '14 at 23:32
  • 52
    In adition, we can use new `docker exec` feature to work with running container: `docker exec -it bash -c 'cat > /path/to/container/file' < /path/to/host/file/` – Mikl Nov 13 '14 at 16:23
  • 19
    @Mikl I think it should be `docker exec -i ...` instead of `-it`, because there's no TTY when piping in from a file. – z0r May 24 '15 at 09:36
  • I've managed to implement this in Java with Remote API https://github.com/highel/docker-rest-file-upload/blob/master/DockerRestFileUpload.java – Boris Treukhov Jun 24 '15 at 05:39
  • This really seems like simplest solution for a single file. – Kelvin Aug 05 '15 at 21:29
  • 4
    If you are still stuck on an old version of Docker (as I am) and want to copy a whole directory, you could do this: `tar -c -v -f - /path/to/host/directory | docker exec -i bash -c 'tar -x -v --strip-components 1 -f - -C /path/to/container/directory'` – eahanson Feb 01 '16 at 22:24
  • 1
    Hmm, this did not work for me with Docker 19.03.8, host Centos 8, ubuntu:18.04 image. It did create `file` on the container, but it was blank. – wisbucky Aug 03 '20 at 19:08
54

If you need to do this on a running container you can use docker exec (added in 1.3).

First, find the container's name or ID:

$ docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS                   NAMES
b9b7400ddd8f        ubuntu:latest                "/bin/bash"         2 seconds ago       Up 2 seconds                                elated_hodgkin

In the example above we can either use b9b7400ddd8f or elated_hodgkin.

If you wanted to copy everything in /tmp/somefiles on the host to /var/www in the container:

$ cd /tmp/somefiles
$ tar -cv * | docker exec -i elated_hodgkin tar x -C /var/www

We can then exec /bin/bash in the container and verify it worked:

$ docker exec -it elated_hodgkin /bin/bash
root@b9b7400ddd8f:/# ls /var/www
file1  file2
adean
  • 688
  • 5
  • 5
48
  1. Create a new dockerfile and use the existing image as your base.

    FROM myName/myImage:latest
    
    ADD myFile.py bin/myFile.py
    
  2. Then build the container:

    docker build .
    
Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
RustyShackleford
  • 25,262
  • 6
  • 22
  • 38
  • 2
    This is what worked for me. NOTHING else. Thank you! – Owen Jan 02 '17 at 02:20
  • It will create a new image, not directly a new container. If you reuse this image while myFile.py as changed, it will use the older version of the file, unless you rebuild the image. – Guillaume Lebreton Dec 15 '18 at 11:11
  • I find this the fastest way only if you're testing on a remote server. – Dominik Krulak Dec 06 '19 at 08:56
  • 3
    According to [this](https://www.ctl.io/developers/blog/post/dockerfile-add-vs-copy/) most people should use COPY rather than ADD. But for local files (as in this example) they're equivalent. – Alex Shroyer Jan 15 '20 at 15:30
42

The solution is given below,

From the Docker shell,

root@123abc:/root#  <-- get the container ID

From the host

cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root

The file shall be directly copied to the location where the container sits on the filesystem.

Eric Wilson
  • 57,719
  • 77
  • 200
  • 270
pierce
  • 470
  • 4
  • 5
  • 10
    Great answer. In newer docker releases the path has been renamed to /var/lib/docker/aufs/mnt/ – Alex Volkov Dec 19 '14 at 00:01
  • the devicemapper path doesn't seem to be work on fedora with docker 1.6. Have put it up as a separate Q, http://stackoverflow.com/questions/29939419/copying-file-from-host-to-container, any comments would be appreciated. – Yogesh_D Apr 29 '15 at 11:53
  • 1
    The file `/var/lib/docker` does not exist.... – jvriesem Nov 03 '21 at 15:22
35

Another solution for copying files into a running container is using tar:

tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x

Copies the file foo.sh into /tmp of the container.

Edit: Remove reduntant -f, thanks to Maartens comment.

Community
  • 1
  • 1
joemat
  • 776
  • 8
  • 9
  • This is good if you need to send a whole directory. For a single file, Erik's answer is simpler. – Kelvin Aug 05 '15 at 21:27
  • 1
    @Kelvin: But tar also preserves file attributes and name. Amongst others that means you only have to type the name once (and there you get tab completion from your shell). So I'd say tar is actually simpler, as long as it is installed in the container. – Maarten Aug 06 '15 at 13:17
  • 1
    The `-f -` is a bit redundant though, default behaviour is to write to stdout anyway. – Maarten Aug 06 '15 at 13:21
  • this means there is a host dependency on tar – fields Feb 25 '16 at 03:59
  • You are right - you need tar to be installed on the host and within the container. Nowadays using docker cp is the better solution. – joemat Feb 25 '16 at 07:55
24

To copy a file from host to running container

docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $HOST_PATH

Based on Erik's answer and Mikl's and z0r's comments.

Community
  • 1
  • 1
Andrea
  • 12,296
  • 4
  • 32
  • 39
  • The accepted solutions sometimes disturbs the indentation of files when transferring to running containers. This works perfect for such cases – Dreams Aug 08 '19 at 06:42
24

This is a direct answer to the question 'Copying files from host to Docker container' raised in this question in the title.

Try docker cp. It is the easiest way to do that and works even on my Mac. Usage:

docker cp /root/some-file.txt some-docker-container:/root

This will copy the file some-file.txt in the directory /root on your host machine into the Docker container named some-docker-container into the directory /root. It is very close to the secure copy syntax. And as shown in the previous post, you can use it vice versa. I.e., you also copy files from the container to the host.

And before you downlink this post, please enter docker cp --help. Reading the documentation can be very helpful, sometimes...

If you don't like that way and you want data volumes in your already created and running container, then recreation is your only option today. See also How can I add a volume to an existing Docker container?.

Community
  • 1
  • 1
19

I tried most of the (upvoted) solutions here but in docker 17.09 (in 2018) there is no longer /var/lib/docker/aufs folder.

This simple docker cp solved this task.

docker cp c:\path\to\local\file container_name:/path/to/target/dir/

How to get container_name?

 docker ps 

There is a NAMES section. Don't use aIMAGE.

aerin
  • 20,607
  • 28
  • 102
  • 140
16

With Docker 1.8, docker cp is able to copy files from host to container. See the Docker blog post Announcing Docker 1.8: Content Trust, Toolbox, and Updates to Registry and Orchestration.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
joemat
  • 776
  • 8
  • 9
15

To copy files/folders between a container and the local filesystem, type the command:

docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}

For example,

docker cp /home/foo container-id:/home/dir

To get the contianer id, type the given command:

docker ps

The above content is taken from docker.com.

Sunny
  • 407
  • 5
  • 15
prayagupa
  • 30,204
  • 14
  • 155
  • 192
10

Assuming the container is already running, type the given command:

# cat /path/to/host/file/ | docker exec -i -t <container_id> bash -c "/bin/cat > /path/to/container/file"

To share files using shared directory, run the container by typing the given command:

# docker run -v /path/to/host/dir:/path/to/container/dir ...

Note: Problems with permissions might arise as container's users are not the same as the host's users.

johndodo
  • 17,247
  • 15
  • 96
  • 113
  • 1
    In addition: `docker exec -it bash -c 'cat > /path/to/container/file' < /path/to/host/file/` – Mikl Nov 13 '14 at 16:22
  • 2
    Note that `cat` will not be terminated once it exits. If it matters to you (if you are copying bash scripts, bash will refuse to run them), you should run `lsof | grep yourfilename` and kill the `cat` process that holds the said file. – johndodo Nov 14 '14 at 07:36
  • Thx! Great tip. Can you pls tell me how to kill this process with one command? Something like `kill $(lsof | grep /path/to/file | sed ...)`. I'll be grateful for your help – Mikl Nov 14 '14 at 13:41
  • `kill $(docker top CONTAINERNAME | sed -n '/cat$/p' | sed 's/^root[^0-9]\+\([0-9]\+\).*$/\1/')` – Mikl Nov 14 '14 at 19:30
9

Container Up Syntax:

docker run -v /HOST/folder:/Container/floder 

In docker File

COPY hom* /myFolder/        # adds all files starting with "hom"
COPY hom?.txt /myFolder/    # ? is replaced with any single character, e.g., "home.txt"
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
  • How would you copy more than 1, but specific files to the container? e.g. files: alpha.txt and bravo.txt – edjm Sep 13 '22 at 15:51
8

This is the command to copy data from Docker to Host:

docker cp container_id:file path/filename /hostpath

docker cp a13fb9c9e674:/tmp/dgController.log /tmp/

Below is the command to copy data from host to docker:

docker cp a.txt ccfbeb35116b:/home/
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Maninder
  • 1,539
  • 1
  • 10
  • 12
8
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH

The destination path must be pre-exist

Syscall
  • 19,327
  • 10
  • 37
  • 52
Aditya Bhuyan
  • 328
  • 6
  • 10
7

In a docker environment, all containers are found in the directory:

/var/lib/docker/aufs/required-docker-id/

To copy the source directory/file to any part of the container, type the given command:

sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/

Sunny
  • 407
  • 5
  • 15
0x3bfc
  • 2,715
  • 1
  • 16
  • 20
7

Docker cp command is a handy utility that allows to copy files and folders between a container and the host system.

If you want to copy files from your host system to the container, you should use docker cp command like this:

docker cp host_source_path container:destination_path

List your running containers first using docker ps command:

abhishek@linuxhandbook:~$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              
  PORTS               NAMES
  8353c6f43fba        775349758637        "bash"              8 seconds ago       Up 7 
  seconds                            ubu_container

You need to know either the container ID or the container name. In my case, the docker container name is ubu_container. and the container ID is 8353c6f43fba.

If you want to verify that the files have been copied successfully, you can enter your container in the following manner and then use regular Linux commands:

docker exec -it ubu_container bash

Copy files from host system to docker container Copying with docker cp is similar to the copy command in Linux.

I am going to copy a file named a.py to the home/dir1 directory in the container.

docker cp a.py ubu_container:/home/dir1

If the file is successfully copied, you won’t see any output on the screen. If the destination path doesn’t exist, you would see an error:

abhishek@linuxhandbook:~$ sudo docker cp a.txt ubu_container:/home/dir2/subsub
        Error: No such container:path: ubu_container:/home/dir2

If the destination file already exists, it will be overwritten without any warning.

You may also use container ID instead of the container name:

docker cp a.py 8353c6f43fba:/home/dir1
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
Abhishek Patwa
  • 167
  • 2
  • 5
6

Try docker cp.

Usage:

docker cp CONTAINER:PATH HOSTPATH

It copies files/folders from PATH to the HOSTPATH.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ganga
  • 125
  • 1
  • 1
6

If the host is CentOS or Fedora, there is a proxy NOT in /var/lib/docker/aufs, but it is under /proc:

cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root

This cmd will copy all contents of data directory to / of container with id "containerid".

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254
  • This is not unique to Redhat: it also works on Debian. (maybe all Gnu/Linux with `/proc`). Also extend path to put file somewhere else, not just root. – ctrl-alt-delor Feb 13 '17 at 19:23
5

Many that find this question may actually have the problem of copying files into a Docker image while it is being created (I did).

In that case, you can use the COPY command in the Dockerfile that you use to create the image.

See the documentation.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Klas Mellbourn
  • 42,571
  • 24
  • 140
  • 158
5

tar and docker cp are a good combo for copying everything in a directory.

Create a data volume container

docker create --name dvc --volume /path/on/container cirros

To preserve the directory hierarchy

tar -c -C /path/on/local/machine . | docker cp - dvc:/path/on/container

Check your work

docker run --rm --volumes-from dvc cirros ls -al /path/on/container
Everett Toews
  • 10,337
  • 10
  • 44
  • 45
5

In case it is not clear to someone like me what mycontainer in @h3nrik answer means, it is actually the container id. To copy a file WarpSquare.mp4 in /app/example_scenes/1440p60 from an exited docker container to current folder I used this.

docker cp `docker ps -q -l`:/app/example_scenes/1440p60/WarpSquare.mp4 .

where docker ps -q -l pulls up the container id of the last exited instance. In case it is not an exited container you can get it by docker container ls or docker ps

ishandutta2007
  • 16,676
  • 16
  • 93
  • 129
5
docker cp SRC_PATH CONTAINER_ID:DEST_PATH

For example, I want to copy my file xxxx/download/jenkins to tomcat

I start to get the id of the container Tomcat

docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
63686740b488        tomcat              "catalina.sh run"   12 seconds ago      Up 11 seconds       0.0.0.0:8080->8080/tcp   peaceful_babbage

docker cp xxxx/download/jenkins.war  63686740b488:usr/local/tomcat/webapps/
Mourad MAMASSI
  • 849
  • 1
  • 11
  • 14
5

docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH to copy from host machine to container.

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH to copy from the container to the host machine.

4

This is a onliner for copying a single file while running a tomcat container.

docker run -v /PATH_TO_WAR/sample.war:/usr/local/tomcat/webapps/myapp.war -it -p 8080:8080 tomcat

This will copy the war file to webapps directory and get your app running in no time.

karthik101
  • 1,619
  • 4
  • 17
  • 23
  • 1
    -v will mount (i.e. create a link), not copy – Vitaliy Ulantikov Dec 03 '17 at 20:46
  • the difference in the result is that mounting hides the previous container content, e.g. if you mount a host folder on a container folder you cannot see anymore the previous container folder content – mrq Mar 14 '18 at 06:22
4

This is what worked for me

#Run the docker image in detached mode 
$docker run -it -d test:latest bash

$ docker ps
CONTAINER ID        IMAGE               COMMAND
a6c1ff6348f4        test:latest     "bash"

#Copy file from host to container
sudo docker cp file.txt a6c1ff6348f4:/tmp

#Copy the file from container to host
docker cp test:/tmp/file.txt /home
jfk
  • 4,335
  • 34
  • 27
3

The best way for copying files to the container I found is mounting a directory on host using -v option of docker run command.

ryanyuyu
  • 6,366
  • 10
  • 48
  • 53
3

There are good answers, but too specific. I find out docker ps is good way to get container id you're interested in. Then do

mount | grep <id>

to see where the volume is mounted. That's

/var/lib/docker/devicemapper/mnt/<id>/rootfs/

for me, but it might be a different path depending on the OS and configuration. Now simply copy files to that path.

Using -v is not always practical.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
akostadinov
  • 17,364
  • 6
  • 77
  • 85
3

My favorite method:

CONTAINERS:

CONTAINER_ID=$(docker ps | grep <string> | awk '{ print $1 }' | xargs docker inspect -f '{{.Id}}')

file.txt

mv -f file.txt /var/lib/docker/devicemapper/mnt/$CONTAINER_ID/rootfs/root/file.txt

or

mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt
user3159411
  • 55
  • 1
  • 6
  • the devicemapper path doesn't seem to be work on fedora with docker 1.6. Have put it up as a separate Q, http://stackoverflow.com/questions/29939419/copying-file-from-host-to-container, any comments would be appreciated. – Yogesh_D Apr 29 '15 at 11:52
3

I just started using docker to compile VLC, here's what you can do to copy files back and forth from containers:

su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt

Search for a familiar file in that txt and you'll have the folder, cd to it as root and voila! copy all you want.

There might be a path with "merged" in it, I guess you want the one with "diff" in it.

Also if you exit the container and want to be back where you left off:

docker ps -a
docker start -i containerid

I guess that's usefull when you didn't name anything with a command like

docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash

Sure the hacker method but so what!

colin lamarre
  • 1,714
  • 1
  • 18
  • 25
3

You can use below commands

  1. Copy file from host machine to docker container

    docker cp /hostfile container_id:/to_the_place_you_want_the_file_to_be

  2. Copy file from docker container to host machine

    docker cp container_id:src_path to_the_place_you_want_the_file_to_be

Pankaj Agrawal
  • 193
  • 1
  • 1
  • 11
2

You can just trace the IP address of your local machine using

ifconfig

Then just enter into your Docker container and type

scp user_name@ip_address:/path_to_the_file destination

In any case if you don't have an SSH client and server installed, just install it using:

sudo apt-get install openssh-server
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Harshit Anand
  • 602
  • 9
  • 13
2

In my opinion you have not to copy files inside image but you can use GIT or SVN for your files and then set a volume synchronized with a local folder. Use a script while runing container who can check if data already exist in local folder if not copy it from GIT repository. That make your image very lightweight.

h.aittamaa
  • 329
  • 3
  • 4
  • This seems like a security risk and access nightmare waiting to happen. How do you provide access to the git repository from within your image? Even assuming it's a public repository you're going to assume the host your container runs on has access to that repo. – tbm Mar 27 '19 at 19:19
  • I'm agree with you if git is used inside docker container. But in our case, the script is running from the host machine – h.aittamaa Mar 29 '19 at 09:57
2

The simpliest way to achieve this is,

  1. Find the container id
  2. docker cp <filename> <container-id>:<path>
Soumyajit
  • 329
  • 1
  • 5
  • 16
2

If you're able to use a container registry, the appendlayer Python package does what you're asking for:

Assume that ubuntu:base is already available in the registry.

You can then add a new layer consisting of some local files on top of it using the script, saving the whole thing as a new image (i.e. ubuntu:test).

$ pip install appendlayer
$ tar cvf - test.txt | appendlayer <host> <repository> <old-tag> <new-tag>

All without having to rebuild or even download any of the image data to your local machine.

malthe
  • 1,237
  • 13
  • 25
2

I wanted to have a build process happen in the container without files like the .git folder, but I want those files when I run the container interactively to debug problems. Like Ben Davis's answer, this executes the file copy within the container. But I don't want to have to actually run that command myself when I enter the container. Thus the following script will do the trick:

# mount the current [project] directory as read only
docker run --name my_container -v $(pwd):/mnt/application:ro -itd my_image /bin/bash
# copy the missing project files from the mounted directory
docker exec -it my_container /bin/bash -c 'cp -rnT /mnt/application $HOME/application'
# interactively use the container
docker attach my_container

This leaves behind a my_container container instance. To run the command again, you would have to write docker rm my_container. Or instead, if you wanted to get into that container instance again, you could execute docker start my_container && docker attach my_container.

Note the cp -n flag, which prevents overwriting files if they already exist in the destination. The :ro portion does not allow the host files to be changed. And you could change $(pwd) to a specific directory, like /home/user/dev/application.

Erasmus
  • 596
  • 5
  • 8
1

Where you don't have a directory defined as a volume in the Dockerfile, the /var/lib/docker/aufs/mnt// will work. But there are cases where the directory within the container is defined as a volume. In this case, the contents under aufs/mnt/*/ and the contents seen by the container are different.

You will need to inspect the container using docker inspect and then, look for volumes. There you will find a mention for something like /var/lib/docker/vfs/dir/fe940b... (the id). You will need to add/modify the files here instead of under aufs/mnt/*.

The confusing part is that the files also appear under /aufs/mnt/*. I spent quite a while scratching my head why changes here didn't work for me. Hope this helps someone.

user3392439
  • 973
  • 8
  • 6
1

I'd mount and then run the image with a daemon, just any as given here;

docker run -d -v /blah1/blah2:/mnt --name mntcontainer ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

then

docker exec -it mntcontainer bash
East2West
  • 657
  • 1
  • 6
  • 22
1

Another workaround is using the good old scp. This is useful in the case you need to copy a directory.

From your host run:

scp FILE_PATH_ON_YOUR_HOST IP_CONTAINER:DESTINATION_PATH
scp foo.txt 172.17.0.2:foo.txt

In the case you need to copy a directory:

scp -r DIR_PATH_ON_YOUR_HOST IP_CONTAINER:DESTINATION_PATH
scp -r directory 172.17.0.2:directory

be sure to install ssh into your container too.

apt-get install openssh-server
gaetano
  • 865
  • 1
  • 15
  • 29
  • I had no issue using `docker cp` to copy folders as well. As a side note for others, I normally don't like to read the docs because they are often times hard to understand but the docs on the `docker cp` command are simple. – Post Impatica Aug 27 '17 at 18:13
1

If using Windows as host, you can use WinSCP to connect to Docker and transfer files through the GUI.

If on Linux, the scp command would also work through the terminal.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
R.K
  • 11
  • 2
1

One thing which I tried and it worked

Once you spin up your docker container and if you create any file under that container; You can easily access that file from below location of your docker host:-

cd /var/lib/docker/aufs/containers/container_id/tmp

Try once!

Community
  • 1
  • 1
1

real deal is:

docker volume create xdata
docker volume inspect xdata

so you see its mount poit dir.
just copy your stuff there
then

docker run  --name=example1 --mount source=xdata,destination=/xdata -it yessa bash

where yessa is image name

1

Using the following command from outside the container, I was able to copy file from my host machine to the container.

 487b00c94dd4 = Container ID
D:\demo\demo.tar= Source Url
/myfolder= Container Url

 
docker cp "D:\demo\demo.tar" 487b00c94dd4:/myfolder
Sayed Uz Zaman
  • 606
  • 1
  • 9
  • 25
0

I simply copy the file directly from where the container is located from the host machine.

For example:

First find out the container id:

root@**3aed62678d54**:/home#

And then from the host, let's say the file is in the home directory:

root@saasdock:/home/dnepangue# cp cheering_nasa.gif /var/lib/docker/aufs/mnt/**3aed62678d54**a5df47a4a00a58bb0312009c2902f8a37498a1427052e8ac454b/home/

Back to the container...

root@**3aed62678d54**:/home# ls cheering_nasa.gif
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
asterinux
  • 9
  • 1
0

I usually create python server using this command

python -m SimpleHTTPServer

in the particular directory and then just use wget to transfer file in the desired location in docker. I know it is not the best way to do it but I find it much easier.

terminal
  • 72
  • 3
0

Copy from container to host dir

docker cp [container-name/id]:./app/[index.js] index.js

(assume you have created a workdir /app in your dockerfile)

Copy from host to container

docker cp index.js [container-name/id]:./app/index.js
ilyankou
  • 1,309
  • 8
  • 13
Niyas Ali
  • 203
  • 2
  • 9
0

Bring dotfile into shell session (using base64 escape)

There are times when executing a separate interactive command to the shell launch is cumbersome. Here's what I do when I want to copy a dotfile into my container so my shell will contain my customizations

docker exec -u root -it mycontainername bash -c "echo "$(cat ~/.bashrc | base64 -w 0)" | base64 --decode > /tmp/.bashrc_inside_container; bash --rcfile /tmp/.bashrc_inside_container"
Sridhar Sarnobat
  • 25,183
  • 12
  • 93
  • 106
0

I would highly recommend that you do not copy any files to any container, instead use a docker volume. This will allow you to persist files on your host. If you do not do it this way, then when its time to upgrade your docker image/container (you should do this on any release that contains any CVE's) then you would be removing the files you just uploaded.

I SFTP to my Docker Host (Linux Server usually), uploading the file there.

billsecond
  • 612
  • 3
  • 21
  • 50