I know, there is possible way how to copy file bidirectionally between host and docker container using docker cp and also it is possible to obtain file from running container using docker-py. But I am not able to figure out how (or if it is even possible) copy file from host to running container using docker-py. 
Do you guys have any experiences with such kind of problem? Is it possible to do or I have to execute command using python os.system. I would like to avoid this solution.
            Asked
            
        
        
            Active
            
        
            Viewed 1.2k times
        
    16
            
            
         
    
    
        s.t.e.a.l.t.h
        
- 440
- 2
- 4
- 14
- 
                    1You can do interesting things with `put_archive`. https://docker-py.readthedocs.io/en/stable/containers.html#docker.models.containers.Container.put_archive – Oluwafemi Sule Sep 24 '17 at 13:20
- 
                    Thank you, I missed this option in SDK, I was aimed on copy. I am going to try it – s.t.e.a.l.t.h Sep 24 '17 at 13:22
- 
                    Any update here? I'm trying to copy files on local machine into docker container – Michael Ababio Jan 31 '18 at 17:26
- 
                    check out the answers here... https://stackoverflow.com/a/59743346/6420513 – John Drinane Jan 16 '20 at 19:25
3 Answers
27
            
            
        Something like this should work:
import os
import tarfile
import docker
client = docker.from_env()
def copy_to(src, dst):
    name, dst = dst.split(':')
    container = client.containers.get(name)
    os.chdir(os.path.dirname(src))
    srcname = os.path.basename(src)
    tar = tarfile.open(src + '.tar', mode='w')
    try:
        tar.add(srcname)
    finally:
        tar.close()
    data = open(src + '.tar', 'rb').read()
    container.put_archive(os.path.dirname(dst), data)
And then use it like:
copy_to('/local/foo.txt', 'my-container:/tmp/foo.txt')
 
    
    
        Yani
        
- 1,465
- 2
- 16
- 25
5
            
            
        Code snippet using memory BytesIO:
def copy_to_container(container: 'Container', src: str, dst_dir: str):
    """ src shall be an absolute path """
    stream = io.BytesIO()
    with tarfile.open(fileobj=stream, mode='w|') as tar, open(src, 'rb') as f:
        info = tar.gettarinfo(fileobj=f)
        info.name = os.path.basename(src)
        tar.addfile(info, f)
    container.put_archive(dst_dir, stream.getvalue())
 
    
    
        Yuan HOng
        
- 2,327
- 1
- 11
- 2
- 
                    Nice! This can be simplified a bit by executing `tar.add(src, arcname=os.path.basename(src))` in the with block instead of opening the file, creating the tarinfo and adding the file object. – Manuel Jacob Apr 21 '23 at 11:35
0
            
            
        #!/usr/bin/python
import os
import tarfile
import docker
client = docker.from_env()
def copy_to(src, dst):
    name, dst = dst.split(':')
    container = client.containers.get(name)
    os.chdir(os.path.dirname(src))
    srcname = os.path.basename(src)
    tar = tarfile.open(srcname + '.tar', mode='w')
    obj=os.walk(srcname)
    for items in obj:
        for files in items[2]:
            if files[-4::] == ".csv" :
                abs_path = items[0] + "/" + files
                tar.add(abs_path)
    tar.close()
    data = open(srcname + '.tar', 'rb')
    container.put_archive(dst, data)
    data.close()
copy_to('source_directory', 'container_name:destination_directory')
 
    
    
        Bert Blommers
        
- 1,788
- 2
- 13
- 19
 
    
    
        Dagger
        
- 1
- 
                    1Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 17 '22 at 17:14