[Docker] Volume and Network

Docker Volume

Data Persistence

Containers were meant and designed for stateless workloads and the design of the container layers shows that.

A Docker image is a read-only template consisting of various layers and when the image is run as a container, the container contains a small write-only layer of the data. This means:

  • The data is locked tightly to the host and makes running applications that share data across multiple containers and applications difficult.
  • The data doesn’t persist when the container is terminated and extracting the data out of the container is difficult.
  • Writing to the container’s write layer requires a storage driver to manage the filesystem.

For a containerized stateful application, such as an application that requires a database, the data from the previous container will no longer be accessible when an existing container is removed or a new container is added.

Solutions to this problem:

  • tmpfs mounts
  • Bind mounts
  • Volumnes

tmpfs Mounts

1
2
3
docker run -it --name tmpfs-test --mount type=tmpfs, target=/
tmpfs-mount ubuntu bash
docker run -it --name tmpfs-test --tmpfs /tmpfs-mount ubuntu bash

tmpfs mounts are best for containers that generate data that doesn’t need to be persisted and doesn’t have to be written to the container’s writable layer

Bind Mounts
In bind mounts, the file/directory on the host machine is mounted into the container.

We’ll try to mount our Docker host’s home directory to a directory called host-home within the container. To do this, type the following command:

1
2
3
docker run -it --name mount-test --mount type=bind,source="$HOME",
target=/host-home ubuntu bash
docker run -it --name mount-test -v $HOME:/host-home ubuntu bash

If a file is created by a bind mount of the home directory of the Docker host, the file should also be created in the home directory of the Docker host.

Bind mounts are of immense help and are most often used during the development phase of an application.

Remember with bind mounts, the data flow goes both ways on the Docker host as well as the container. Any destructive actions (such as deleting a directory) will negatively impact the Docker host as well.

Volumes
Docker volumes are the current recommended method of persisting data stored in containers. Volumes are completely managed by Docker and have many advantages over bind mounts:

  • Volumes are easier to back up or transfer than bind mounts
  • Volumes work on both Linux and Windows containers
  • Volumes can be shared among multiple containers without problems

Commands:
docker volume create
docker volume inspect
docker volume ls command shows all the volumes present on the host.
docker volume prune removes all unused local volumes.
docker volume rm

1
2
docker volume create --name=<name of the volume> --label=<any extra metadata>
docker volume inspect <name of the volume>

Using Volumes when starting a container

1
2
3
docker run -it --name volume-test --mount target=/data-volume
ubuntu bash
docker run -it --name volume-test -v:/data-volume

Volume in the Dockerfile
VOLUME ["/data-volume"]

Docker Network

Container networking helps in allowing (or limiting) cross container talk. To facilitate Docker, it also comes with different modes of networks.

  • bridge
  • host
  • overlay
  • macvlan
  • none

A bridge network is a user-defined network that allows for all containers connected on the same network to communicate. Bridge networks are useful when we have containers running on the same host that need to talk to each other. If the containers that need to communicate are on different Docker hosts, the overlay network would be needed.

Docker Compose

By just providing a YAML file describing the containers required and the relation between the containers, Docker Compose lets us bring up all the containers with a single command.

  • Build, stop, and start the containers associated with the application
  • Tail the logs of the running containers, saving us the trouble of having to open multiple terminal sessions for each container
  • View the status of each container

Docker Compose helps you enable continuous integration.

the Compose file is a YAML configuration file that defines the services, networks, and volumes that are required for the application to be started. Docker expects the compose file to be present in the same path into which the docker-compose command is invoked having a file name of docker-compose.yaml (or docker-compose.yml).

docker-compose up
docker-compose stop stop the containers
docker-compose start resume the containers
docker-compose logs
docker-compose down completely tear down the containers

1
2
3
4
5
6
7
8
9
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: dontusethisinprod
ports:
- "3306:3306"
volumes:
- "dbdata:/var/lib/mysql"

The data of the MySQL database is stored in a volume known as dbdata, which is mounted onto the directory /var/lib/mysql of the container. This is where MySQL stores the data. In other words, any data saved to the database in the container is handled by the volume named dbdata.