Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 15

Copying Files to Docker Containers for Debugging

Recommended resources

Hello! Welcome to the next lesson in your journey to master Docker.

In our last session, we focused on managing the container lifecycle with commands like docker stop and restart, and we explored how to build resilient services using restart policies. This gave you control over the state of your containers. Today, we'll learn how to interact with the contents of a running container, a crucial skill for debugging and runtime management.

This lesson directly addresses the learning outcome: Copy files between the host and running containers using 'docker cp' for debugging. As a DevOps Engineer, you'll frequently need to extract log files, crash dumps, or other artifacts from a container for analysis, or perhaps inject a new configuration file or a debugging script without rebuilding the entire image. The docker cp command is your primary tool for these tasks.

1. The docker cp Command: Syntax and Core Usage

At its heart, docker cp works much like the standard Linux cp command, but with the added ability to specify a container as a source or destination. It allows you to move files and directories between your host machine's filesystem and a container's filesystem.

The basic syntax is straightforward:
docker cp [OPTIONS] <source_path> <destination_path>

To specify a path inside a container, you prefix it with the container's name or ID, followed by a colon (:).

  • Host to Container: docker cp /path/on/host/file.txt my_container:/path/in/container/
  • Container to Host: docker cp my_container:/path/in/container/file.txt /path/on/host/

For a comprehensive breakdown of the command's syntax and behavior, the following article from Spacelift is an excellent resource.

Using Docker Cp Command in Containers [Examples]

This article, 'Using Docker Cp Command in Containers', provides a thorough explanation of the command. We'll start with the fundamentals.

Please read the section titled 'What is docker cp?'. Pay close attention to the syntax and the table that explains how the destination path is handled differently for files versus directories. This is a common source of confusion that we'll revisit.

Let's illustrate with a quick, practical example. Imagine you have a running Nginx container named web-server and you want to retrieve its default configuration file.

  1. Start a container (if you don't have one running):

    docker run -d --name web-server nginx
    
  2. Copy the Nginx config file from the container to your current directory on the host:

    docker cp web-server:/etc/nginx/nginx.conf .
    

    The . at the end represents the current working directory on your host. You should now see an nginx.conf file in your terminal.

  3. Now, let's go the other way. Create a dummy file on your host and copy it into the container:

    echo "This is a test file" > host-file.txt
    docker cp host-file.txt web-server:/usr/share/nginx/html/
    

    You can verify the file was copied by executing a command inside the container:

    docker exec web-server ls /usr/share/nginx/html/
    

    You should see host-file.txt listed alongside index.html and 50x.html.


2. A Practical Use Case: Debugging

The learning outcome specifically highlights debugging, and for good reason. While ideally your containerized applications should stream logs to stdout/stderr for collection, sometimes an application writes crucial diagnostic information to a file. This could be a detailed error report, a crash dump, or a performance trace.

The video below demonstrates a realistic scenario where docker cp is used to pull a file generated by a test run out of a container for inspection.

How to debug Docker containers! (Python + VSCode)

In this clip from the 'How to debug Docker containers!' video by DevOps Directive, you'll see a practical example of using docker cp in a debugging workflow.

Watch from 03:49 to 05:35. The author modifies a Python test to write to a file, runs the test inside the container, and then uses docker cp to copy the resulting file to the host for analysis.

This workflow is invaluable. It allows you to inspect the state of a container (either running or stopped) by examining the files it produced, without having to bake complex log-shipping logic into your image for simple debugging tasks.


3. Best Practices and Advanced Usage

While docker cp is simple, using it effectively in a professional DevOps context requires understanding its nuances and appropriate use cases.

When to Use (and When to Avoid) docker cp

This command is a powerful tool for ad-hoc tasks, but it's not a substitute for well-designed Dockerfiles and volume management. The article you read earlier has an excellent section on this.

Using Docker Cp Command in Containers [Examples]

Let's revisit the Spacelift article to focus on the proper role of docker cp in a production-oriented workflow.

Please read the section 'When to use docker cp?'. This section frames the command in the context of DevOps best practices, highlighting it as a tool for debugging and inspection, while cautioning against using it to manually alter container state.

To summarize the key points for a DevOps professional:

  • Do use docker cp for:
    • Debugging: Pulling logs, dumps, and reports from a container.
    • Inspection: Grabbing a copy of a config file to see what the application is actually using.
    • One-off tasks: Injecting a temporary script or making a quick backup of a file before a risky operation.
  • Avoid using docker cp for:
    • Deploying code: Your application code should be part of the image, built via your Dockerfile. Using docker cp to update application files leads to configuration drift and breaks the principle of immutable infrastructure.
    • Managing persistent data: For data that needs to survive container restarts, always use Docker volumes. Files copied into a container's regular filesystem will be lost if the container is removed and recreated.

Handling Directories and Permissions

Two common operational needs are copying directory contents and preserving file permissions.

  • Copying Directory Contents: A subtle but critical detail is the trailing / on the source path.

    • docker cp my-dir container:/app copies the directory my-dir into /app, resulting in /app/my-dir.
    • docker cp my-dir/. container:/app copies the contents of my-dir into /app.
  • Preserving Permissions: The -a (or --archive) flag tells docker cp to copy files while preserving all UID/GID information. This is essential when file ownership and permissions are critical for the application to function correctly.

The Spacelift article provides examples for these and other flags. You can refer to section "Examples: How to use Docker cp command" if you want to explore them further.

Test your understanding!

You have a local directory named hotfix containing two files: patch.py and config.json. You need to copy these two files into the /app/src/ directory of a running container named webapp. The existing contents of /app/src/ should be preserved.

Which command would you use to accomplish this?

Show answer

The correct command is:

docker cp hotfix/. webapp:/app/src/

Using hotfix/. as the source ensures that the contents of the hotfix directory are copied, not the directory itself. This will place patch.py and config.json directly inside /app/src/.


Conclusion

In this lesson, we've drilled down into docker cp, a command that bridges the gap between your host machine and the isolated filesystem of a container. While simple on the surface, its true value lies in its application for debugging and runtime inspection.

Key Takeaways:

  • docker cp uses a container_name:/path syntax to transfer files to and from a container.
  • Its primary and most powerful use case is for debugging: extracting logs, reports, and other artifacts from a container for offline analysis.
  • It is an anti-pattern to use docker cp to manage application code or persistent data in production; use immutable images and volumes for those purposes.
  • The trailing /. on a source directory path is used to copy its contents rather than the directory itself.
  • The -a flag preserves file ownership and permissions during the copy, which can be critical for some applications.

In the next lesson, we will continue with local Docker environment management. After creating, running, and interacting with containers, it's inevitable that you'll accumulate unused resources. Our next topic will be: Prune unused images, containers, and volumes to manage local storage.