Skip to main content

Containers: Docker (Part 2)

We will be using a virtual machine in the faculty's cloud.

When creating a virtual machine in the Launch Instance window:

  • Name your VM using the following convention: cc_lab_<username>, where <username> is your institutional account.
  • Select Boot from image in Instance Boot Source section
  • Select CC 2024-2025 in Image Name section
  • Select the m1.large flavor.

In the virtual machine:

  • Download the laboratory archive from here in the /home/student directory. Use: wget https://repository.grid.pub.ro/cs/cc/laboratoare/lab-containers-part-1.zip to download the archive.

  • Extract the archive using unzip lab-containers-part-1.zip

  • Run chmod u+x ./lab-containers-part-1.sh && ./lab-containers-part-1.sh to create the lab-containers-part-1 directory with the necessary files.

  • Navigate to the corresponding directory where you will resolve all the tasks using `cd ./lab-containers-part-1"

$ # Download the laboratory archive
$ wget https://repository.grid.pub.ro/cs/cc/laboratoare/lab-containers-part-1.zip
$ # Extract the archive
$ unzip lab-containers-part-1.zip
$ # Change permissions and execute the setup script
$ chmod u+x ./lab-containers-part-1.sh
$ # Run the setup script
$ ./lab-containers-part-1.sh
$ # Navigate to the working directory
$ cd ./lab-containers-part-1

Recap from the previous laboratory: Containers: Docker (Part 1)

Needs / use-cases

  • easy service install
  • isolated test environments
  • local replicas of production environments

Objectives

  • container management (start, stop, build)
  • service management
  • container configuration and generation

What are containers?

Containers are an environment in which we can run applications isolated from the host system.

In Linux-based operating systems, containers are run like an application which has access to the resources of the host station, but which may interact with processes from outside the isolated environment.

The advantage of using a container for running applications is that it can be easily turned on and off and modified. Thus, we can install applications in a container, configure them and run them without affecting the other system components

A real usecase where we run containers is when we want to set up a server that depends on fixed, old versions of certain libraries. We don't want to run that server on our system physically, as conflicts with other applications may occur. Containerizing the server, we can have a version of the library installed on the physical machine and another version installed on the container without conflict between them.

Containers versus virtual machines?

Both containers and virtual machines allow us to run applications in an isolated environment. However, there are fundamental differences between the two mechanisms. A container runs directly on top of the operating system. Meanwhile, a virtual machine runs its own kernel and then runs the applications on top of that. This added abstraction layer adds overhead to running the desired applications, and the overhead slows down the applications.

Another plus for running containers is the ability to build and pack them iteratively. We can easily download a container from a public repository, modify it, and upload it to a public repository without uploading the entire image. We can do that because changes to a container are made iteratively, saving the differences between the image original and modified version.

There are also cases where we want to run applications inside a virtual machine. E.g, if we want to run a compiled application for an operating system other than Linux, we could not do this because containers can run applications that are compiled for the system host operation. Virtual machines can also run operating systems other than the operating system host.

Volumes

While it makes sense to run Docker containers by themselves as services, all the data that they produce is ephemeral and will be deleted when the container is destroyed.

To provide an input to the containers and a permanent storage for them we use volumes.

Volumes are used to save outputs of files permanently. Start a container based on the image you can build and call infinite-wrierin the background using the following command:

docker run -d --name perpetual-writer -v perpetual-storage:/var/perpetual-storage -t perpetual-writer

Stop it and remove it. Start a new container based on the same image using the same command. Enter the container and check the content of the /perpetual-storage/logs file.

The files are still stored on disk but in the /var/lib/docker directory. To find local mount point of the volume run the docker volume inspect command. List the content of that directory.

Run the scripts in TODO. Identify for each container what volume it is using and what is the path to that volume on disk. There are three containers.

Bind mounts

Bind volumes mount files or directories from the host to a path in the container.

We will be running the nginx container using content on our host system. The command to do this from the repository root is:

docker run --name better-nginx -v $PWD/nginx-website:/usr/share/nginx/html:ro -d nginx

The nginx-website directory is mounted to the /usr/share/nginx/html directory. Change the above command to mount the better-website directory instead. See what has changed.

Add an additional mount point to the above command to mount the nginx-confs/nginx.conf file as the Nginx configuration file fount at /etc/nginx/nginx.conf.