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 8,319 times
13
s.t.e.a.l.t.h
- 401
- 1
- 4
- 13
-
You 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
2 Answers
23
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,297
- 2
- 12
- 23
1
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,147
- 1
- 8
- 2