Docker: Starting Out 3

So I'm sure at this point you're wondering how to work on files on your local machine. This can be achieved with volumes. It's worth noting that at this point that files stored on containers are lost when the container stops running. I feel Volumes and Networks are the final piece for anyone starting out in Docker to be able to perform basic to intermediate operations. If you haven't seen the previous two articles I suggest you do so at this point.

Docker Starting Out
Docker Starting Out 2

Volumes

Lets continue with the use of the alpine image from the last time. We'll start start a new instance of the alpine image (I mean create a new alpine container).

docker run -ti --name nerdhands -v /data -d alpine sh  

Now, navigate into the /data folder and make some changes. Lets create a file for the sake of the tutorial, just to get the whole idea.

cd /data # navigate into the folder  
touch file.txt # create a file called file  
exit  

After exiting the shell prompt, we have to restart the container

docker kill nerdhands # terminate the process  
docker start nerdhands # restart the nerdhands container  
docker exec -ti nerdhands sh # start the container with shell prompt  

Once in the shell prompt type the following commands to confirm that our file is still in the container

cd /data # navgate to the data volume  
ls # list files  

Let us now map a folder on the host machine to the data volume in the container instance on creation (a.k.a create a host data volume). Only folders in a users profile directory can be mapped and must be absolute. e.g C:/Users/chile/folder_path

docker run --name nerhdands -v C:/Users/chile/folder_path:/data -d alpine sh  

You have now successfully created a container named nerdhands (--name nerdhands) that will start in the background as a daemon (-d) and most importantly map a folder in the container to one on your system (-v C:/Users/chile/folder_path:/data). Now launch the container using.

docker exec -ti nerdhands sh  

Lets go ahead and play with the mapped directory using some Linux shell command magic.

ls /data # view the content of our directory  
cd /data # go into the directory  
mkdir Ichigo # create a new folder  
cd /Ichigo # enter the newly created Ichigo folder  
vi bankai.txt # Hit [insert] enter a few text words and then hit [esc], type :wq and hit [enter]  
exit # exit the shell  

and then to kill the running daemon (our nerdhands container)

docker kill nerdhands  


Using this method, you can also simply mount a single file as a volume to the container instead of an entire directory.

docker run --name nerhdands -v C:/Users/chile/folder_path/file.txt:/data/file.txt -d alpine sh  

Now go over to the folder you mapped to the container to view the changes you've made. Cool huh. Lets go deeper into volumes and data then.
Let us now look at creating a a special kind of volume that can be used by any container by simply referencing the given name during creation of the container. Lets see what it takes to create such a cotainer.

docker create -v /data --name data-container alpine /bin/true  

Now to use this data volume container

docker run -d -ti --volumes-from data-container --name container-user-1 alpine sh  
docker run -d -ti --volumes-from data-container --name container-user-2 alpine sh  
docker run -d -ti --volumes-from data-container --name container-user-3 alpine sh  

All three containers now have access to data-container. Now even if there's a /data folder in the container, the data-container data volume container takes over, which means you will also see files from data-contaner. You can run ls / to confirm the existence of our newly created volume. If you choose to, you can have multiple data volume containers attached to a container by simply using multiple --volumes-from-container as in the example below.

docker run -d -ti --volumes-from data-container-1 --volumes-from data-container-2 --volumes-from data-container-3 --name container-user-1 alpine sh  

But you need to have created those data containers before hand. In cases where you want to add multiple data volume containers to multiple app containers, you can simply reference a container which already has the data containers attached to it.

docker run -d -ti --volumes-from container-user-1 --name container-user-2 alpine sh  
docker run -d -ti --volumes-from container-user-1 --name container-user-3 alpine sh  

This way the data volume containers are automatically attached to our other two containers upon creation.
You can view the data volume containers you've created by using the below command.

docke volume ls  

Docker volume ls

Other actions you can perform include, inspecting the volume to get some more info about about a specific data container and also delete it.

docker volume inspect [name]  
docker volume rm [name]  


Docker volume inspect

You can't remove a volume that is in use by other containers. You'd first of all have to delete the containers before you can delete the volume.

Docker rm error

Networks

Very important in going into to Docker is understanding networks and networking in Docker. How do I make use of the host network, how do I link up the containers, how do I create my own network etc. lets touch on all these concerns. There's a likelihood that if you're web developer who's trying out Docker you'd do some network configuration at some point.
By default Docker automatically creates three networks for you when installed (see image below) but this is not to say that you're limited to what you can do. The docker network ls command is used to list the available networks.

Docker network ls

Creating your own network is as simple as running the below command. You supply the create command, the network name and the driver. You can use any of the three default drivers and custom drivers as well. You can run the ls command to view your network amongst the list of existing networks.

docker network create -d bridge new-network-1  

Docker new network

Lets make use of our alpine images some more to understand the concept of networks. First we'll create two containers, one named nerdhands-network-1 which will use our default network config and the other nerdhands-network-2 :) which we will tell to use our newly created network.

docker run -ti --name nerdhands-network-1 -d alpine sh  
docker run -ti --net=new-network-1 --name nerdhands-network-2 -d alpine sh  

Now lets go into the first container and copy ipaddress using ifconfig linux command.

docker exec -ti nerdhands-network-1 sh  
ifconfig  
exit  

Network ifconfig

Now after exiting, we go into the second container to try ping the container.

docker exec -ti nerdhands-network-2 sh  
ping [ipaddress] -w 5  

Network ifconfig fail

You will notice that there's a 100% loss in packets. Now lets create a third network nerdhands-network-3 and add it to our custom bridge. We will create it without the -d so that it takes us straight to the shell prompt.

docker run -ti --net=new-network-1 --name nerdhands-network-3 alpine sh  
ifconfig  

Straight up, ifconfig gives you a clue that you're on the same network with the nerdhands-network-2 container.

Same network ifconfig

Now lets try pinging the nerdhands-network-2 container. Hope you copied the ip, else it would be a good time to master a skill else you can try pinging the container using the name.

ping nerdhands-network-2  

Same network ping

Same network ping with container name

Nothing stops you from creating a container that resides directly on the host system itself. There are scenarios where this is exactly what you want.

docker run -tid --net=host --name nerdhands-network-4 alpine sh  

Since you can access containers over the network using their names, you can as well replace that db string with ip address to the container name.

We can also map port numbers in the containers to the host system. This can be done either automatically or explicitly specifying it

For automatically assigning ports

docker run -tid -P --name nerdhands-network-5 alpine sh  

For explicity specifying ports

docker run -tid -p 8118:8000 --name nerdhands-network-5 alpine sh  

Well, yeah our alpine image does not have a running web app but nothing stops you from installing and configuring a web server on it or even a db if you choose. So please try that on your own.

We have now come to end of the Docker: Starting Out series. From here on its all advanced stuff. For the first two parts of the series use the links below.

Docker Starting Out
Docker Starting Out 2

But who is to say that this is the very end :D
Another One

Show Comments