Introduction
This tutorial will guide you through the process of cloning a Docker container image. Docker images are packaged templates containing everything needed to run an application, and cloning allows you to make copies that you can then customize. By the end of this guide, you will understand how to clone a Docker image, modify it, and share it for deployment.
Understanding Docker and Verifying Your Environment
Before we start cloning Docker images, it is important to understand what Docker is and verify that our environment is properly set up.
What is Docker?
Docker is a platform that uses containers to develop, deploy, and run applications. Containers package an application with all its dependencies, ensuring it works consistently across different environments. This makes Docker particularly useful for development and deployment workflows.
Verifying Docker Installation
Let's first make sure Docker is correctly installed on our system. Open a terminal window and run:
docker --version
You should see output similar to:
Docker version 20.10.21, build baeda1f
Next, check that the Docker service is running:
sudo systemctl status docker
The output should indicate that Docker is active (running). If it's not running, you can start it with:
sudo systemctl start docker
Testing Docker Functionality
Let's run a simple test command to verify that Docker is working properly:
docker run hello-world
This command downloads and runs the hello-world image, which prints a confirmation message and exits. You should see output similar to:
Hello from Docker!
This message shows that your installation appears to be working correctly.
Listing Docker Images
To see what Docker images are currently available on your system, run:
docker images
This command lists all the Docker images that are currently stored locally. The output shows the image repository, tag, image ID, creation date, and size.
Now that we have confirmed Docker is working properly, we are ready to start working with Docker images in the next step.
Pulling and Running a Docker Image
In this step, we will pull a Docker image from Docker Hub and run it on our local system. This is the first step in the process of cloning a Docker image.
What is Docker Hub?
Docker Hub is a cloud-based registry service where users can find and share container images. It contains many official images maintained by software vendors as well as community-contributed images.
Pulling an Image from Docker Hub
Let's pull the official Nginx web server image from Docker Hub. Nginx is a popular web server that we will use as our example throughout this tutorial.
Run the following command to download the Nginx image:
docker pull nginx:latest
This command downloads the latest version of the Nginx image. You should see output showing the download progress:
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
186b1aaa4aa6: Pull complete
b4df32aa5a72: Pull complete
a0bcbecc962e: Pull complete
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
Verifying the Downloaded Image
To confirm that the image has been downloaded successfully, list your Docker images again:
docker images
You should now see the Nginx image in the list:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 142MB
Running the Nginx Docker Container
Now let's run a container based on the Nginx image we just pulled:
docker run --name my-nginx -d -p 8080:80 nginx
This command does the following:
--name my-nginx: Names our container "my-nginx"-d: Runs the container in detached mode (in the background)-p 8080:80: Maps port 8080 on our host to port 80 in the containernginx: Uses the Nginx image we pulled earlier
You should see a long string output, which is the container ID.
Verifying the Running Container
To check if the container is running:
docker ps
You should see output similar to:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8d3e9c5b9a7 nginx "/docker-entrypoint.…" 30 seconds ago Up 29 seconds 0.0.0.0:8080->80/tcp my-nginx
You can now access the Nginx default page by opening a web browser and navigating to http://localhost:8080 or by using curl:
curl http://localhost:8080
You should see the HTML content of the Nginx welcome page.
Now that we have successfully pulled and run a Docker image, we are ready to create our own custom image based on it in the next step.
Creating a Custom Docker Image
Now that we have a running Nginx container, we will create a custom image by modifying it. This is the core of the cloning process. We will:
- Make changes to the running container
- Create a new image from these changes
- Run a container based on our new image
Understanding Docker Image Creation
Docker images can be created in two ways:
- Using a Dockerfile (the recommended approach for production)
- By committing changes made to a running container (useful for exploration and experimentation)
We will use the second approach in this tutorial, as it is more straightforward for understanding the cloning process.
Modifying the Running Container
First, let's create a custom HTML file to replace the default Nginx welcome page. We need to enter the running container and modify its files.
Use the following command to execute a shell inside the running container:
docker exec -it my-nginx bash
This opens an interactive bash shell inside the container. Now, let's create a custom HTML file:
echo "<html><body><h1>My Custom Docker Image</h1><p>This is a custom Nginx image created in the LabEx tutorial.</p></body></html>" > /usr/share/nginx/html/index.html
You can verify the change by checking the content of the file:
cat /usr/share/nginx/html/index.html
Now exit the container shell:
exit
Testing the Changes
Let's test if our changes were applied by accessing the Nginx server again:
curl http://localhost:8080
You should now see our custom HTML content instead of the default Nginx welcome page.
Creating a New Image from the Modified Container
Now that we have modified the container, we will create a new image that includes these changes. This is done using the docker commit command:
docker commit my-nginx my-custom-nginx:v1
This command creates a new image named my-custom-nginx with the tag v1 based on the current state of the my-nginx container.
Verifying the New Image
Let's verify that our new image was created:
docker images
You should see your new image in the list:
REPOSITORY TAG IMAGE ID CREATED SIZE
my-custom-nginx v1 a1b2c3d4e5f6 10 seconds ago 142MB
nginx latest 605c77e624dd 2 weeks ago 142MB
Running a Container from the New Image
Now, let's stop and remove the original container, and then run a new container based on our custom image:
docker stop my-nginx
docker rm my-nginx
docker run --name my-custom-container -d -p 8081:80 my-custom-nginx:v1
These commands:
- Stop the original container
- Remove the original container
- Create a new container based on our custom image, mapped to port 8081
Testing the New Container
Let's verify that our new container is running correctly:
docker ps
You should see your new container in the list:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
g9h8i7j6k5l4 my-custom-nginx:v1 "/docker-entrypoint.…" 10 seconds ago Up 9 seconds 0.0.0.0:8081->80/tcp my-custom-container
Now, access the Nginx server on the new port:
curl http://localhost:8081
You should see the same custom HTML content, confirming that our new image contains the changes we made.
Congratulations! You have successfully cloned a Docker image and customized it. In the next step, we will learn how to share this custom image.
Tagging and Sharing Your Docker Image
Now that we have created a custom Docker image, we will learn how to tag it properly and prepare it for sharing. In a real-world scenario, you would push the image to a registry like Docker Hub, but in this tutorial, we will focus on the preparation steps.
Understanding Docker Image Tags
Docker images are identified by their repository name and tag. Tags help in versioning and organizing images. The default tag is latest, but it's a good practice to use meaningful version tags.
Adding More Tags to Your Image
Let's add a few more tags to our custom image:
docker tag my-custom-nginx:v1 my-custom-nginx:latest
docker tag my-custom-nginx:v1 my-custom-nginx:stable
These commands create two additional tags for our image: latest and stable. The actual image data is shared between all three tags, so this operation is very efficient.
Verifying the Tags
Let's check our images again:
docker images
You should now see multiple entries for my-custom-nginx:
REPOSITORY TAG IMAGE ID CREATED SIZE
my-custom-nginx v1 a1b2c3d4e5f6 10 minutes ago 142MB
my-custom-nginx latest a1b2c3d4e5f6 10 minutes ago 142MB
my-custom-nginx stable a1b2c3d4e5f6 10 minutes ago 142MB
nginx latest 605c77e624dd 2 weeks ago 142MB
Notice that all the my-custom-nginx images have the same Image ID, indicating they are the same image with different tags.
Preparing for Image Distribution
In a real-world scenario, you would push your image to a registry like Docker Hub. To do this, you would need to:
- Create an account on Docker Hub
- Log in to Docker Hub from your terminal
- Tag your image with your Docker Hub username
- Push the image
For demonstration purposes, let's assume your Docker Hub username is yourusername. Here's how you would prepare your image for pushing:
docker tag my-custom-nginx:v1 yourusername/my-custom-nginx:v1
To push the image (in a real scenario), you would use:
## This is for demonstration only - we won't actually push
## docker push yourusername/my-custom-nginx:v1
Saving a Docker Image to a File
Instead of pushing to a registry, you can also save a Docker image to a file for manual transfer:
docker save -o my-custom-nginx.tar my-custom-nginx:v1
This command saves the image to a tarball named my-custom-nginx.tar. You can verify the file was created:
ls -lh my-custom-nginx.tar
You should see output similar to:
-rw------- 1 labex labex 142M Nov 10 12:34 my-custom-nginx.tar
Loading an Image from a File
To load an image from a tarball on another machine (or the same machine after removing the image), you would use:
## We won't actually run this command as part of the tutorial
## docker load -i my-custom-nginx.tar
Exporting Container Documentation
To help others understand your custom image, it's good practice to document the changes you've made. Let's create a simple documentation file:
cat > my-custom-nginx-doc.txt << EOF
## My Custom Nginx Image
This is a custom Nginx image created by cloning the official Nginx image.
### Changes Made
- Replaced the default welcome page with a custom HTML page
### How to Run
docker run --name my-custom-container -d -p 8080:80 my-custom-nginx:v1
### Version History
- v1: Initial custom version with modified welcome page
EOF
You now have a documentation file for your custom image.
Congratulations! You've learned how to tag your Docker image and prepare it for sharing. In the next step, we'll go through some best practices and clean up our environment.
Best Practices and Cleaning Up
In this final step, we will cover some best practices for working with Docker images and clean up our environment.
Best Practices for Docker Images
1. Use Specific Tags
Always use specific version tags rather than relying on the latest tag. This ensures consistency in your deployments.
## Better approach
docker pull nginx:1.23.2
## Less predictable
docker pull nginx:latest
2. Keep Images Small
Smaller images are faster to download and use less storage. Consider using alpine-based images when possible:
## Let's see the size difference
docker pull nginx:alpine
docker images | grep nginx
You might see output like:
nginx alpine 2bc7edbc3cf2 2 weeks ago 40.7MB
nginx latest 605c77e624dd 2 weeks ago 142MB
The alpine version is significantly smaller!
3. Use Multi-Stage Builds
When creating images with a Dockerfile, use multi-stage builds to keep the final image small. Here's a simple example (you don't need to run this):
## Build stage
FROM golang:1.17 AS builder
WORKDIR /app
COPY . .
RUN go build -o app
## Final stage
FROM alpine:3.15
COPY --from=builder /app/app /app
CMD ["/app"]
4. Document Your Images
Always maintain documentation for your custom images, including:
- What the image is for
- How to use it
- What changes you've made
- Any configuration options
We created a simple documentation file in the previous step.
5. Scan for Vulnerabilities
Regularly scan your images for vulnerabilities:
## Example of scanning (Docker Desktop has this built-in)
## docker scan my-custom-nginx:v1
Inspecting Docker Images
Let's explore a useful command for inspecting Docker images:
docker inspect my-custom-nginx:v1
This command displays detailed information about the image, including its layers, configuration, and environment variables.
Viewing Image History
You can see the history of how an image was built:
docker history my-custom-nginx:v1
This shows each layer of the image and the commands that created them.
Cleaning Up
Now let's clean up our environment by removing the containers and images we created:
- First, stop and remove our custom container:
docker stop my-custom-container
docker rm my-custom-container
- Remove the images we created:
docker rmi my-custom-nginx:v1 my-custom-nginx:latest my-custom-nginx:stable
- Optionally, remove the Nginx image:
docker rmi nginx:latest nginx:alpine
- Check that all containers and images have been removed:
docker ps -a
docker images
Using Docker System Prune
Docker provides a convenient command to clean up unused resources:
docker system prune
This removes all stopped containers, unused networks, dangling images, and build cache. You'll be asked to confirm before proceeding.
For a more aggressive cleanup, you can use:
docker system prune -a
This additionally removes all unused images, not just dangling ones.
Conclusion
You have now learned how to:
- Pull and run Docker images
- Modify running containers
- Commit changes to create new custom images
- Tag images for organization and distribution
- Save images to files for manual transfer
- Document your custom images
- Clean up your Docker environment
These skills form the foundation of working with Docker images and will be valuable as you continue your journey with containerization.
Summary
In this hands-on tutorial, you have learned the complete process of cloning a Docker container image. You started by understanding Docker basics and verifying your environment. You then pulled an official Nginx image and ran it as a container. Next, you customized this container by modifying its content and committed those changes to create your own custom image.
You also learned how to properly tag your images for versioning and distribution, how to save images to files for manual transfer, and how to document your changes. Finally, you explored best practices for working with Docker images and cleaned up your environment.
These skills provide a solid foundation for working with Docker in development and production environments. You can now confidently create and customize Docker images to fit your specific requirements, making your applications more portable and consistent across different environments.



