Docker Volume Cli Lab
Lab 1: The "Magical Data" Test (Named Volumes)
-
Create Volume:
docker volume create magic-box -
Start Container 1:
docker run -d --name writer -v magic-box:/data alpine sh -c "echo 'I was here' > /data/secret.txt && sleep 1000" -
Check Data:
docker exec writer cat /data/secret.txt(Output: I was here) -
Destroy Container 1:
docker rm -f writer -
Start Container 2:
docker run -d --name reader -v magic-box:/app_data alpine sleep 1000(Notice we mounted it to a different path/app_datajust to prove we can!) -
Verify:
docker exec reader cat /app_data/secret.txtResult: Output is I was here. The data survived!
Lab 2: The "Live Code" Test (Bind Mounts)
Best for Web Developers
-
Create a folder:
mkdir my-site -
Create file: Inside
my-site, createindex.htmlwith textVersion 1. -
Run Nginx:
docker run -d -p 8080:80 -v $(pwd)/my-site:/usr/share/nginx/html --name web nginx -
Check Browser: Go to
localhost:8080. You see Version 1. -
Modify File: Edit
index.htmlon your laptop to sayVersion 2 - Live Update!. Save it. -
Refresh Browser: Instantly, you see Version 2. No rebuild required!
Lab 1: The "Disaster Recovery" (Backup & Restore)
Goal: Simulate a database corruption and restore from a backup file.
-
Create Data & Populate:
-
docker volume create precious-data -
docker run -d --name production-db -v precious-data:/data alpine sh -c "echo 'Important Financial Records' > /data/money.txt && sleep 1000" -
Perform Backup (The "Sidecar" Method):
-
Run a temporary container that sees both the volume AND your current folder.
-
docker run --rm -v precious-data:/volume-data -v $(pwd):/backup alpine tar cvf /backup/snapshot.tar /volume-data -
Check: You should see
snapshot.taron your laptop now. -
Simulate Disaster:
-
docker rm -f production-db -
docker volume rm precious-data(Data is GONE!) -
Restore:
-
docker volume create new-data -
docker run --rm -v new-data:/volume-data -v $(pwd):/backup alpine tar xvf /backup/snapshot.tar -C / -
Verify:
-
docker run --rm -v new-data:/data alpine cat /data/money.txt -
Result: "Important Financial Records" is back!
5: Extremely Detailed Labs for "DevSecOps Architect Level"
Lab 2: The "Manual Full Stack" (WordPress + MySQL)
Goal: Manually connect a frontend and backend. This is "The Hard Way."
Create Network: docker network create my-blog-net
Start MySQL (The Backend):
docker run -d \
--name mysql-db \
--network my-blog-net \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=somewordpress \
-e MYSQL_DATABASE=wordpress \
mysql:5.7
Start WordPress (The Frontend):
docker run -d \
--name my-blog \
--network my-blog-net \
-p 8080:80 \
-e WORDPRESS_DB_HOST=mysql-db \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=somewordpress \
wordpress
- Note: See
-e WORDPRESS_DB_HOST=mysql-db? We are using the container name as the address!
Test: Open http://localhost:8080. You will see the WordPress installation screen.
Cleanup (Painful, isn't it?): docker rm -f my-blog mysql-db docker network rm my-blog-net docker volume rm mysql-data
Takeaway: Running these huge commands every time is annoying. This is why we use Docker Compose (next topic).
Lab 3: The "Security Lockdown" (Read-Only Containers)
Goal: Prevent a hacked application from modifying configuration files.
-
Create a Dummy Config:
echo "admin_access=true" > config.txt -
Run in Read-Only Mode:
docker run -d --name secure-app -v $(pwd)/config.txt:/app/config.txt:ro alpine sleep 1000 -
Note the
:roat the end of the volume path. -
Attempt Hack (Try to change config):
docker exec -it secure-app sh -c "echo 'admin_access=FALSE' > /app/config.txt" -
Result:
sh: can't create /app/config.txt: Read-only file system -
Success: The container prevented the modification.