Containers

A computer program is composed of two main parts: code and data. Code is the instructions that are executed by the computer. Data is the information that is processed by the code. In order to run a program, the code must be loaded into the memory. The memory is a temporary storage that is used by the CPU to store the code and data.

Code part of a program is contained in a file which is called an executable file (.exe in Windows, no common extension in Linux and MacOS). An executable file may contain cpu instructions and data that will be loaded into the memory. If the program does not need to load some data into memory before running, then the executable file can run some instructions in order to read the data from a file. Or if the program needs to store a data in a persistent way, then the program can write the data to a file. These operations are done by using operating system's system calls.

Therefore, a large program can be considered as a collection of executable files and data files (sometimes called assets, resources, etc.). However, an executable file may need a library in order to run. A library is a collection of functions that can be used by a program. These files are not executable files, but they are needed by the executable file in order to run (in Windows, they have .dll extension, in Linux they have .so extension, in MacOS they have .dylib extension). In order to run a program, the operating system must load the executable file and the libraries into the memory or the library can be loaded into the memory when the program needs it.

A static binary is an executable file that contains all the code and does not need any library in order to run. On the other hand, a dynamic binary is an executable file that needs a library in order to run. If the library is not found in the system, then the program will not run and will give an error. Also, if a library is updated, then all the programs that use this library also will be affected this change. This may cause a problem because the program may not work as expected.

A container is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries, and settings. Therefore every library that is needed by the program is included in the container. This means that the program may run in any environment that shares the same operating system kernel. This is because the container does not contain the operating system itself, but it contains the all other parts that are needed by the program.

This approach solves the problems that are mentioned above. However, it is not enough to bundle all dependencies of a program into a single package. Also we need an isolation mechanism in order to run multiple containers on the same machine in a secure way. This isolation is done by the operating system kernel. The operating system kernel is the core of the operating system that manages the hardware and provides services to the programs. The kernel is responsible for managing the memory, the CPU, the file system, the network, etc. Indeed, each process (a running instance of a program) is isolated from each other in memory. This means that a process cannot access the memory of another process by default. However, filesystem, network, etc. are shared between processes. In order to isolate these parts. Linux introduced namespaces and cgroups. By utilizing these features of the Linux kernel, containers can work on a complete isolation.

Therefore, contaieners may be used for isolation without the need of virtual machines. This comes with a significant performance improvement. For this reason, containers are widely used in the industry. However, in order to work with containers, you need some tools to build container images, run containers, and manage containers. These tools generally comes in a bundled package called container runtime.

Docker

Docker is one of the most popular container runtimes in the industry.

WIP: Container Image WIP: Container Registry WIP: Dockerfile

Docker Compose

App Runner

Serverless

AWS Lambda