Docker is a popular "containerization" platform that allows developers to run applications inside isolated environments called containers. Containers are similar to virtual machines, however they do not run an entire operating system (like virtualbox, qemu).
In principle containers are somewhat similar to the classic chrooted jailkits that could be used to setup a completely isolated environment within the linux system to run applications securely in a sandbox that would not affect the underlying host system in anyway.
Dockers brings lots of powerful features and makes things a lot easier to do compared to the older jailkit approaches.
Containers just bundle the application along with necessary dependencies into a lightweight package and these containers use the underlying (host) os kernel to run their environment. Since containers use the underlying operating system kernel to run their environment, a linux based container can run only on a linux host os and a windows based container can run only on a windows host os.
This is a short article on how to get started with docker on Ubuntu with as few commands as possible. We shall see how to quickly install docker and run a few commands to launch a container using images from the standard repository.
Note: Our host system is running Ubuntu 22.10
Update apt package cache
Switch to main mirrors on Ubuntu: Before you issue the apt update command, you might want to switch to the main official mirrors intead of local mirrors for better performance. Launch the software properties dialog and select main servers.
lxqt-sudo software-properties-kde
Select main servers, instead of geo-specific local servers and update package cache data.
Next, update the package cache.
sudo apt update
Install the docker.io package
This will install docker and get you ready to do stuff.
sudo apt install docker.io -y
You should be able to check the version now
$ docker -v Docker version 20.10.21, build 20.10.21-0ubuntu1~22.10.2 $
Start docker daemon
Start the docker daemon (server/service) which manages all docker containers.
systemctl start docker
$ systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; preset: enabled) Active: active (running) since Sun 2023-05-28 11:10:43 IST; 2min 55s ago TriggeredBy: ● docker.socket Docs: https://docs.docker.com Main PID: 8052 (dockerd) Tasks: 9 Memory: 20.6M CPU: 601ms CGroup: /system.slice/docker.service └─8052 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.460045832+05:30" level=info msg="scheme \"unix\" not registered, fallback to default scheme" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.460177903+05:30" level=info msg="ccResolverWrapper: sending update to cc: {[{unix:///run/containerd/containerd.sock <nil> 0 <nil>}] <nil> <nil>}" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.460293477+05:30" level=info msg="ClientConn switching balancer to \"pick_first\"" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.955597019+05:30" level=info msg="Loading containers: start." May 28 11:10:43 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:43.204875582+05:30" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP ad> May 28 11:10:43 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:43.414958523+05:30" level=info msg="Loading containers: done." May 28 11:10:43 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:43.542507320+05:30" level=info msg="Docker daemon" commit="20.10.21-0ubuntu1~22.10.2" graphdriver(s)=overlay2 version=20.10.21 May 28 11:10:43 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:43.542620544+05:30" level=info msg="Daemon has completed initialization" May 28 11:10:43 silver-VirtualBox systemd[1]: Started Docker Application Container Engine. May 28 11:10:43 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:43.655478370+05:30" level=info msg="API listen on /run/docker.sock" $
Run the Hello World Container
Now that you have docker installed, its time to do something very basic, like launching the hello-world container.
The "hello-world" container is a dummy sample image that does nothing, other than letting you check whether your docker installation is able to launch containers fine.
$ sudo docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 719385e32844: Pull complete Digest: sha256:fc6cf906cbfa013e80938cdf0bb199fbdbb86d6e3e013783e5a766f50f5dbce0 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ $
When the image for a container does not exist on the host system and you try to launch it, then docker will automatically pull the image from the repository.
Search for Ubuntu images
You can search the online docker hub for images that can be used to launch containers. There are lots of them, each emulating a different distro environment or application.
Here is an example of how to search for ubuntu based images.
$ sudo docker search ubuntu NAME DESCRIPTION STARS OFFICIAL AUTOMATED ubuntu Ubuntu is a Debian-based Linux operating sys… 16003 [OK] websphere-liberty WebSphere Liberty multi-architecture images … 294 [OK] ubuntu-upstart DEPRECATED, as is Upstart (find other proces… 114 [OK] neurodebian NeuroDebian provides neuroscience research s… 100 [OK] ubuntu/nginx Nginx, a high-performance reverse proxy & we… 95 ubuntu/squid Squid is a caching proxy for the Web. Long-t… 60 open-liberty Open Liberty multi-architecture images based… 59 [OK] ubuntu/apache2 Apache, a secure & extensible open-source HT… 58 ubuntu/bind9 BIND 9 is a very flexible, full-featured DNS… 52 ubuntu-debootstrap DEPRECATED; use "ubuntu" instead 51 [OK] ubuntu/mysql MySQL open source fast, stable, multi-thread… 49 ubuntu/prometheus Prometheus is a systems and service monitori… 42 ubuntu/kafka Apache Kafka, a distributed event streaming … 32 ubuntu/postgres PostgreSQL is an open source object-relation… 27 ubuntu/redis Redis, an open source key-value store. Long-… 18 ubuntu/grafana Grafana, a feature rich metrics dashboard & … 9 ubuntu/prometheus-alertmanager Alertmanager handles client alerts from Prom… 9 ubuntu/dotnet-deps Chiselled Ubuntu for self-contained .NET & A… 8 ubuntu/dotnet-aspnet Chiselled Ubuntu runtime image for ASP.NET a… 7 ubuntu/zookeeper ZooKeeper maintains configuration informatio… 6 ubuntu/memcached Memcached, in-memory keyvalue store for smal… 5 ubuntu/dotnet-runtime Chiselled Ubuntu runtime image for .NET apps… 5 ubuntu/telegraf Telegraf collects, processes, aggregates & w… 4 ubuntu/cortex Cortex provides storage for Prometheus. Long… 3 ubuntu/cassandra Cassandra, an open source NoSQL distributed … 2 $
Similarly you can search for any distro images like centos, debian, alpine or fedora.
Pull the Ubuntu image
Once you decide which image you want to use to launch your container, its time to pull the image. In this example we shall simply pull the "ubuntu" image. By default it pulls the latest version.
$ sudo docker pull ubuntu Using default tag: latest latest: Pulling from library/ubuntu dbf6a9befcde: Pull complete Digest: sha256:dfd64a3b4296d8c9b62aa3309984f8620b98d87e47492599ee20739e8eb54fbf Status: Downloaded newer image for ubuntu:latest docker.io/library/ubuntu:latest $
Similarly you could pull the centos image
sudo docker pull centos
$ sudo docker pull centos Using default tag: latest latest: Pulling from library/centos a1d0c7532777: Pull complete Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177 Status: Downloaded newer image for centos:latest docker.io/library/centos:latest $
Note that even if your host OS is Ubuntu, you can pull and launch a centos or alpine based container, since the linux kernel is the same.
The images that you just downloaded came from the Docker Hub which acts as the repository of all docker images, both official and user published. Its located here: https://hub.docker.com/search
List available images on the system
Now that we have pulled in a few docker images, lets list them to ensure that they are available on the system.
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest 9c7a54a9a43c 3 weeks ago 13.3kB ubuntu latest 3b418d7b466a 4 weeks ago 77.8MB $
The above command simply shows you what images you have on your system that can be used to launch a container.
Launch a container
Now its finally time to launch our first container. Lets launch a ubuntu container
$ sudo docker run -d -t --name myubuntucontaner ubuntu f5d8771b5423e774d7fda9c451e4b90e12d43f9ec1fcac2aeddf4cc70119a9a1 $
The options are as follows:
- -d: detch the container process from the terminal. Run container in background and print container ID
- -t: Allocate a pseudo-TTY so that we can connect to it via a bash command terminal
- --name: give a unique name to this container. Here its myubuntucontaner
If you do not provide a name, it will automatically generate a unique random (but human readable name) for the new container. Look at the example below where the ubuntu container gets a unique name
$ sudo docker run -td ubuntu 5a8ac204e0020e000ac9047081946619656bf8565c160163843e1feb6be7c6f8 $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5a8ac204e002 ubuntu "/bin/bash" 3 seconds ago Up 2 seconds gracious_mahavira bab84b1ee5df nginx:latest "/docker-entrypoint.…" 3 hours ago Up 3 hours 0.0.0.0:8081->80/tcp, :::8081->80/tcp nginx-1 $
Get a shell right away: If you use the "-i" option instead of the "-d" option, you can get an interactive shell right away:
$ sudo docker run -ti ubuntu [sudo] password for silver: root@08a4989771e3:/#
Now you can run commands inside the container.
List the running containers
The following command can be run on the HOST system to list out all the containers that are running.
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f5d8771b5423 ubuntu "/bin/bash" 2 minutes ago Up 2 minutes myubuntucontaner $
This lets us monitor the running containers and how long each has been running for, along with ports and commands be run on each.
Get a bash shell in the container
The following command will bring up a interactive bash shell inside the container allowing you to run commands and get the output as any normal command shell.
If you launched the container with the "-d" switch and sent it to background, you can use this command to get back into it with an interactive shell.
$ sudo docker exec -it myubuntucontaner bash root@f5d8771b5423:/# root@f5d8771b5423:/#
Now you can run commands in the container
root@f5d8771b5423:/# ls bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var root@f5d8771b5423:/#
You can even install packages inside the ubuntu container using apt command for example.
To exit from the container bash, type exit and hit enter.
Update sytem and check distro version
apt update
apt install -y lsb-release
root@1ab6588117e8:/# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04 LTS
Release: 24.04
Codename: noble
root@1ab6588117e8:/#
At the time of writing, 24.04 is the latest ubuntu version
Monitoring commands
apt install htop
htop
Install nano
By default nano text editor is not available
apt install nano
Run networking commands
Here we shall install the networking commands and see the network setup. We need a couple of commands like ifconfig, netstat, ping and ip. These will allow us to check the network setup and run ping tests.
apt install net-tools
ifconfig
root@1ab6588117e8:/# ifconfig
eth0: flags=4163
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 5936 bytes 25049832 (25.0 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2839 bytes 212480 (212.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@1ab6588117e8:/#
netstat command is also available now:
root@1ab6588117e8:/# netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 1ab6588117e8:42796 ubuntu-mirror-1.ps5.:80 TIME_WAIT
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags Type State I-Node Path
root@1ab6588117e8:/#
apt update netstat apt-get install -y iputils-ping ping [term] apt install iproute2 ip addr
root@1ab6588117e8:/# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 5: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever root@1ab6588117e8:/#
As can be seen, this ubuntu container has an ethernet interface with ip address 172.17.0.3/16 and it can connect to the internet very fine which can be verified with the ping command.
The default route is 172.17.0.1 as we can see. This particular ip address device exists on the host os as we can see in the next command output.
root@1ab6588117e8:/# ip route default via 172.17.0.1 dev eth0 172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2 root@1ab6588117e8:/#
On the host os if you run ifconfig we can see an interface named docker0
$ ifconfig docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:8bff:fec2:6ae3 prefixlen 64 scopeid 0x20<link> ether 02:42:8b:c2:6a:e3 txqueuelen 0 (Ethernet) RX packets 5960 bytes 323637 (323.6 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 6412 bytes 42257253 (42.2 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ... veth306943c: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::3874:83ff:fe0c:a5c7 prefixlen 64 scopeid 0x20<link> ether 3a:74:83:0c:a5:c7 txqueuelen 0 (Ethernet) RX packets 18 bytes 3098 (3.0 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 72 bytes 8121 (8.1 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vethd8a505c: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::2008:70ff:febb:fb56 prefixlen 64 scopeid 0x20<link> ether 22:08:70:bb:fb:56 txqueuelen 0 (Ethernet) RX packets 5942 bytes 403979 (403.9 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 6411 bytes 42256890 (42.2 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ...
Besides docker0, the other 2 vethxxxxxx devices you see are bridge devices one for each container. These devices connect the container with the docker0 device over bridge allowing them to connect to the internet via the host machine where docker0 interface exists.
We can verify the bridge link using the command:
$ bridge link 12: veth306943c@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master docker0 state forwarding priority 32 cost 2 14: vethd8a505c@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master docker0 state forwarding priority 32 cost 2 $
On the host os, you can list the networks created by docker using the following command:
$ sudo docker network ls NETWORK ID NAME DRIVER SCOPE 4d50b8ec4750 bridge bridge local 9dd5a5f28a9e host host local 2a0298db1223 none null local $
Ping Host to container: The host can ping the container like this:
$ ping 172.17.0.3 PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data. 64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.051 ms 64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.068 ms 64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.089 ms 64 bytes from 172.17.0.3: icmp_seq=4 ttl=64 time=0.070 ms ...
Ping Container to Host: The container can ping the host as well
root@5a8ac204e002:/# ping 192.168.1.115 PING 192.168.1.115 (192.168.1.115) 56(84) bytes of data. 64 bytes from 192.168.1.115: icmp_seq=1 ttl=64 time=0.076 ms 64 bytes from 192.168.1.115: icmp_seq=2 ttl=64 time=0.047 ms 64 bytes from 192.168.1.115: icmp_seq=3 ttl=64 time=0.054 ms 64 bytes from 192.168.1.115: icmp_seq=4 ttl=64 time=0.076 ms ...
Networking inside docker itself is an extensive subject that we shall be covering in other articles.
Stopping a container
To stop a container simply use the stop command.
$ sudo docker stop myubuntucontaner
After stopping a container can again be started using the run command.
Removing an Image
This will completely remove the container image. Without the image you cannot launch the container. You would need to download the image again.
$ sudo docker rmi centos Untagged: centos:latest Untagged: centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177 Deleted: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6 Deleted: sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59 silver@silver-VirtualBox:~$
Launching Nginx Container
This super simple command would launch an nginx container running the nginx web server. Note that we do not specify a name for the container so it would choose a unique random name on its own.
$ sudo docker run -td -p 8080:80 nginx 718912f9e15b84d2ca0aba516a3abf223ca6da1d870cba86d94859d50abb4274 $
The new option used here is the -p (ports option) which maps ports from the host system to the container system. The format is as follows:
-p HOST_PORT:CONTAINER_PORT
So in the above example, nginx is running inside the container on port 80 and that port is mapped with the port 8080 on our host ubuntu system.
We can check port mapping and commands using the docker ps command as well:
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 718912f9e15b nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp sleepy_burnell 5a8ac204e002 ubuntu "/bin/bash" 22 hours ago Up 22 hours gracious_mahavira $
Note the column for PORTS which shows how the host ip:port has been mapped to container port.
Note that container has been launched using the nginx image. I am wondering what distro is this image based on. Lets connect to the bash terminal and find out.
$ sudo docker exec -it sleepy_burnell bash root@718912f9e15b:/#
root@718912f9e15b:/# cat /etc/os* PRETTY_NAME="Debian GNU/Linux 11 (bullseye)" NAME="Debian GNU/Linux" VERSION_ID="11" VERSION="11 (bullseye)" VERSION_CODENAME=bullseye ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" root@718912f9e15b:/#
So its a Debian 11 system!
Docker daemon log files
Docker does not log its messages to a separate log file.
The docker daemon log files can be checked using the journalctl command:
journalctl -xu docker.service journalctl -u docker.service
$ journalctl -u docker.service May 28 11:10:42 silver-VirtualBox systemd[1]: Starting Docker Application Container Engine... May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.364904538+05:30" level=info msg="Starting up" May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.366032414+05:30" level=info msg="detected 127.0.0.53 nameserver, assuming systemd-resolved, so using resolv.conf: /run/systemd/resolve/resolv.conf" May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.448904812+05:30" level=info msg="parsed scheme: \"unix\"" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.448946385+05:30" level=info msg="scheme \"unix\" not registered, fallback to default scheme" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.448968128+05:30" level=info msg="ccResolverWrapper: sending update to cc: {[{unix:///run/containerd/containerd.sock <nil> 0 <nil>}] <nil> <nil>}" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.448979270+05:30" level=info msg="ClientConn switching balancer to \"pick_first\"" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.459789377+05:30" level=info msg="parsed scheme: \"unix\"" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.460045832+05:30" level=info msg="scheme \"unix\" not registered, fallback to default scheme" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.460177903+05:30" level=info msg="ccResolverWrapper: sending update to cc: {[{unix:///run/containerd/containerd.sock <nil> 0 <nil>}] <nil> <nil>}" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.460293477+05:30" level=info msg="ClientConn switching balancer to \"pick_first\"" module=grpc May 28 11:10:42 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:42.955597019+05:30" level=info msg="Loading containers: start." May 28 11:10:43 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:43.204875582+05:30" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP ad> May 28 11:10:43 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:43.414958523+05:30" level=info msg="Loading containers: done." May 28 11:10:43 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:43.542507320+05:30" level=info msg="Docker daemon" commit="20.10.21-0ubuntu1~22.10.2" graphdriver(s)=overlay2 version=20.10.21 May 28 11:10:43 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:43.542620544+05:30" level=info msg="Daemon has completed initialization" May 28 11:10:43 silver-VirtualBox systemd[1]: Started Docker Application Container Engine. May 28 11:10:43 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:10:43.655478370+05:30" level=info msg="API listen on /run/docker.sock" May 28 11:14:52 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:14:52.551384711+05:30" level=info msg="ignoring event" container=bbe8989d1a2f8b0b628a7af12cef461784545f9b60f8ed728a11e16037a1c373 module=libcontainerd namespace=moby > May 28 11:16:05 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:16:05.546926568+05:30" level=info msg="ignoring event" container=45af694c845ed2af2885820c94d27a2219e6e8ca219132178105bbe69431db6b module=libcontainerd namespace=moby > May 28 11:50:24 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:50:24.394729059+05:30" level=info msg="Container failed to exit within 10s of signal 15 - using the force" container=f5d8771b5423e774d7fda9c451e4b90e12d43f9ec1fcac2ae> May 28 11:50:24 silver-VirtualBox dockerd[8052]: time="2023-05-28T11:50:24.472630260+05:30" level=info msg="ignoring event" container=f5d8771b5423e774d7fda9c451e4b90e12d43f9ec1fcac2aeddf4cc70119a9a1 module=libcontainerd namespace=moby > May 29 10:50:31 silver-VirtualBox dockerd[8052]: time="2023-05-29T10:50:31.993334420+05:30" level=error msg="Error setting up exec command in container myubuntucontaner: Container f5d8771b5423e774d7fda9c451e4b90e12d43f9ec1fcac2aeddf4cc> ...
For live monitoring most recent entries:
journalctl -f -u docker.service
The above command should work all recent versions of Fedora, CentOS and OpenSUSE using systemd.
Some Questions
How does Docker handle kernel version mismatch ?
Just like me you might be wondering, what would happen if you try to run a container with applications that need latest kernel on a host system running on an older kernel. Well in theory and most of the time practise, it will fail.
Docker is merely process isolation, but does not emulate anything like virtualisation. If a container has applications that depend on specific new kernel features then the user must ensure to run the container on a host os with those kernel features available.
It would be wrong to assume that just because the docker daemon is running on a older system, it can run any docker image even if the image relies on newer kernels
Conclusion
Docker is a powerful modern "containerization" tool used widely in all kind of deployments. It is not at all difficult to learn, but there is certainly a learning curve that you can climb up quickly.
The above article just showed basic commands to give you an introduction of how the basic docker commands work, so that you can play with it a little bit on your machine.
To test docker you do not need any online server. You can just do it on your desktop machine with some linux distro installed.
To actually put docker to practical use we need to do more things like Dockerfiles, Docker Compose and network configuration. We shall be covering this in other articles.