Docker Made Easy

I don’t often cover Docker on the channel. However, lately I have had some requests to define the basics behind the use of Docker. Docker is application virtualization. LXD which I often discuss is Operating System (OS) and userspace application virtualization. Virtual Machines virtualize the hardware, the OS, and the application. Docker is easy to use once you know the basics.

To install Docker on Ubuntu, I recommend:

curl -sSL https://get.docker.com | sh

Docker can also be installed on Ubuntu via a Snap file which I do not recommend for configuration reasons:

sudo snap install docker

To install docker-compose:

sudo apt install docker-compose

To allow use of Docker commands without sudo:

sudo usermod -aG docker $USER
newgrp docker
groups

In the video we cover Stacks – Containers – Images – Volumes – networks

Docker Stacks are used in docker clusters aka docker swarms.
Containers are the docker applications that are executed from docker images.
Images are downloaded aka “pulled” from a docker hub.
Volumes are the non-volatile persistent storage containers or folder mappings for docker containers.
Docker containers do not store persistent data without volumes between runs.
Docker Networks are how docker containers communication with other docker containers and external users.

The simplest way to run a docker container is “docker run”:

docker run --env-file .env -d -p 22300:22300 joplin/server:latest 

Docker containers that are running can be seen with:

docker ps

All docker containers, running or not can be listed:

docker ps -a

Docker containers can be stopped:

docker stop {container-id}

Containers can be deleted (they must be stopped first):

docker rm {container-id}

Containers that are stopped can be started:

docker start {container-id}

Docker-compose is the advised way to run docker apps. One advantage docker-compose has is being able to run multiple containers with a single command.

In the video, I used an example for the Joplin Notes server with a postgres database. Edit and create a docker-compose.yaml file:

nano docker-compose.yaml

Put the following contents in the file making adjustments for your needs:

version: '3'

services:
    db:
        image: postgres:15
        volumes:
            - ./data/postgres:/var/lib/postgresql/data
        ports:
            - "5432:5432"
        restart: unless-stopped
        environment:
            - POSTGRES_PASSWORD=AbCD12345
            - POSTGRES_USER=JoplinUser
            - POSTGRES_DB=JoplinDB
    app:
        image: joplin/server:latest
        depends_on:
            - db
        ports:
            - "22300:22300"
        restart: unless-stopped
        environment:
            - APP_PORT=22300
            - APP_BASE_URL=https://testing.scottibyte.com
            - DB_CLIENT=pg
            - POSTGRES_PASSWORD=AbCD12345
            - POSTGRES_DATABASE=JoplinDB
            - POSTGRES_USER=JoplinUser
            - POSTGRES_HOST=db
            - MAX_TIME_DRIFT=0
            - MAILER_ENABLED=1
            - MAILER_HOST=smtp.gmail.com
            - MAILER_PORT=587
            - MAILER_SECURITY=starttls
            - MAILER_SECURE=1
            - MAILER_AUTH_USER=vmsman@gmail.com
            - MAILER_AUTH_PASSWORD=password
            - MAILER_NOREPLY_NAME=JoplinServer
            - MAILER_NOREPLY_EMAIL=noreply@scottibyte.com

To execute a docker-compose file:

docker-compose up -d

To stop the containers in the docker compose and delete them, which does not delete the images or the persistent data in your volume mappings:

docker-compose down

After you have run and updated a docker container for a long time, old stale leftover images may be using up space on your server. If you have your current apps up and running, you can delete all orphaned images with the following command. Images in use by current running containers will not be deleted and fail with an error:

docker rmi $(docker images -q)

To create a Docker Swarm, aka cluster use the following with the appropriate interface address:

docker swarm init --advertise-addr 172.16.1.148

The init command above creates a swarm management node and also makes that node a worker node. Tha command lists the necessary command to add worker nodes to your cluster as seen in the video.

You can use the same docker-compose.yaml to deploy an application stack to your swarm.

docker stack deploy -c docker-compose.yaml Joplin

The name “Joplin” above is the name of the Stack being deployed in the swarm/cluster. A docker application node is either a standalone node with the use of “docker run” or “docker-compose” or it is defined as a swarm/cluster with “docker stack deploy”.

To view your stacks and services in a swarm:

docker stack ls
docker stack services Joplin

This is simply meant as a basic intro to Docker and Docker swarms. There is a lot more to learn.