Docker Certification: A Complete Walkthrough¶
I successfully completed the Docker Certification test, which consisted of nine distinct labs designed to test my practical, hands-on skills with the Docker CLI. This document serves as a detailed log of each task, my solution, and the core concepts behind them. It covers the entire lifecycle of Docker objects: from creating containers and networks to managing images, transferring files, and troubleshooting.
Table of Contents¶
- Task 1: Create a Running Nginx Container
- Task 2: Create a Container and Override CMD
- Task 3: Copy a File From a Container to the Host
- Task 4: Copy a File From the Host to a Container
- Task 5: Pull Docker Images
- Task 6: Remove Large Docker Images
- Task 7: Remove a Docker Network
- Task 8: Create a Custom Docker Network
- Task 9: Restart Exited Containers
Task 1: Create a Running Nginx Container¶
- Objective: On
App Server 1, create a container namednginx_1using thenginx:alpineimage and ensure it remains running. - The "What & Why": This is the most fundamental Docker command. The goal is to run a pre-built application (Nginx web server) from an image. Using the
-d(detached) flag is crucial to run the container in the background so it stays alive. The:alpinetag specifies a lightweight version of the image, which is a best practice. - Solution:
sudo docker run -d --name nginx_1 nginx:alpine - Verification: I used
sudo docker psto list all running containers. Seeingnginx_1in the list with a status ofUpconfirmed success.
Task 2: Create a Container and Override CMD¶
- Objective: On
App Server 1, create a container nameddebug_1from theubuntu/apache2:latestimage, but overwrite its default command withsleep 1000. - The "What & Why": A common debugging technique. I needed to start a container with the application's exact environment but prevent the main application (Apache) from starting. By adding a command after the image name (
sleep 1000), I told Docker to ignore the image's defaultCMDand run my command instead. This keeps the container alive for inspection. - Solution:
sudo docker run -d --name debug_1 ubuntu/apache2:latest sleep 1000 - Verification: The key was to check the
COMMANDcolumn in the output ofsudo docker ps. Seeing"sleep 1000"confirmed I had successfully overridden the default.
Task 3: Copy a File From a Container to the Host¶
- Objective: On
App Server 1, copy/tmp/test.txt.gpgfrom thedevelopment_3container to the/tmpdirectory on the host. - The "What & Why": Containers have isolated filesystems. The
docker cpcommand is the bridge to move files across this boundary. This is essential for extracting logs, data, or artifacts from a container for analysis or backup. - Solution:
sudo docker cp development_3:/tmp/test.txt.gpg /tmp - Verification: I ran
ls -l /tmp/test.txt.gpgon the host server. The file's presence confirmed the successful copy.
Task 4: Copy a File From the Host to a Container¶
- Objective: On
App Server 1, copy/tmp/nautilus.txt.gpgfrom the host into the/usr/src/directory inside theubuntu_latestcontainer. - The "What & Why": This is the reverse of the previous task and is fundamental for deploying code, injecting configuration, or providing data to an application running inside a container. A great feature of
docker cpis that it automatically creates the destination directory (/usr/src/) if it doesn't already exist. - Solution:
sudo docker cp /tmp/nautilus.txt.gpg ubuntu_latest:/usr/src/ - Verification: I ran a command inside the container using
docker execto confirm the file had arrived:sudo docker exec ubuntu_latest ls -l /usr/src/nautilus.txt.gpg.
Task 5: Pull Docker Images¶
- Objective: On
App Server 1, download theredis:alpineandmemcached:alpineimages. - The "What & Why": The
docker pullcommand pre-downloads images from a registry (like Docker Hub) to the local server. This saves time during deployments, as thedocker runcommand won't have to download them. It's a common pre-caching step in automated workflows. - Solution:
sudo docker pull redis:alpine sudo docker pull memcached:alpine - Verification: The
sudo docker imagescommand lists all images stored locally. I confirmed that bothredis:alpineandmemcached:alpinewere present in the list.
Task 6: Remove Large Docker Images¶
- Objective: On
App Server 1, find and delete all Docker images larger than 100MB. - The "What & Why": A critical housekeeping task. Docker images can consume significant disk space. Regularly removing large, unused images is essential for managing storage on the host server.
- Solution: For the test, I identified the large images with
sudo docker imagesand removed them one by one.# First, identify the image ID sudo docker images # Then, remove it sudo docker rmi [IMAGE_ID]- Pro Tip: For future use, I learned a powerful one-liner to automate this:
sudo docker images | awk '($NF ~ /GB/) || ($NF ~ /MB/ && substr($NF, 1, length($NF)-2) > 100) {print $3}' | xargs sudo docker rmi -f
- Pro Tip: For future use, I learned a powerful one-liner to automate this:
- Verification: I ran
sudo docker imagesagain and confirmed that no images with a size greater than 100MB remained.
Task 7: Remove a Docker Network¶
- Objective: On
App Server 1, delete the Docker network namedphp-network. - The "What & Why": As applications are deployed and removed, their custom networks can be left behind. Cleaning up these unused networks is good practice to avoid clutter and prevent potential networking conflicts.
- Solution:
sudo docker network rm php-network - Verification: I ran
sudo docker network lsand confirmed thatphp-networkwas no longer in the list.
Task 8: Create a Custom Docker Network¶
- Objective: On
App Server 1, create abridgenetwork namedmysql-networkwith a specific subnet and gateway. - The "What & Why": This is a best practice for multi-container applications. Custom bridge networks provide better isolation and, most importantly, automatic DNS resolution, allowing containers to communicate using their names instead of IP addresses. Defining a subnet gives me precise control over the network's IP range.
- Solution:
sudo docker network create --driver bridge --subnet 182.18.0.0/24 --gateway 182.18.0.1 mysql-network - Verification: I used
sudo docker network inspect mysql-networkand checked theIPAM(IP Address Management) section of the JSON output to confirm that my specified subnet and gateway were configured correctly.
Task 9: Restart Exited Containers¶
- Objective: On
App Server 1, find the stopped containerslab1_containerandlab2_containerand get them running. - The "What & Why": A common real-world task. Containers can stop for various reasons. The
docker startcommand is used to restart an existing container that is in anExitedorCreatedstate, reusing its configuration. This is different fromdocker run, which creates a new container. - Solution: I started both containers efficiently with a single command.
sudo docker start lab1_container lab2_container - Verification: I ran
sudo docker ps(without the-aflag) to list only the running containers. Seeing bothlab1_containerandlab2_containerin this list with a status ofUpconfirmed the final task was complete.