Laravel is an open source php framework which makes it easier to make web applications.After installing and understanding the basics of Laravel I started exploring the files and how the application runs. Using the sail up command I started the application's container which made the application locally available for me to look at and try on. Since docker containers are loosely isolated I wanted to know about the extent of this isolation, I dived deeper into the files to find out.
As I was exploring the files, which were in the example-app directory on my local system, I started performing some changes to the code in order to understand Laravel better. I noticed that even though the application is being run by a container, the complete code of the application is accessible to me locally, so I made some changes to the blade template just to see how the files inside the container will react.
Image : Adding <> to the blade template from VSCode to the files stored in local system
Now, after saving this, I have a look at the application, everything was displaying and running normally, without any hiccups, so I decided to log into the container using terminal and have a look at the files inside the container.
Image : Added <> to the blade template from VSCode is visible inside the container as well.
How does this happen ?
So how does this happen? How do changes to local files end up being synced all the way to files stored in a specific directory inside the container. This happens due to a bind mount being present from the local system’s file directory to the container’s html directory.
A bind mount creates a replication of the directory it is connected to under a different point.
It does this over FUSE Server which is an inbuilt file system for docker, which uses gRPC protocol to transfer files between local machine and the container. FUSE (Filesystem Under uSerspacE). First the container sends a request to the FUSE client running on the container, which creates a socket using AF_VSOCK to contact the VMBUS which opens a AF_HYPERV(this socket is only with windows, with Linux systems it is still a AF_VSOCK socket) socket to transfer the data to the NTFS using FUSE server running on localhost.
In Linux, there are too types of mounts, bind mounts and file system mounts, they are stored in files mtab and fstab respectively. In mtab only those binds/paths are present which have already been mounted but with file system mounts entire file systems during booting of the linux system.
Image : The list of mounts present in the mstab file
In the above image we can see the mtab file, in which we can other mounts of the system as well.
Followed by the location of the mounted directory, we have the mounting flags, which are nosuid, nodev ,relatime which specify the mounting characteristics.
How are bind mounts useful?
Data present in the container is generally not stored anywhere and is lost once the container is shut down or if it fails on its own, to keep data which is being processed on the container free from loss we can create bind mounts between the host machine and the container to transfer data from the host machine to the container and vice versa. This can be also helpful in cases like ours where we have an application's code present on the local system, and whenever the container is running it takes the code from the mounted directory.
You can read more about them here.
There are various ways to insert data into a container from an external storage device or a host machine, we looked at barely one of them in this blog, if you are interested in learning more on the topic then you can check out this which is considered a better option than bind mounts since it works on both Windows and Linux containers.