Updated April 1, 2023
Introduction to Docker Copy Command
Docker Copy is a directive or instruction that is used in a Dockerfile to copy files or directories from local machine to the container filesystem where the source is the local path and destination is the path in the container filesystem. We can specify multiple source paths and we need to use a relative path while specifying multiple sources. We can use wildcards to specify the source as well. We can specify the destination as an absolute path or relative to the WORKDIR directive if the WORKDIR directive is defined in the Dockerfile. We can change the ownership of the files or directories while copying it to the container filesystem. In this topic, we are going to learn about Docker Copy Command.
Syntax
There are two forms of COPY instructions we have: –
1. COPY [–chown=<user>:<group>] <src>… <dest>
2. COPY [–chown=<user>:<group>] [“<src>”,… “<dest>”]
- –chown is used to change the ownership of the file in the container filesystem
- <user>:<group> is used to specify the user and group to whom we want to give the ownership
- <src> is where we specify the path of the localhost
- <dest> is where we specify the path in the container filesystem.
- 2nd form is used when we have whitespaces in the source or destination path.
How Copy Command works in Docker?
As we know it is used to copy local files or directories to the container filesystem so whenever we have something to copy to the container while building an Image we use this instruction. It takes the source path and destination path. It also has the ‘–chown’ option to change the ownership of the files or directories, however, it only works while building a Linux container and does not work for Windows containers because of user and group ownership translation restriction between Linux and Windows. When we build the Docker image using the ‘docker build’ command and when docker daemon interprets this directive, docker daemon will check for the files and directories on the local filesystem and if the files or folders exist, it changes the ownership of the file is defined in the Dockerfile and copies to the specified destination which is the path in the container filesystem. If we have defined WORKDIR directive and want to copy the files or folders to that directory we can simply use the ‘.’ to copy it to the working directory that is defined by the WORKDIR directive earlier in the Dockerfile.
Examples of Docker Copy Command
Here are the following examples mentioned below.
Example #1
Create a simple Dockerfile to copy the index.html file to the container to replace the default one. Here, is the Dockerfile: –
FROM ubuntu
RUN apt-get update && apt-get install -y nginx
COPY index.html /var/www/html
ENTRYPOINT ["nginx", "-g", "daemon off;"]
Let’s build a Docker image using the above Dockerfile as below: –
$docker build -t my-app
Run a container using the above Docker image: –
$docker run -d -p 80:80 my-app
Now, let’s test that the file has been copied to the container or not using the below commands: –
$cat index.html
$docker exec --it e3 sh
#cat /var/www/html/index.html
Explanation: – In the above snapshot, we have created a container using a newly created Docker image and then checked the contents of the local copy of ‘index.html’. Connected to the container and checked the contents of the file ‘index.html’ that we have copied using the ‘COPY’ directive. We can see that the ‘index.html’ file in the container filesystem has the same content as the local ‘index.html’.
Example #2
Use of the ‘–chown’ option. To use this option, the mentioned user must be available in the base image otherwise build gets fail.
Create a container using any Docker image, here, we use my-app:v2 however, we can use the above created Docker image i.e. my-app.
Connect to the newly created container.
Create a user, here, we create ‘testuser2’
$docker ps
$docker exec -it <container ID or container name> sh
#adduser testuser2
Exit from the container and export it as a tar using the below command: –
$docker export <container ID or container name>> my-app.tar
Now, import this tar file as a Docker image using the ‘Docker import’ command as below: –
$docker import my-app.tar my-app:v4
Again build a new Docker image using the below Dockerfile but this time use the ‘my-app:v4’ Docker image as a base image.
FROM ubuntu
RUN apt-get update && apt-get install -y nginx
COPY --chown=testuser2:testuser2 index.html /var/www/html
ENTRYPOINT ["nginx", "-g", "daemon off;"]
Explanation: – In the above snapshot, we have built a new Docker image ‘my-app:v5’ using the above Dockerfile.
Let’s confirm the ownership of the copied index.html file in the container filesystem by creating a new container using the ‘my-app:v5’ image.
$docker run -d -p 80:80 my-app:v5
Connect to the container.
$docker exec -it <container ID or container name> sh
Check the ownership of the file ‘index.html’ located at /var/www/html using the below command: –
#ls -l /var/www/html
Explanation: – In the above snapshot, we can see that the owner of the ‘index.html’ file is testuser2.
Example #3
Use of the ‘–from’ option. This option is used when we have a multistage build in Dockerfile. When we specify this option in the Dockerfile, it sets the source location to a previous build stage and copies the output of the first build which is specified as ‘FROM <base_image> as <name>’, below is the Dockerfile and my-app.go file to achieve test above scenario: –
my-app.go
package main
import "fmt"
func main() {
fmt.Println("Welcome to my-app")
}
Dockerfile
package main
import "fmt"
func main() {
fmt.Println("Welcome to my-app")
}
Create a new Docker image using the above Dockerfile: –
$docker build -t my-app:go
Let’s run a container using the above Docker image: –
$docker run my-app:go
In the above snapshot, we can see that container shows the output perfectly fine.
We need to check the image size of the ‘my-app:go’ and ‘golang’ images: –
$docker image my-app:go
$docker image golang
Explanation: In the above snapshot, we can see that the image size of my-app:go is only 6.48 MB whereas golang size is 810 MB which is huge as compared to my-app:go. It is because my-app:go does not include the golang image in it. We have used the golang image only to compile our application. Once compiled it stores the output as ‘build1’ which is used in the COPY directive in the second stage build using the ‘–from’ option.
Advantages
- We can easily copy local files to the container filesystem.
- It also provides the option to change the ownership of the file while copying it to the container filesystem.
- It is used to create a multistage build that helps to create the Docker image efficiently.
Conclusion
Docker COPY is a directive to copy the local files with different options that we have discussed above. We have the Docker ADD directive as well for the same but cannot help in multistage build.
Recommended Articles
This is a guide to Docker Copy Command. Here we discuss How to Copy Command works in Docker and Examples along with the explanation. You may also have a look at the following articles to learn more –