Docker Copy Command: Copy Files and Directories in Docker
In Docker, a Dockerfile outlines how an image is to be built. It's essentially a plain-text file with step-by-step instructions that tell Docker how to build the image. From the top, it specifies the base image, files, and directories to be copied, and commands to be executed when a container runs, ensuring the application runs reliably across all computing environments.
The Docker COPY command is an essential command in a Dockerfile that copies files and directories from the build context ( the directory your Dockerfile is currently located on the local or host machine) to the image's filesystem.
#Syntax
The COPY command follows the syntax shown:
COPY source .. destination
Where:
source: The build context or path to the project files on the host machine.
destination: The destination path inside the Docker image.
Ready to supercharge your Docker infrastructure? Scale effortlessly and enjoy flexible storage with Cherry Servers bare metal or virtual servers. Eliminate infrastructure headaches with free 24/7 technical support, pay-as-you-go pricing, and global availability.
#Docker COPY command examples
Let’s explore the Docker COPY command with example usages for better context.
#Copy a single file
At a foundational level, you can copy a single file from the build content into the specified path inside the image. Consider a simple directory structure on the host machine with a Dockerfile and a Python file called app.py.
project_dir/
├── Dockerfile
└── app.py
Here is the Dockerfile used to create the image.
FROM python:3.12-slim
WORKDIR /src
COPY app.py .
CMD ["python", "app.py"]
Let’s explore the file line by line
The first line FROM python:3.12-slim specifies the base environment. In this case, we are using a lightweight Python base image python:3.12-slim from Docker Hub.
-
WORKDIR /src: This sets
/srcas the working directory inside the container. Once set, all commands in the container will run in that directory. This also includes actions specified by instructions such asCOPY,ADD,RUN, andCMD. -
COPY app.py .: This instruction copies the application
app.pyfrom the local machine to the container’s working directory, in this case,/src. -
CMD ["python", "app.py"] Runs the application when the container is launched. When you run the container, Docker will execute the command
python app.py.
#Copy multiple files
When copying multiple files, there are two approaches, and we shall look at each in turn.
You can copy files by explicitly specifying each one. Take the following example.
COPY app.py utils.py config.py ./
In this scenario, the command copies app.py, utils.py, and config.py only to the current working directory inside the container. This is recommended when you want to copy specific files and leave the rest out.
Another approach is using wildcards to copy the files. This copies all files with the same extension.
COPY *.py ./
In this example, the COPY command copies all Python files (i.e., those with the .py extension). Caution must be exercised, as this copies all files with the same extension.
#Copy a directory
Copying a directory is similar to copying files, but you need to specify a directory name. Suppose you have the following directory structure:
project/
├── Dockerfile
└──── app/
├── __init__.py
├── main.py
└── requirements.txt
Here’s the Dockerfile:
FROM python:3.12-slim
WORKDIR /src
COPY app/ /src/
CMD ["python", "main.py"]
The line COPY app/ /src/ copies the app directory, including all files and subdirectories, from the host machine to the /src/ directory.
The example we have seen copies only the directory contents, not the directory itself. This is the directory structure in the container once it is run:
/src/
├── __init__.py
├── main.py
└── requirements.txt
To copy the directory and its contents, you need to remove the trailing slash from the app/ directory. This is how the COPY instruction should look.
COPY app /src/
``
The container directory structure would look like this.
```bash command
/src/
└── app/
├── __init__.py
├── main.py
└── requirements.txt
Therefore
COPY app/ /app/ → Copies contents only
COPY app /app/ → Copies directory + contents
#Copy a directory and rename it
To rename a directory inside the container, use the following syntax:
COPY source_directory/ /working_directory/new_folder_name/
In the following example, the folder app on the host machine is being copied and renamed to python-app in the /src directory inside the container.
Here’s the Dockerfile:
COPY app/ /src/python-app
The container directory structure would now appear as follows.
/src/
└── python-app/
├── __init__.py
├── main.py
└── requirements.txt
#Docker best practices when copying files and directories
As you have seen, copying files and directories using the COPY command is quite a breeze. However, there are some recommended best practices to keep in mind to ensure smooth workflows and the security of your data.
#Explicitly specify the files and directories to be copied
The COPY command, when followed by a period symbol, copies everything. For example, to copy everything in the build context to the /src folder, the command would be COPY . /src. This copies everything, including local configurations, modules, git files, and secrets. This is potentially dangerous as it can copy sensitive information such as API keys and credentials. To prevent this, explicitly specify the files to be copied.
#Install dependencies first
For multi-stage builds, it’s good practice to copy dependencies first to enable seamless caching. The following example ensures that dependencies specified in the requirements.txt directory are copied first before the code.
FROM python:3.12-slim
WORKDIR /src
COPY requirements.txt README.md /src/
RUN pip install -r requirements.txt
COPY main.py .
CMD ["python", "main.py"]
#Use .dockerignore file
The build context contains all project files, including sensitive ones such as API keys, log files, login credentials, and private config files like .env. These should never be committed to a Docker image to prevent risk of exposure.
The .dockerignore file excludes sensitive files from the Docker image during the build process. Additionally, it enhances faster build times by ignoring large and unnecessary files, such as log files, which might lead to a bloated image.
For illustration, the following files are specified in the .dockerignore folder
*.log
.env
.git
The COPY command in the Dockerfile instructs Docker to copy all the files to the image. During the image build process, Docker will skip all files and directories specified in the .dockerignore file. In this case, .env, .git, and all the log files *.log.
COPY . /src/
#Conclusion
In this guide, we have seen how to copy files and directories using the Docker COPY command. We have looked at different instances, including copying single and multiple files and directories. Lastly, we have outlined some best practices to keep in mind when using the COPY command to avoid exposure of sensitive files and ensure smooth workflows.
Starting at just $3.24 / month, get virtual servers with top-tier performance.