Each one of these layers correspond to an instruction in the Dockerfile.
We use a Dockerfile to build a read-only image that we will later run in containers.
Below is an example of a Dockerfile:
And we run the below command to get our docker image:
After the build, all the layers are read-only.
Running the image in a container:
We run the debian image in a container using the below command:
After we run the above command, docker adds a new writable layer on top of the read-only layers.
Anytime docker creates a new element (file, interface, ...), or makes a change to an element in the read-only layers , the change is written to the writable layer using the COW (Copy On Write) model.
When the container exits, the writable layer and all its data are lost.
Persistent volumes (volume mount):
If we want to keep our data after the container exits, we need to create a persistent volume.
The below command creates the "/var/lib/docker/volumes/data_1" folder on the host and mounts it inside the container on the mountpoint "/var/lib/database" and runs the "mongo" image.
If our container exits, we would still have our data in the folder: "/var/lib/docker/volumes/data_1"
Alternative location for storage (bind mounting):
When we want to store our data in a location different than the default one "/var/lib/docker/volumes", we provide in that case the full path to the location we want to store our container's data in.
path_h: path on the host.
path_c: path inside the container.
The storage driver manage the storage of images and takes care of the data written to the writable layer of the image.
It also manages the storage of images and containers.
Examples of storage drivers include for example: ZFS, BTRFS, OVERLAY, ...
Volume drivers plugins:
The volume driver plugins manage volumes and allows docker containers to be deployed with an external storage on a variety of platforms (Convoy, Azure File Storage, ...) We can specify a volume driver when running a container: