如何使用docker-py将文件放入Docker容器已有目录且不覆盖该目录?
Got it, let's break down how to solve this problem. Since mounting volumes isn't an option and you can't rearrange host directories to use shared volumes, the reliable approaches here are directly copying the file into the container using docker-py's built-in tools. Here are two straightforward methods:
Method 1: Upload via In-Memory Tar Archive
Docker's API (and docker-py) has a put_archive method that lets you send tar archives to a container directory. We can package the single host file into an in-memory tar stream, then upload it—this adds the file to the existing directory without overwriting the directory itself.
This method is great for larger files, as it preserves file permissions and metadata, and is efficient for data transfer.
import docker import tarfile from io import BytesIO # Initialize docker client client = docker.from_env() # Configure your paths/container name container_name = "your-target-container" host_file = "/path/on/host/important-file.txt" container_dir = "/already/exists/container/directory" # Create an in-memory tar archive with the host file tar_buffer = BytesIO() with tarfile.open(fileobj=tar_buffer, mode='w') as tar: # Add the file to the tar, using only the filename (not full host path) tar.add(host_file, arcname=tarfile.os.path.basename(host_file)) tar_buffer.seek(0) # Reset buffer position to start for reading # Get the container and upload the archive target_container = client.containers.get(container_name) upload_success = target_container.put_archive(path=container_dir, data=tar_buffer) if upload_success: print("File copied to container successfully!") else: print("Failed to upload the file to the container.")
Method 2: Write File Content via exec_run
For smaller files, you can use docker-py's exec_run to run a cat command inside the container, then pipe the host file's content into that command. This avoids tar packaging entirely and is super concise.
import docker # Initialize docker client client = docker.from_env() # Configure your paths/container name container_name = "your-target-container" host_file = "/path/on/host/small-file.txt" container_file_path = "/already/exists/container/directory/small-file.txt" # Read the host file content with open(host_file, 'rb') as f: file_content = f.read() # Execute the write command inside the container target_container = client.containers.get(container_name) exit_code, output = target_container.exec_run( cmd=f"cat > {container_file_path}", stdin=True, # Enable passing input to the command stdout=True, stderr=True ) if exit_code == 0: print("File copied successfully!") else: print(f"Error copying file: {output.decode('utf-8')}")
Additional Notes
- If you want to avoid overwriting an existing file with the same name in the container, add a check first. For example, run
exec_run("test -f {container_file_path}")and only proceed if the exit code is non-zero. - Method 1 preserves file metadata (like permissions, timestamps), while Method 2 writes the file with default permissions set by the container's user/umask.
- Ensure the container is running when you perform these operations—both methods require a running container to work.
内容的提问来源于stack exchange,提问作者thinwybk

