Installing Docker on Ubuntu 20.04

Ok, so, this is gonna be short and simple...for the most part .😅
We will be setting up Docker Engine on Ubuntu 20.04 as a systemd service.

First, Older versions of Docker were called docker, docker.io, or docker-engine
If you have any of those installed, first remove them.

sudo apt-get remove docker docker-engine docker.io containerd runc

The contents of /var/lib/docker/, including images, containers, volumes, and networks, will be preserved from your previous installation.
If you want a clean start, do this

 sudo rm -rf /var/lib/docker
 sudo rm -rf /var/lib/containerd

WARNING, this will remove your docker volumes, images, and data

Setup Repository

  1. Update apt and required packages
sudo apt-get update
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

2. Add Docker's official GPG key

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

3. Setup Docker's stable repository

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Install Docker Engine

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Since we installed via the apt package manager, updating is as simple as

sudo apt-get update

Now, Docker is installed and set up as a systemd service named docker.service, and its service file is stored in /lib/systemd/system/docker.service
You can check its status with

sudo systemctl status docker

You can verify by running a test container,

docker run hello-world

This will print a test message then exit.

You can also start, stop, restart, disable or enable docker daemon by running

sudo systemctl start docker
sudo systemctl stop docker
sudo systemctl restart docker
sudo systemctl disable docker
sudo systemctl enable docker

To list running container

docker container ls

To list all containers (start and stopped)

docker container ls -a

To create or create and run a container

docker create --name containername imageurl
docker run --name containername imageurl

Refer to here for more detailed instructions
https://docs.docker.com/engine/reference/commandline/create/

To pull a new docker image

docker pull imageurl

To start, stop, or restart a container

docker start containername
docker stop containername
docker restart containername

To update a container

docker stop containername
docker rm containername
docker pull imageurl
docker run --name containername imageurl

Remember to use the same run/create command you used previously to run/create the container. It's handy to keep all your docker run commands in a text file somewhere.

Docker daemon also has a neat feature of restarting docker daemon without stopping any of your containers, in case you want to update docker daemon or something.

Edit your /etc/docker/daemon.json file

sudo nano /etc/docker/daemon.json

and add this

{
  "live-restore": true
}

then press ctrl+x then Y and Enter to save.

Restart Policies

Docker has something called restart policies to manage the automatic start and stop of your container. Following restart policies are available,

  1. no : Do not automatically restart the container. (the default)
  2. on-failure : Restart the container if it exits due to an error, which manifests as a non-zero exit code.
  3. always : Always restart the container if it stops. If it is manually stopped, it is restarted only when Docker daemon restarts or the container itself is manually restarted. (See the second bullet listed in restart policy details)
  4. unless-stopped : Similar to always, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker daemon restarts.

You can set any of them via the --restart flag while creating a container.

Managing Docker Containers via Systemd

Although it is recommended to use restart policies to manage containers, I'm gonna show you how to manage them via systemd service of your host ubuntu.
Suppose you want to start or stop containers based on some system events, like after you have successfully run a system check on boot, or after you have your external storage device plugged in and ready to be mounted inside your containers.

Remember, if you want to manage docker containers via systemd, put --restart no flag in your container.

Simply, create a containername.service file in /etc/systemd/system directory, and add the following

[Unit]
Description=Docker Conatiner name
After=network-online.target docker.service
Requires=docker.service
StartLimitIntervalSec=10
StartLimitBurst=5

[Service]
Type=simple
ExecStart=/usr/bin/docker start -a containername
ExecStop=/usr/bin/docker stop containername
Restart=always
RestartSec=10s

[Install]
WantedBy=docker.service

Then reload systemctl, start and enable your service

sudo systemctl daemon-reload
sudo systemctl start containername
sudo systemctl enable coontainername

This will start your container after you have network connectivity and your docker daemon is ready. Also, in case your container stops due to some reason, it will automatically restart them, and keep restarting (you can remove Restart=always to disable that) at a 10 seconds interval (you can adjust it with RestartSec=10s value) whenever it stops.

The After= specifies the service after which this service will run.
The Requires= specifies the dependant service, without which this service won't start. (it's more or less the same as after but both are required in this case)
The WantedBy= puts your service in the specifiedservice.service.wants folder. So basically, whenever the specified service runs, this service will be started too.

If you want your container service to start only and only after your foo.service has started, you would put only foo.service in all three after, requires, and wantedby.

To view container status via systemd

sudo systemctl status containername

To view full logs via systemd

sudo journalctl -f -u containername

or via docker daemon

docker logs containername

Refer to systemd man page for more info.
https://www.freedesktop.org/software/systemd/man/systemd.unit.html

Uninstall Docker Engine

Like most things in life, removing is as simple as

  1. Remove packages
sudo apt-get purge docker-ce docker-ce-cli containerd.io

2. Remove images, containers & volumes

sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

WARNING, this will remove your docker volumes, images, and data

Wasn't that quick 🤣