{"id":23607,"date":"2025-07-02T11:40:31","date_gmt":"2025-07-02T11:40:31","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=23607"},"modified":"2025-07-12T05:38:38","modified_gmt":"2025-07-12T05:38:38","slug":"docker-lab-excercise-assignment-7","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/docker-lab-excercise-assignment-7\/","title":{"rendered":"Docker Lab, Excercise &amp; Assignment &#8211; 7 &#8211; Docker Volume"},"content":{"rendered":"\n<p>Below is a <strong>very detailed tutorial and lab manual for learning Docker Volumes<\/strong>, using the Ubuntu image for practical, hands-on labs. This covers all major types of Docker volumes, their use cases, and gives you example commands and exercises for each. You\u2019ll understand:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What are Docker volumes?<\/li>\n\n\n\n<li>Types of volumes: <strong>named volumes<\/strong>, <strong>anonymous volumes<\/strong>, <strong>host (bind) mounts<\/strong>, <strong>tmpfs mounts<\/strong><\/li>\n\n\n\n<li>Volume management (create, inspect, list, prune, remove)<\/li>\n\n\n\n<li>Data persistence and sharing<\/li>\n\n\n\n<li>Backing up and restoring volumes<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>1. Introduction to Docker Volumes<\/strong><\/h2>\n\n\n\n<p><strong>Docker Volumes<\/strong> are the preferred way to persist data in Docker containers. They store data outside the container\u2019s writable layer, surviving container removal, and enabling data sharing between containers.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Why use volumes?<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Persistence:<\/strong> Data isn\u2019t lost when the container is deleted.<\/li>\n\n\n\n<li><strong>Sharing:<\/strong> Multiple containers can access the same data.<\/li>\n\n\n\n<li><strong>Performance:<\/strong> Volumes are managed by Docker, optimized for speed.<\/li>\n\n\n\n<li><strong>Backups &amp; Migration:<\/strong> Easier to backup and move data.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>2. Types of Docker Volumes<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">a. <strong>Named Volumes<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Managed by Docker.<\/li>\n\n\n\n<li>You give them a name.<\/li>\n\n\n\n<li>Docker stores them under <code>\/var\/lib\/docker\/volumes\/<\/code>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">b. <strong>Anonymous Volumes<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Not named (Docker generates a random name).<\/li>\n\n\n\n<li>Typically used for quick\/temporary storage.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">c. <strong>Host (Bind) Mounts<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Map a host directory\/file into the container.<\/li>\n\n\n\n<li>Full control; can access any part of your filesystem.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">d. <strong>tmpfs Mounts<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Stored in memory only (not on disk).<\/li>\n\n\n\n<li>Data disappears after the container stops.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. <strong>Lab Setup<\/strong><\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Install Docker: <code>sudo apt-get update sudo apt-get install docker.io -y sudo systemctl start docker sudo systemctl enable docker<\/code><\/li>\n\n\n\n<li>Pull Ubuntu image: <code>docker pull ubuntu:latest<\/code><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. <strong>Practical Labs for Each Volume Type<\/strong><\/h1>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>A. Named Volumes<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Create and Use a Named Volume<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Create a volume:<\/strong><code>docker volume create mydata<\/code>\n<ul class=\"wp-block-list\">\n<li>Check with:<br><code>docker volume ls<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Run Ubuntu container using the named volume:<\/strong><code>docker run -it --name vol-test1 -v mydata:\/data ubuntu:latest bash<\/code>\n<ul class=\"wp-block-list\">\n<li>This mounts the volume at <code>\/data<\/code> inside the container.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Inside the container, add a file:<\/strong> <code>echo \"This is a test file\" > \/data\/testfile.txt exit<\/code><\/li>\n\n\n\n<li><strong>Remove the container:<\/strong> <code>docker rm vol-test1<\/code><\/li>\n\n\n\n<li><strong>Create a new container, attach the same volume:<\/strong><code>docker run -it --name vol-test2 -v mydata:\/data ubuntu:latest bash<\/code>\n<ul class=\"wp-block-list\">\n<li><code>cat \/data\/testfile.txt<\/code><\/li>\n\n\n\n<li>You should see the content is <strong>persisted<\/strong>!<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>LAB TASK<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Try creating a new file in the <code>\/data<\/code> directory from the second container and verify it appears if you mount the volume again in a new container.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>B. Anonymous Volumes<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Run a Container with an Anonymous Volume<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Start a container with an anonymous volume:<\/strong> <code>docker run -it -v \/anondata ubuntu:latest bash<\/code><\/li>\n\n\n\n<li><strong>Inside the container:<\/strong> <code>echo \"Anonymous volume\" > \/anondata\/anon.txt exit<\/code><\/li>\n\n\n\n<li><strong>Check volume list:<\/strong><code>docker volume ls<\/code>\n<ul class=\"wp-block-list\">\n<li>A random volume will have been created.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Find which one:<\/strong> <code>docker inspect &lt;container-id> | grep Source<\/code><\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>LAB TASK<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Remove the container and see if the data persists. (Spoiler: It does, but the volume is harder to track without a name.)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>C. Host (Bind) Mounts<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Mount a Host Directory into a Container<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>On your host, create a directory:<\/strong> <code>mkdir ~\/docker-host-dir echo \"Hello from the host\" > ~\/docker-host-dir\/hostfile.txt<\/code><\/li>\n\n\n\n<li><strong>Run the container with bind mount:<\/strong> <code>docker run -it --name bind-test -v ~\/docker-host-dir:\/mnt ubuntu:latest bash<\/code><\/li>\n\n\n\n<li><strong>Inside the container:<\/strong> <code>cat \/mnt\/hostfile.txt echo \"Hello from container\" > \/mnt\/containerfile.txt exit<\/code><\/li>\n\n\n\n<li><strong>Check on the host:<\/strong><code>cat ~\/docker-host-dir\/containerfile.txt<\/code>\n<ul class=\"wp-block-list\">\n<li>Both the host and the container can see and edit files in this directory.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>LAB TASK<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Open two containers at once (in different terminals) mounting the same host directory. See if changes are visible in both in real time.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>D. tmpfs Mounts (Ephemeral Memory Only)<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Run a Container with tmpfs<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Run the container:<\/strong> <code>docker run -it --tmpfs \/mnt\/tmpfs:rw,size=64m ubuntu:latest bash<\/code><\/li>\n\n\n\n<li><strong>Inside the container:<\/strong> <code>echo \"Ephemeral data\" > \/mnt\/tmpfs\/ephemeral.txt ls \/mnt\/tmpfs exit<\/code><\/li>\n\n\n\n<li><strong>Restart container (or run new one):<\/strong>\n<ul class=\"wp-block-list\">\n<li>The <code>\/mnt\/tmpfs<\/code> folder will be empty; tmpfs data vanishes after the container stops.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>LAB TASK<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Try storing large files in the tmpfs mount and see what happens if you exceed the size limit.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. <strong>Managing Docker Volumes<\/strong><\/h1>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>List All Volumes<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker volume ls\n<\/code><\/span><\/pre>\n\n\n<h3 class=\"wp-block-heading\"><strong>Inspect a Volume<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker volume inspect mydata\n<\/code><\/span><\/pre>\n\n\n<h3 class=\"wp-block-heading\"><strong>Remove a Volume<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker volume rm mydata\n<\/code><\/span><\/pre>\n\n\n<h3 class=\"wp-block-heading\"><strong>Remove Unused Volumes<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker volume prune\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. <strong>Advanced: Sharing Volumes Across Containers<\/strong><\/h1>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Create a named volume:<\/strong> <code>docker volume create sharedvol<\/code><\/li>\n\n\n\n<li><strong>Start a first container writing to the volume:<\/strong><code>docker run -it --name writer -v sharedvol:\/shared ubuntu:latest bash<\/code>\n<ul class=\"wp-block-list\">\n<li><code>echo \"Shared data\" > \/shared\/shared.txt<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Start a second container to read from the volume:<\/strong><code>docker run -it --name reader -v sharedvol:\/shared ubuntu:latest bash<\/code>\n<ul class=\"wp-block-list\">\n<li><code>cat \/shared\/shared.txt<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. <strong>Backup &amp; Restore Volumes<\/strong><\/h1>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Backup a Docker Volume<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">docker run --rm -v mydata:<span class=\"hljs-regexp\">\/data -v $(pwd):\/<\/span>backup ubuntu tar czvf \/backup\/mydata-backup.tar.gz -C \/data .\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\"><strong>Restore a Docker Volume<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">docker run --rm -v mydata:<span class=\"hljs-regexp\">\/data -v $(pwd):\/<\/span>backup ubuntu bash -c <span class=\"hljs-string\">\"cd \/data &amp;&amp; tar xzvf \/backup\/mydata-backup.tar.gz --strip 1\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. <strong>Volume Mount Options (Advanced)<\/strong><\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Read-only mount:<\/strong> <code>docker run -it -v mydata:\/data:ro ubuntu bash<\/code><\/li>\n\n\n\n<li><strong>Mount subdirectory of host:<\/strong> <code>docker run -it -v \/home\/ubuntu\/specific-dir:\/data ubuntu bash<\/code><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. <strong>Summary Table<\/strong><\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Volume Type<\/th><th>Command Example<\/th><th>Data Persistence<\/th><th>Host Path Control<\/th><th>Use Case<\/th><\/tr><\/thead><tbody><tr><td>Named Volume<\/td><td><code>-v mydata:\/data<\/code><\/td><td>Yes<\/td><td>No<\/td><td>Standard, portable data storage<\/td><\/tr><tr><td>Anonymous Volume<\/td><td><code>-v \/data<\/code><\/td><td>Yes<\/td><td>No (random name)<\/td><td>Short-lived, quick storage<\/td><\/tr><tr><td>Bind Mount<\/td><td><code>-v \/host\/dir:\/data<\/code><\/td><td>Yes<\/td><td>Yes<\/td><td>Host-managed data, dev\/testing<\/td><\/tr><tr><td>tmpfs Mount<\/td><td><code>--tmpfs \/data<\/code><\/td><td>No<\/td><td>No<\/td><td>Ephemeral, sensitive data, speed<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. <strong>Lab Checklist<\/strong><\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create, inspect, remove, and prune volumes<\/li>\n\n\n\n<li>Use named, anonymous, bind, and tmpfs mounts<\/li>\n\n\n\n<li>Persist data across containers<\/li>\n\n\n\n<li>Share data between containers<\/li>\n\n\n\n<li>Backup and restore volume data<\/li>\n\n\n\n<li>Explore mount options (ro, size, etc.)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Challenge Lab<\/strong><\/h2>\n\n\n\n<p>Try the following scenario:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Start a container with both a named volume and a bind mount. <code>docker run -it -v mydata:\/volume-data -v ~\/docker-bind:\/bind-data ubuntu bash<\/code><\/li>\n\n\n\n<li>Write different files to both directories, then restart the container and verify persistence.<\/li>\n\n\n\n<li>Backup both the named volume and the bind mount to your host system.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>End of Lab<\/strong><\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"epyt-gallery\" data-currpage=\"1\" id=\"epyt_gallery_15356\"><iframe loading=\"lazy\"  id=\"_ytid_60040\"  width=\"760\" height=\"427\"  data-origwidth=\"760\" data-origheight=\"427\" src=\"https:\/\/www.youtube.com\/embed\/?enablejsapi=1&autoplay=0&cc_load_policy=0&cc_lang_pref=&iv_load_policy=1&loop=0&rel=1&fs=1&playsinline=0&autohide=2&theme=dark&color=red&controls=1&disablekb=0&\" class=\"__youtube_prefs__  no-lazyload\" title=\"YouTube player\"  data-epytgalleryid=\"epyt_gallery_15356\"  allow=\"fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen data-no-lazy=\"1\" data-skipgform_ajax_framebjll=\"\"><\/iframe><div class=\"epyt-gallery-list\"><div>Sorry, there was a YouTube error.<\/div><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Below is a very detailed tutorial and lab manual for learning Docker Volumes, using the Ubuntu image for practical, hands-on labs. This covers all major types of Docker volumes, their&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[4862],"tags":[],"class_list":["post-23607","post","type-post","status-publish","format-standard","hentry","category-docker"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/23607","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=23607"}],"version-history":[{"count":4,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/23607\/revisions"}],"predecessor-version":[{"id":49916,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/23607\/revisions\/49916"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=23607"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=23607"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=23607"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}