Notes from the course Docker for absolute beginners presented by Saurabh Dhingra on Coursera.
Why Docker? The different components of an application may have specific requirements regarding libraries and dependencies, operating system, and server. And those requirements might be imcompatible.
One could install them on different VMs, but that is costly. Alternative: putting them on containers.
Container is an isolated area with its on dependencies and libraries installed. The containers run on the same OS and the same server.
docker is installed as a service. On Ubuntu, to check if it is running:
systemctl status docker
If the application running on a docker crashes, we can run it without using
systemctl, using sudo dockerd
. It shows log messages. Or even sudo dockerd --debug
.
How to create and run a docker container from a docker image. Docker image
contains application code and stuff to make the application run. Example (after
having called sudo dockerd
in a separate shell):
rhyme@ip-10-199-122-109:~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:80f31da1ac7b312ba29d65080fddf797dd76acfb870e677f390d5acba9741b17
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
A. The Docker client contacted the Docker daemon.
B. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
C. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
D. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
The docker image
There is a command in each docker image which initiates the docker execution. In
this hello-world
image, it has printed that previous message.
It gets the image from the the docker hub. That is the default docker public registry.
There is no container running now:
rhyme@ip-10-199-122-109:~$ docker container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
The history of execution of the containers shows it has exited:
rhyme@ip-10-199-122-109:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
771570b2ef26 hello-world "/hello" 6 minutes ago Exited (0) 6 minutes ago awesome_galileo
This container had the name awesome_galileo
. Each time a image is executed, a
container with a new name is created. One can specify the container name using
the option --name
. On this image, it was executed the command /hello
.
Some of the flags used for running a image are:
i
: interactive (keep STDIN open even if not attached)t
: allocate a pseudo-TTYd
: detach (run container in background and print container ID)
Running ubuntu as an image:
rhyme@ip-10-199-122-109:~$ docker run -itd ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
125a6e411906: Pull complete
Digest: sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d
Status: Downloaded newer image for ubuntu:latest
5d0c8bb99ebdf5a023983f6559cae6ee8798f4c6d8fb2a00f09a2b1b1de5e92f
rhyme@ip-10-199-122-109:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d0c8bb99ebd ubuntu "bash" 3 minutes ago Up 3 minutes gallant_chebyshev
To stop the container, either give its name or its ID (can be only some chars of it). It can be restarted given the same identification:
rhyme@ip-10-199-122-109:~$ docker stop 5d
5d
rhyme@ip-10-199-122-109:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d0c8bb99ebd ubuntu "bash" 6 minutes ago Exited (137) 8 seconds ago gallant_chebyshev
fcf827ec1e62 hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago eloquent_ramanujan
771570b2ef26 hello-world "/hello" 20 minutes ago Exited (0) 20 minutes ago awesome_galileo
rhyme@ip-10-199-122-109:~$ docker start 5d
5d
rhyme@ip-10-199-122-109:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d0c8bb99ebd ubuntu "bash" 7 minutes ago Up 8 seconds gallant_chebyshev
To remove a container:
rhyme@ip-10-199-122-109:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d0c8bb99ebd ubuntu "bash" 13 minutes ago Exited (137) 23 seconds ago gallant_chebyshev
fcf827ec1e62 hello-world "/hello" 16 minutes ago Exited (0) 16 minutes ago eloquent_ramanujan
771570b2ef26 hello-world "/hello" 26 minutes ago Exited (0) 26 minutes ago awesome_galileo
rhyme@ip-10-199-122-109:~$ docker rm 5d
5d
rhyme@ip-10-199-122-109:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fcf827ec1e62 hello-world "/hello" 16 minutes ago Exited (0) 16 minutes ago eloquent_ramanujan
771570b2ef26 hello-world "/hello" 26 minutes ago Exited (0) 26 minutes ago awesome_galileo
Remove all containers:
rhyme@ip-10-199-122-109:~$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
fcf827ec1e6236b54eec64f5d7d62e4f89155c01ac420d063821461e0b406298
771570b2ef26296374dbb7eea070d34a4400e0da5de8da7312263aa0870c5953
Total reclaimed space: 0B
rhyme@ip-10-199-122-109:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
To remove images (it will only affect images that are not used by/attached to any container):
rhyme@ip-10-199-122-109:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest d2e4e1f51132 13 days ago 77.8MB
hello-world latest feb5d9fea6a5 7 months ago 13.3kB
rhyme@ip-10-199-122-109:~$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest d2e4e1f51132 13 days ago 77.8MB
hello-world latest feb5d9fea6a5 7 months ago 13.3kB
rhyme@ip-10-199-122-109:~$ docker rmi ubuntu
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d
Deleted: sha256:d2e4e1f511320dfb2d0baff2468fcf0526998b73fe10c8890b4684bb7ef8290f
Deleted: sha256:e59fc94956120a6c7629f085027578e6357b48061d45714107e79f04a81a6f0c
rhyme@ip-10-199-122-109:~$ docker image rm hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:80f31da1ac7b312ba29d65080fddf797dd76acfb870e677f390d5acba9741b17
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359
rhyme@ip-10-199-122-109:~$ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
To download an image without running it:
rhyme@ip-10-199-122-109:~$ docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
125a6e411906: Pull complete
Digest: sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
rhyme@ip-10-199-122-109:~$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest d2e4e1f51132 13 days ago 77.8MB
Running the image ubuntu without the detach flag opens bash:
rhyme@ip-10-199-122-109:~$ docker run -it ubuntu
root@180754b28733:/# ls
bin dev home lib32 libx32 mnt proc run srv tmp var
boot etc lib lib64 media opt root sbin sys usr
root@180754b28733:/# exit
exit
rhyme@ip-10-199-122-109:~$
Otherwise, if the container is detached, it can be accessed later:
rhyme@ip-10-199-122-109:~$ docker run -itd ubuntu
e51bf16aed17f1fc03fe79108d1d811cd1a8e449798ae2f691df89e1aaa19f02
rhyme@ip-10-199-122-109:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e51bf16aed17 ubuntu "bash" 13 seconds ago Up 12 seconds hungry_greider
rhyme@ip-10-199-122-109:~$ docker exec -it e5 bash
root@e51bf16aed17:/#
To exit, just type exit
or Ctrl+D
.
It can be executed command without the using the interactive mode:
rhyme@ip-10-199-122-109:~$ docker exec e5 ls
bin
boot
dev
etc
...
To inspect a container or an image:
rhyme@ip-10-199-122-109:~$ docker inspect e5
[
{
"Id": "e51bf16aed17f1fc03fe79108d1d811cd1a8e449798ae2f691df89e1aaa19f02",
"Created": "2022-05-13T12:58:12.212417997Z",
"Path": "bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
...
rhyme@ip-10-199-122-109:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest d2e4e1f51132 13 days ago 77.8MB
rhyme@ip-10-199-122-109:~$ docker image inspect d2
[
{
"Id": "sha256:d2e4e1f511320dfb2d0baff2468fcf0526998b73fe10c8890b4684bb7ef8290f",
"RepoTags": [
"ubuntu:latest"
],
"RepoDigests": [
"ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d"
],
"Parent": "",
"Comment": "",
"Created": "2022-04-29T23:21:15.708209475Z",
...
Deploying a web application like Jenkins:
rhyme@ip-10-199-122-109:~$ docker pull jenkins/jenkins
Using default tag: latest
latest: Pulling from jenkins/jenkins
6aefca2dc61d: Pull complete
4f7808c00553: Pull complete
...
rhyme@ip-10-199-122-109:~$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
jenkins/jenkins latest f4079e4b5013 2 days ago 461MB
ubuntu latest d2e4e1f51132 13 days ago 77.8MB
Check which are the ports exposed:
rhyme@ip-10-199-122-109:~$ docker image inspect f4 | grep ExposedPorts -A 3
"ExposedPorts": {
"50000/tcp": {},
"8080/tcp": {}
},
Jenkins actually runs on the port 8080. This is the port of the Jenkins
container. To access the Jenkins container through the host machine, we need to
map it to an external port (i.e., the host port). The following command runs the
image jenkins/jenkins
on detached mode, mapping the host port 80 to the
container port 8080:
rhyme@ip-10-199-122-109:~$ docker run -d -p 80:8080 jenkins/jenkins
4837e4f31df22702034bfb1cf4e70e0e8a3804bfd076f42551c0e8f4fe431850
rhyme@ip-10-199-122-109:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4837e4f31df2 jenkins/jenkins "/sbin/tini -- /usr/\u2026" 12 seconds ago Up 11 seconds 50000/tcp, 0.0.0.0:80->8080/tcp quizzical_pike
e51bf16aed17 ubuntu "bash" 26 minutes ago Up 26 minutes hungry_greider
Now, if I open on the browser this URL http://localhost:80/, I’ll get a Jenkins page “Getting started”. According to the instruction on this site, to access it, one need to get the password in a given file. To do that:
rhyme@ip-10-199-122-109:~$ docker exec 48 cat /var/jenkins_home/secrets/initialAdminPassword
2f1135059bbc41ce937cc47742e745cc
Docker networks
There are three ways to connect the container to the network:
- Bridge network: the default. Each container is behind the IP mask 172.17.0.0.
Ex:
docker run ubuntu
- None network: No network at all. Ex:
docker run ubuntu --network=none
- Host network: The container gets the same network as the host. But you won’t
be able have multiple containers running on the same port like 8080! Ex:
docker run ubuntu --network=host
To list those networks:
rhyme@ip-10-199-122-109:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
ff58ae7bcd9c bridge bridge local
b70de08e4bed host host local
897199270ec8 none null local
rhyme@ip-10-199-122-109:~$ docker network inspect ff
[
{
"Name": "bridge",
"Id": "ff58ae7bcd9cfc1d58f5e148fe53743359e4b34224234c3c83287c97232780a2",
"Created": "2022-05-13T12:20:05.600109711Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
...
When the docker engine is installed in the host machine, it will install an
interface called docker0
:
To check its IP:
rhyme@ip-10-199-122-109:~$ ip addr
...
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:74:8a:32:36 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:74ff:fe8a:3236/64 scope link
valid_lft forever preferred_lft forever
...
In a container, there is a network namespace, which has its own network
interface which is conected through a virtual cable to the host network
interface docker0
.
It is possible to create a new network isolated from the previous one. So, containers linked to one network won’t be able to access the containers linked to the second network:
rhyme@ip-10-199-122-109:~$ docker network create --driver=bridge --subnet=182.1.0.1/16 testingIsolatedNetwork
e3a9af23f061daf37f22a9ea75697ba8d19c6d9d90a43647586d80203f57430d
rhyme@ip-10-199-122-109:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
b19dbc4f1a7d bridge bridge local
b70de08e4bed host host local
897199270ec8 none null local
e3a9af23f061 testingIsolatedNetwork bridge local
rhyme@ip-10-199-122-109:~$ docker network inspect e3
[
{
"Name": "testingIsolatedNetwork",
"Id": "e3a9af23f061daf37f22a9ea75697ba8d19c6d9d90a43647586d80203f57430d",
"Created": "2022-05-13T16:50:46.851712035Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "182.1.0.1/16"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
Creating a new container with the previously created network:
rhyme@ip-10-199-122-109:~$ docker run -itd --name=testUbuntu --net=testingIsolatedNetwork ubuntu
b47e9508376b07690cfa359a82eb1c3a28a3b9be313c6658407974df467fb719
rhyme@ip-10-199-122-109:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b47e9508376b ubuntu "bash" 4 seconds ago Up 3 seconds testUbuntu
e51bf16aed17 ubuntu "bash" 4 hours ago Up 5 minutes hungry_greider
rhyme@ip-10-199-122-109:~$ docker inspect b4
[
{
...
"NetworkSettings": {
"Bridge": "",
...
"Networks": {
"testingIsolatedNetwork": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"b47e9508376b"
],
"NetworkID": "e3a9af23f061daf37f22a9ea75697ba8d19c6d9d90a43647586d80203f57430d",
"EndpointID": "6d7ada31bd723e51da91a3f8b857bc2e93ef528e1af0358e09ee969b5787ab83",
"Gateway": "182.1.0.1",
"IPAddress": "182.1.0.2",
...
}
}
}
}
]
If the container is already running and we want to connect to a new network:
rhyme@ip-10-199-122-109:~$ docker network connect e3 e5
rhyme@ip-10-199-122-109:~$ docker inspect e5
[
{
...
"NetworkSettings": {
...
"Networks": {
"bridge": {
"Aliases": null,
"NetworkID": "b19dbc4f1a7d18a603cbc755ad6e87d600b73b8b2ae36cad4bc916e23fef59be",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
...
},
"testingIsolatedNetwork": {
"Aliases": [
"e51bf16aed17"
],
"NetworkID": "e3a9af23f061daf37f22a9ea75697ba8d19c6d9d90a43647586d80203f57430d",
"EndpointID": "4890c37503bfe111fe149e2e041846fb160be674530d4c34bd44d9247dee2e1c",
"Gateway": "182.1.0.1",
"IPAddress": "182.1.0.3",
...
}
}
}
}
]
Stoping and removing all the running containers:
rhyme@ip-10-199-122-109:~$ docker stop $(docker ps -aq)
b47e9508376b
4837e4f31df2
e51bf16aed17
180754b28733
rhyme@ip-10-199-122-109:~$ docker rm $(docker ps -aq)
b47e9508376b
4837e4f31df2
e51bf16aed17
180754b28733
Removing the created network:
rhyme@ip-10-199-122-109:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
b19dbc4f1a7d bridge bridge local
b70de08e4bed host host local
897199270ec8 none null local
e3a9af23f061 testingIsolatedNetwork bridge local
rhyme@ip-10-199-122-109:~$ docker network rm e3
e3
To remove all created networks if they are not being used:
rhyme@ip-10-199-122-109:~$ docker network prune
WARNING! This will remove all custom networks not used by at least one container.
Are you sure you want to continue? [y/N] y
rhyme@ip-10-199-122-109:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
b19dbc4f1a7d bridge bridge local
b70de08e4bed host host local
897199270ec8 none null local
Note that the default networks are preserved.
Communicating between two docker containers
Creating a new bridge network and two new containers running CentOS. Initially, one container will be using one network, and the second another network:
rhyme@ip-10-199-122-109:~$ docker network create --driver=bridge --subnet=182.0.1.1/16 isolatedNetwork
8fbbd32b9698366ec0c190bee3a62743cfa930483dc3dc170981aee369a016d5
rhyme@ip-10-199-122-109:~$ docker run -itd centos
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
3e3f352266f99945f35f779e8253186d66a69b0fe30cefd39ce33da7d5082d06
rhyme@ip-10-199-122-109:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e3f352266f9 centos "/bin/bash" 18 seconds ago Up 8 seconds interesting_johnson
rhyme@ip-10-199-122-109:~$ docker run -itd --name=test1 --net=isolatedNetwork centos
df383244597344d0daf2f094ed74eb81bd3eeba25b7bd4eec9ca2e3ce3166549
rhyme@ip-10-199-122-109:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df3832445973 centos "/bin/bash" 6 seconds ago Up 5 seconds test1
3e3f352266f9 centos "/bin/bash" 2 minutes ago Up About a minute interesting_johnson
Because they are on different networks, the containers can’t see each other:
rhyme@ip-10-199-122-109:~$ docker exec -it 3e /bin/bash
[root@3e3f352266f9 /]# ping test1
ping: test1: Name or service not known
[root@3e3f352266f9 /]#
I can connect the first container to the network that is being used by the second container, then they’ll communicate:
rhyme@ip-10-199-122-109:~$ docker network connect isolatedNetwork 3e
rhyme@ip-10-199-122-109:~$ docker exec -it 3e /bin/bash
[root@3e3f352266f9 /]# ping test1
PING test1 (182.0.0.2) 56(84) bytes of data.
64 bytes from test1.isolatedNetwork (182.0.0.2): icmp_seq=1 ttl=64 time=0.139 ms
64 bytes from test1.isolatedNetwork (182.0.0.2): icmp_seq=2 ttl=64 time=0.076 ms
64 bytes from test1.isolatedNetwork (182.0.0.2): icmp_seq=3 ttl=64 time=0.072 ms
64 bytes from test1.isolatedNetwork (182.0.0.2): icmp_seq=4 ttl=64 time=0.065 ms
Docker volumes
How to make docker persist the data? When a container is created, there are two layers:
- Docker image layer (read-only)
- Container layer (writable)
When container is deleted, all the data is deleted as well. If I want to
preserve the data, we need to store it in a so called data volume. To do this,
we map the container layer to a volume. The volume resides on the docker host,
so it is external to the container. The created volumes are available in
/var/lib/docker/volumes
. To create a volume:
rhyme@ip-10-199-122-109:/var/lib/docker/volumes$ docker volume create data_volume
data_volume
rhyme@ip-10-199-122-109:/var/lib/docker/volumes$ sudo ls -ltr | grep data_volume
drwx-----x 3 root root 4096 May 13 17:28 data_volume
rhyme@ip-10-199-122-109:/var/lib/docker/volumes$ cd data_volume
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume$ sudo ls -ltr
total 4
drwxr-xr-x 2 root root 4096 May 13 17:28 _data
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume$ cd _data
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ sudo ls -ltr
total 0
To create a container linked to the newly created volume, and map that volume to
the directory /www
:
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ docker run -itd -v data_volume:/www ubuntu
5a06ee073e7ee6a075bbca832c9009cbde6dc29f6f37a0e36f634fde4f287ecc
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a06ee073e7e ubuntu "bash" 4 seconds ago Up 2 seconds pedantic_shaw
Let’s run this container and create a file in this volume:
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ docker exec -it 5a /bin/bash
root@5a06ee073e7e:/# ls
bin dev home lib32 libx32 mnt proc run srv tmp var
boot etc lib lib64 media opt root sbin sys usr www
root@5a06ee073e7e:/# cd www
root@5a06ee073e7e:/www# echo "Test Data" > test.txt
root@5a06ee073e7e:/www# ls
test.txt
root@5a06ee073e7e:/www#
exit
Note that this file is available in the volume folder, and it persists even after stopping and removing the container where the file was created:
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ ls
test.txt
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ docker stop 5a
5a
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ ls
test.txt
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ docker rm 5a
5a
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ ls
test.txt
It is possible to connect another container to that volume:
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ docker run -itd -v data_volume:/www ubuntu
4e8027c6097cad79d5dd377a85ba3432ebbf78277e51770dcbb5d65f581a7e23
rhyme@ip-10-199-122-109:/var/lib/docker/volumes/data_volume/_data$ docker exec -it 4e bash
root@4e8027c6097c:/# cd www
root@4e8027c6097c:/www# ls
test.txt
This was the default volume mount. There is also the bind volume mount:
rhyme@ip-10-199-122-109:~$ docker run -it -v /home/rhyme/data:/www ubuntu
root@a0057d52bf0b:/# cd www
root@a0057d52bf0b:/www# echo "Test data" > test.txt
root@a0057d52bf0b:/www# ls
test.txt
root@a0057d52bf0b:/www# exit
rhyme@ip-10-199-122-109:~$ ls data
test.txt
No new volume is listed:
rhyme@ip-10-199-122-109:~$ docker volume ls
DRIVER VOLUME NAME
local 75d5ae2552776b37d6ae34e659941e7c01d91c9f9956777b43c460d05cb6f593
local 40119234d3647a7aad0685353a657383c98e733dc3b9fa54785cae19bc40469e
local a1b3908774dd64b94ece53b3a7df11d039fb7cb07b7aff3a2eb2e59fa6d9f874
local c7c7f58dc3715d0809145f810cab2f079df20be6e2e77b349c88b1ca02913a67
local data_volume
Alternative syntax to create a container using a bind mount:
rhyme@ip-10-199-122-109:~$ docker run -it --mount type=bind,source=/home/rhyme/data,target=/www ubuntu
root@1cafb804c603:/# ls www
test.txt
root@1cafb804c603:/#
To delete a volume:
rhyme@ip-10-199-122-109:~$ docker volume rm data_volume
data_volume