Docker is a tool that enables developers to package their code to run in different environments. Containers contain processes, and all the dependencies to run those processes. In essence what Docker gives us is portable processes.
In this session we are going to build and run our own containers. Most docker images are build from 'base images' that resemble the various Unix operating systems. This is for lots of reasons; Unix/Linux operating system is open source, unlike Windows and MacOS that require a license to run. The favours of Unix that docker containers are build from are super lightweight, which makes them easier to store and run on remote computers.
For this reason before we get into Docker it's worth familiarising ourselves with the Unix operating system.
This operating system usually runs without a Graphical User Interface (GUI). It is built to run software, apps and services on servers. It has 3 parts that we need to know about:
The kernel of Unix is the hub of the operating system. It allocates time and memory to programs and handles file storage and communications in response to system calls.
This is how you can interact with the kernel. The shell presents an interactive terminal into which we can type commands. For example we can get the kernel to read all the files in a directory and have them listed in the shell.
ls -l
The shell command above requests that the kernel run the program ls
the -l
'flag' is an option asking for the long format list. The kernel reads the file system and returns the result.
total 56
drwxr-xr-x 2 root root 4096 Aug 27 11:05 bin
drwxr-xr-x 5 root root 360 Sep 15 14:42 dev
drwxr-xr-x 1 root root 4096 Sep 15 14:42 etc
drwxr-xr-x 2 root root 4096 Aug 27 11:05 home
drwxr-xr-x 7 root root 4096 Aug 27 11:05 lib
drwxr-xr-x 5 root root 4096 Aug 27 11:05 media
drwxr-xr-x 2 root root 4096 Aug 27 11:05 mnt
drwxr-xr-x 2 root root 4096 Aug 27 11:05 opt
dr-xr-xr-x 183 root root 0 Sep 15 14:42 proc
drwx------ 2 root root 4096 Aug 27 11:05 root
drwxr-xr-x 2 root root 4096 Aug 27 11:05 run
drwxr-xr-x 2 root root 4096 Aug 27 11:05 sbin
drwxr-xr-x 2 root root 4096 Aug 27 11:05 srv
dr-xr-xr-x 13 root root 0 Sep 15 14:42 sys
drwxrwxrwt 2 root root 4096 Aug 27 11:05 tmp
drwxr-xr-x 7 root root 4096 Aug 27 11:05 usr
drwxr-xr-x 12 root root 4096 Aug 27 11:05 var
One of the design ideas behind Unix is that everything is a file. Small programs that do one thing can be used in combination together to do many complex things. For example if you want to change directory, there is a Unix program dedicated to that called cd
. If you change into the /bin
folder and list all the files there you can see all the Unix programs listed. Everything is a file, including folders. A folder is a file with a list of other files in it.
Some files are executable and run by the kernel in memory, those processes get a dedicated PID (process ID) which you can use to kill (stop the process) or address from other programs.
In the list of files (that represent folders) above can you see a 10 character string that looks like this:
drwxr-xr-x
These are the permissions of the file and you can read them as follows. The first character indicates file is a folder d
(stands for directory). If it is a file you will see a hyphen -
.
The next group of 3 characters represent the owner of the file's access, and they are in order rwx
which stands for read, write, execute. So if I create a file, I would expect that I can read it, write to it or execute it.
The next 3 characters represent what groups of users can do. Users in Unix can belong to a group, for example you might have a group called 'apprentices'. I can limit access to a file for this group. For example I could removing write access by modifying the permission to r-x
that means read, and execute. How have I changed the permission? Now if you are in the 'apprentices' group you can read the file and execute it, but if you try to write to that file, the Unix system will not allow it. It will throw an error.
The last three characters are the permissions for everyone else. So maybe everyone else can execute the file, but they can't read or write to the file. How would you define those permissions?
As in most operating systems Unix has users. You create users in the Alpine distribution (based on the Busybox flavor of Unix) with the following command.
adduser some_username some_group
As with lots of Unix shell programes there are options you can pass to adduser
to see them just use the --help
flag. You can see all the users in a list by using the cat
program to output the contents of passwd file
cat /etc/passwd
Not that elegant but it works.
Understanding these 3 aspects of Unix is a pre-requisite for starting to work with docker containers, and begin to containerise your own apps. Try the assignment below and lets start to use docker to explore the Unix Alpine base image.
docker run -it alpine /bin/sh
login
as your new userwget --help
)chown --help
)from this:
to this:
login --help
)api-example.yaml
file and read it (hint cat --help
)./api-example.yaml
try to write to it echo "my edit" >> api-example.yaml
You can log out a user by just typing exit
you will then be the root
user again.
* this command invokes docker
, to run
an -it
interactive container called alpine
and when the container starts, execute the program /bin/sh
which is the sh
(shell program) located in the /bin
binary folder at the root of the file system. This will give you a Unix environment to play in!