This is the third part of our Learn docker by example series. In this blog, we will learn docker volume by example. We will be deploying a Redis container using docker. So let’s get started.
Docker volume example
I will be running a redis container to demonstrate how the docker volume works in this session. If you are not familiar with redis, you can check my blog to get a basic overview of redis.
Let’s verify if the docker is running in your system by typing the below command:
docker --version Docker version 20.10.3, build 48d30b5
Now, pull a redis image from the dockerhub by typing the below command:
docker pull redis Using default tag: latest latest: Pulling from library/redis Digest: sha256:7e2c6181ad5c425443b56c7c73a9cd6df24a122345847d1ea9bb86a5afc76325 Status: Downloaded newer image for redis:latest docker.io/library/redis:latest
Verify if the images get successfully pulled:
docker images REPOSITORY TAG IMAGE ID CREATED SIZE redis latest fad0ee7e917a 2 weeks ago 105MB
Awesome, now let’s run this redis container in the background:
docker run --name my-redis -d redis:latest 1b0e45aef1c81c432443089cbf4f1d3ab626d12194c96cb4fad316f16c092369
Verify if the docker container is running
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1b0e45aef1c8 redis:latest "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 6379/tcp my-redis
Now let’s get inside the redis docker container and insert some data into the redis container.
docker exec -it my-redis /bin/bash [email protected]:/data# [email protected]:/data# redis-cli 127.0.0.1:6379>
Insert 3 keys in redis using the MSET command
127.0.0.1:6379> MSET key1 value1 key2 value2 key3 value3 OK 127.0.0.1:6379> MGET key1 key2 key3 1) "value1" 2) "value2" 3) "value3" 127.0.0.1:6379>
Great, now get out of the container by typing the exit command
127.0.0.1:6379> exit [email protected]:/data# exit exit ~
Now let’s kill the redis docker container by using the docker kill command
docker rm -f my-redis my-redis
Now let’s rerun the redis container and verify if our data in redis still exist:
docker run --name my-redis -d redis:latest 814f1bd8fae1c0b888be23d82766c757a88d494d1a804bf524313af5c0d5c4cb ➜ ~ ➜ ~ ➜ ~ docker exec -it my-redis /bin/bash [email protected]:/data# [email protected]:/data# redis-cli 127.0.0.1:6379> MGET key1 key2 key3 1) (nil) 2) (nil) 3) (nil) 127.0.0.1:6379> 127.0.0.1:6379>
You might be wondering what just happened and why my data is missing from redis.
As docker redis containers are running in their environment, and by default, all the container data gets deleted upon deleting the container.
If you wish to persist the data even after the container gets deleted, you can use docker volume to achieve that.
What is docker volume?
Docker volumes are widely used to ensure data persistence while working in containers. There are so many ways to mound volume to a docker container; some of them are:
- You can mound the volume of local storage
- You can mound volume from another container
- You can mound the data from external storage like NFS, s3, etc
For this demo, I will be mounding the data to the host directory
Docker volume mound local directory
In this session, we will be deploying a Redis container and mound a local volume to the Redis container. First, create a folder name ~/Redis-data in your system.
The data can be mound by specifying -v {source-folder}:{container-folder}
Docker run –volume
We can mound volume to a docker container by specifying the –volume or -v option.-v or –volume takes three parameters separated by colon characters (:).The order of fields must be correct.
- For named volumes, the first field is the name of the volume. For anonymous volumes, the first field is omitted.
- The second field is the path where the file or directory is mounted in the container.
- The third field is optional and is a comma-separated list of options, such as ro.
Below is a simple example of a docker container with a volume mound.
docker service create \ --mount 'type=volume,src=<VOLUME_NAME>,dst=<CONTAINER_PATH>,volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"' --name my_service_name \ <IMAGE_NAME>
More details about the docker volume different options can be found here
Let’s run the below command to create a redis container by typing the below command:
docker run --name my-redis -v ~/Redis-data:/data -d redis:latest a297c46fb26537eeff7ec1240ea6eb6a0784aef82fd955799ae03754a8bc4a95
where
~/Redis-data is the local volume where we need to take the data backup.
/data is the folder in the Docker container whose data needs to be backed up in the local directory.
Now, go inside the redis container and insert some data into redis.
docker exec -it my-redis /bin/bash [email protected]:/data# [email protected]:/data# [email protected]:/data# redis-cli 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> keys * (empty array) 127.0.0.1:6379> MSET key1 value1 key2 value2 key3 value3 OK 127.0.0.1:6379> keys * 1) "key2" 2) "key1" 3) "key3" 127.0.0.1:6379>
Now, let’s get out of the docker container and remove the redis container.
docker rm -f my-redis my-redis
Now let’s again create the redis-container by specifying the same docker-volume.
docker run --name my-redis -v /Users/jishanahmad/Redis-data:/data -d redis:latest 814f69fec4df46fed07a2222bc5f53e954c9c9701b39d23c3eae894b26c23812
Go inside the container and check if the redis data exists.
docker exec -it my-redis /bin/bash [email protected]:/data# [email protected]:/data# [email protected]:/data# redis-cli 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> keys * 1) "key2" 2) "key1" 3) "key3" 127.0.0.1:6379>
Fantastic, as you can see from the above output that the redis persisted the data and even container gets deleted our data was intact
Docker-compose volume
So far, we have learned how to assign the volume to a docker container using the docker command line. In this session, we will understand how to assign the volume to containers defined in the docker-compose file.
For this demo, I will be defining the basic docker-compose file and using a redis image to demonstrate the volume assignment. Copy-paste the below code into a docker-compose.yaml file.
version: "3.2" services: redis: image: "redis:latest" ports: - "6379:6379" volumes: - $PWD/redis-data:/var/lib/redis
As you can see in the above dockerfile, we have used volumes: to assign the volume to the container.
volumes: - $PWD/redis-data:/var/lib/redis
We are mounting the local volume $PWD/redis-data to the container volume /var/lib/redis. Now type the below command to start the docker containers
docker-compose up -d
docker-compose up -d Creating network "redis_default" with the default driver Pulling redis (redis:latest)... latest: Pulling from library/redis a2abf6c4d29d: Already exists c7a4e4382001: Pull complete 4044b9ba67c9: Pull complete c8388a79482f: Pull complete 413c8bb60be2: Pull complete 1abfd3011519: Pull complete Digest: sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339 Status: Downloaded newer image for redis:latest Creating redis_redis_1 ... done
Type the below command to verify if the docker container is running
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9c5b4b481c89 redis:latest "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis_redis_1
If you are getting the same output, it means your redis container is running as expected.
Conclusion
We have learned how to deploy a Redis instance within a Docker container. We also learned how to attach the volume to the redis container using the command line and the docker-compose file. I hope you like this tutorial. If so, please do let me know in the comment box.