Copying files from Docker container to host

后端 未结 18 2239
小蘑菇
小蘑菇 2020-11-22 13:39

I\'m thinking of using Docker to build my dependencies on a Continuous Integration (CI) server, so that I don\'t have to install all the runtimes and libraries on the agents

相关标签:
18条回答
  • 2020-11-22 14:07

    Most of the answers do not indicate that the container must run before docker cp will work:

    docker build -t IMAGE_TAG .
    docker run -d IMAGE_TAG
    CONTAINER_ID=$(docker ps -alq)
    # If you do not know the exact file name, you'll need to run "ls"
    # FILE=$(docker exec CONTAINER_ID sh -c "ls /path/*.zip")
    docker cp $CONTAINER_ID:/path/to/file .
    docker stop $CONTAINER_ID
    
    0 讨论(0)
  • 2020-11-22 14:09

    Mount a "volume" and copy the artifacts into there:

    mkdir artifacts
    docker run -i -v ${PWD}/artifacts:/artifacts ubuntu:14.04 sh << COMMANDS
    # ... build software here ...
    cp <artifact> /artifacts
    # ... copy more artifacts into `/artifacts` ...
    COMMANDS
    

    Then when the build finishes and the container is no longer running, it has already copied the artifacts from the build into the artifacts directory on the host.

    Edit

    Caveat: When you do this, you may run into problems with the user id of the docker user matching the user id of the current running user. That is, the files in /artifacts will be shown as owned by the user with the UID of the user used inside the docker container. A way around this may be to use the calling user's UID:

    docker run -i -v ${PWD}:/working_dir -w /working_dir -u $(id -u) \
        ubuntu:14.04 sh << COMMANDS
    # Since $(id -u) owns /working_dir, you should be okay running commands here
    # and having them work. Then copy stuff into /working_dir/artifacts .
    COMMANDS
    
    0 讨论(0)
  • 2020-11-22 14:09

    You can use bind instead of volume if you want to mount only one folder, not create special storage for a container:

    1. Build your image with tag :

      docker build . -t <image>

    2. Run your image and bind current $(pwd) directory where app.py stores and map it to /root/example/ inside your container.

      docker run --mount type=bind,source="$(pwd)",target=/root/example/ <image> python app.py

    0 讨论(0)
  • 2020-11-22 14:10

    TLDR;

    $ docker run --rm -iv${PWD}:/host-volume my-image sh -s <<EOF
    chown $(id -u):$(id -g) my-artifact.tar.xz
    cp -a my-artifact.tar.xz /host-volume
    EOF
    

    Description

    docker run with a host volume, chown the artifact, cp the artifact to the host volume:

    $ docker build -t my-image - <<EOF
    > FROM busybox
    > WORKDIR /workdir
    > RUN touch foo.txt bar.txt qux.txt
    > EOF
    Sending build context to Docker daemon  2.048kB
    Step 1/3 : FROM busybox
     ---> 00f017a8c2a6
    Step 2/3 : WORKDIR /workdir
     ---> Using cache
     ---> 36151d97f2c9
    Step 3/3 : RUN touch foo.txt bar.txt qux.txt
     ---> Running in a657ed4f5cab
     ---> 4dd197569e44
    Removing intermediate container a657ed4f5cab
    Successfully built 4dd197569e44
    
    $ docker run --rm -iv${PWD}:/host-volume my-image sh -s <<EOF
    chown -v $(id -u):$(id -g) *.txt
    cp -va *.txt /host-volume
    EOF
    changed ownership of '/host-volume/bar.txt' to 10335:11111
    changed ownership of '/host-volume/qux.txt' to 10335:11111
    changed ownership of '/host-volume/foo.txt' to 10335:11111
    'bar.txt' -> '/host-volume/bar.txt'
    'foo.txt' -> '/host-volume/foo.txt'
    'qux.txt' -> '/host-volume/qux.txt'
    
    $ ls -n
    total 0
    -rw-r--r-- 1 10335 11111 0 May  7 18:22 bar.txt
    -rw-r--r-- 1 10335 11111 0 May  7 18:22 foo.txt
    -rw-r--r-- 1 10335 11111 0 May  7 18:22 qux.txt
    

    This trick works because the chown invocation within the heredoc the takes $(id -u):$(id -g) values from outside the running container; i.e., the docker host.

    The benefits are:

    • you don't have to docker container run --name or docker container create --name before
    • you don't have to docker container rm after
    0 讨论(0)
  • 2020-11-22 14:10

    Create a path where you want to copy the file and then use:

    docker run -d -v hostpath:dockerimag
    
    0 讨论(0)
  • 2020-11-22 14:13

    If you just want to pull a file from an image (instead of a running container) you can do this:

    docker run --rm <image> cat <source> > <local_dest>

    This will bring up the container, write the new file, then remove the container. One drawback, however, is that the file permissions and modified date will not be preserved.

    0 讨论(0)
提交回复
热议问题