File ownership after docker cp

前端 未结 4 1998

How can I control which user owns the files I copy in and out of a container?

The docker cp command says this about file ownership:

The cp

相关标签:
4条回答
  • 2021-02-19 23:40

    In addition to @Don Kirkby's answer, let me provide a similar example in bash/shell script for the case that you want to copy something into a container while applying different ownership and permissions than those of the original file.

    Let's create a new container from a small image that will keep running by itself:

    docker run -d --name nginx nginx:alpine
    

    Now wel'll create a new file which is owned by the current user and has default permissions:

    touch foo.bar
    ls -ahl foo.bar
    >> -rw-rw-r-- 1 my-user my-group 0 Sep 21 16:45 foo.bar
    

    Copying this file into the container will set ownership and group to the UID of my user and preserve the permissions:

    docker cp foo.bar nginx:/foo.bar
    docker exec nginx sh -c 'ls -ahl /foo.bar'
    >> -rw-rw-r--    1 4098     4098           0 Sep 21 14:45 /foo.bar
    

    Using a little tar work-around, however, I can change the ownership and permissions that are applied inside of the container.

    tar -cf - foo.bar --mode u=+r,g=-rwx,o=-rwx --owner root --group root | docker cp - nginx:/
    docker exec nginx sh -c 'ls -ahl /foo.bar'
    >> -r--------    1 root     root           0 Sep 21 14:45 /foo.bar
    

    tar options explained:

    • c creates a new archive instead of unpacking one.
    • f - will write to stdout instead of a file.
    • foo.bar is the input file to be packed.
    • --mode specifies the permissions for the target. Similar to chown, they can be given in symbolic notation or as an octal number.
    • --owner sets the new owner of the file.
    • --group sets the new group of the file.

    docker cp - reads the file that is to be copied into the container from stdin.

    This approach is useful when a file needs to be copied into a created container before it starts, such that docker exec is not an option (which can only operate on running containers).

    0 讨论(0)
  • 2021-02-19 23:42

    You can also change the ownership by logging in as root user into the container :

    docker exec -it --user root <container-id> /bin/bash
    chown -R <username>:<groupname> <folder/file>
    
    0 讨论(0)
  • 2021-02-19 23:43

    Just a one-liner (similar to @ramu's answer), using root to make the call:

    docker exec -u 0 -it <container-id> chown node:node /home/node/myfile
    
    0 讨论(0)
  • 2021-02-19 23:50

    In order to get complete control of file ownership, I used the tar stream feature of docker cp:

    If - is specified for either the SRC_PATH or DEST_PATH, you can also stream a tar archive from STDIN or to STDOUT.

    I launch the docker cp process, then stream a tar file to or from the process. As the tar entries go past, I can adjust the ownership and permissions however I like.

    Here's a simple example in Python that copies all the files from /outputs in the sandbox1 container to the current directory, excludes the current directory so its permissions don't get changed, and forces all the files to have read/write permissions for the user.

    from subprocess import Popen, PIPE, CalledProcessError
    import tarfile
    
    def main():
        export_args = ['sudo', 'docker', 'cp', 'sandbox1:/outputs/.', '-']
        exporter = Popen(export_args, stdout=PIPE)
        tar_file = tarfile.open(fileobj=exporter.stdout, mode='r|')
        tar_file.extractall('.', members=exclude_root(tar_file))
        exporter.wait()
        if exporter.returncode:
            raise CalledProcessError(exporter.returncode, export_args)
    
    def exclude_root(tarinfos):
        print('\nOutputs:')
        for tarinfo in tarinfos:
            if tarinfo.name != '.':
                assert tarinfo.name.startswith('./'), tarinfo.name
                print(tarinfo.name[2:])
                tarinfo.mode |= 0o600
                yield tarinfo
    
    main()
    
    0 讨论(0)
提交回复
热议问题