Introduction
This guide covers the installation of Docker on Debian 12 Bookworm using the 5W1H (What, Who, Where, When, Why, How) approach. We'll discuss the consequences and conclude with a summary.
Overview
What
Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly.
Who
This guide is intended for developers, system administrators, and IT professionals who want to install and use Docker on Debian 12 Bookworm.
Where
You can install Docker on any machine running Debian 12 Bookworm, whether it's a physical machine or a virtual machine.
When
Install Docker when you need to create, deploy, and run applications inside containers for development, testing, or production environments.
Why
Using Docker on Debian 12 Bookworm has several pros and cons:
Pros | Cons |
---|---|
|
|
How
Follow these steps to install Docker on Debian 12 Bookworm:
Step 1 | Update your system. |
Step 2 | Install necessary packages. |
Step 3 | Add Docker’s official GPG key. |
Step 4 | Add Docker's APT repository. |
Step 5 | Install Docker. |
Step 6 | Start and enable Docker. |
Step 7 | Verify Docker installation. |
Consequences
Installing and using Docker on Debian 12 Bookworm can have several consequences:
Positive |
|
Negative |
|
Conclusion
Docker is a powerful tool for creating, deploying, and running applications inside containers on Debian 12 Bookworm. Despite some challenges, its benefits in streamlining development and deployment processes make it an essential tool for modern software development.
Install Docker
Install Docker which is the Operating System-Level Virtualization Tool, which automates the deployment of applications inside Containers.
Step [1]Install Docker.
root@bizantum:~# apt -y install docker.io
root@bizantum:~# docker version
Client:
Version: 20.10.24+dfsg1
API version: 1.41
Go version: go1.19.8
Git commit: 297e128
Built: Thu May 18 08:38:34 2023
OS/Arch: linux/amd64
Context: default
Experimental: true
Server:
Engine:
Version: 20.10.24+dfsg1
API version: 1.41 (minimum version 1.12)
Go version: go1.19.8
Git commit: 5d6db84
Built: Thu May 18 08:38:34 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.20~ds1
GitCommit: 1.6.20~ds1-1+b1
runc:
Version: 1.1.5+ds1
GitCommit: 1.1.5+ds1-1+b1
docker-init:
Version: 0.19.0
GitCommit:
Step [2]Download an official image and create a Container and output the words [Welcome to the Docker World] inside the Container.
# download the image
root@bizantum:~# docker pull debian
Using default tag: latest
latest: Pulling from library/debian
bba7bb10d5ba: Pull complete
Digest: sha256:d568e251e460295a8743e9d5ef7de673c5a8f9027db11f4e666e96fb5bed708e
Status: Downloaded newer image for debian:latest
docker.io/library/debian:latest
# run echo inside Container
root@bizantum:~# docker run debian /bin/echo "Welcome to the Docker World!"
Welcome to the Docker World!
Step [3]Connect to the interactive session of a Container with [i] and [t] option like follows. If exit from the Container session, the process of a Container finishes.
root@bizantum:~# docker run -it debian /bin/bash
root@6ad840b78fba:/# # Container's console
root@6ad840b78fba:/# uname -a
Linux 6ad840b78fba 6.1.0-9-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.27-1 (2023-05-08) x86_64 GNU/Linux
root@6ad840b78fba:/# exit
exit
root@bizantum:~# # come back
Step [4]If exit from the Container session with keeping container's process, push [Ctrl+p] and [Ctrl+q] key.
root@bizantum:~# docker run -it debian /bin/bash
root@072c016558ac:/# root@bizantum:~# # Ctrl+p, Ctrl+q
# show docker process
root@bizantum:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
072c016558ac debian "/bin/bash" 25 seconds ago Up 24 seconds gracious_kirch
# connect to container's session
root@bizantum:~# docker attach 072c016558ac
root@072c016558ac:/#
# shutdown container's process from Host's console
root@bizantum:~# docker kill 072c016558ac
072c016558ac
root@bizantum:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Add Container images
Add Container images you created.
Step [1]For example, update official image with installing Nginx and add it as a new image for container. The container is generated every time for executing docker run command, so add the latest executed container like follows.
# show images
root@bizantum:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
debian latest 49081a1edb0b 9 days ago 116MB
# start a Container and install nginx
root@bizantum:~# docker run debian /bin/bash -c "apt-get update; apt-get -y install nginx"
root@bizantum:~# docker ps -a | head -2
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22d1b1ecdd1b debian "/bin/bash -c 'apt-g…" 13 seconds ago Exited (0) 1 second ago sharp_wilbur
# add the image
root@bizantum:~# docker commit 22d1b1ecdd1b bizantum.lab/debian-nginx
sha256:5a202ab0ab76404d7a13a6c18980a79d9a6fcfd7ece88b393f1d44835f1c0c81
root@bizantum:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bizantum.lab/debian-nginx latest 5a202ab0ab76 12 seconds ago 153MB
debian latest 49081a1edb0b 9 days ago 116MB
# generate a container from the new image and execute [which] to make sure nginx exists
root@bizantum:~# docker run bizantum.lab/debian-nginx /usr/bin/which nginx
/usr/sbin/nginx
Access to Container Services
If you'd like to access to services like HTTP or SSH which is running in Containers as a daemon, Configure like follows.
Step [1]For example, Use a Container image which has Nginx.
# start a Container and also run Nginx
# map the port of Host and the port of Container with [-p xxx:xxx]
root@bizantum:~# docker run -t -d -p 8081:80 bizantum.lab/debian-nginx /usr/sbin/nginx -g "daemon off;"
666ef1b1b23a3ce4a7c50fb9d558fc96d44bd9ccd333e69edda5277bd7837fc5
root@bizantum:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
666ef1b1b23a bizantum.lab/debian-nginx "/usr/sbin/nginx -g …" 14 seconds ago Up 14 seconds 0.0.0.0:8081->80/tcp, :::8081->80/tcp happy_chaum
# create a test page
root@bizantum:~# docker exec 666ef1b1b23a /bin/bash -c 'echo "Nginx on Docker Container" > /var/www/html/index.html'
# verify it works normally
root@bizantum:~# curl localhost:8081
Nginx on Docker Container
Use Dockerfile
Use Dockerfile and create Docker images automatically. It is also useful for configuration management.
Step [1]For example, Create a Dockerfile that Apache2 is installed and started.
root@bizantum:~# vi Dockerfile
# create new
FROM debian
MAINTAINER Bizantum <admin@bizantum.lab>
RUN apt-get update
RUN apt-get -y install tzdata
RUN apt-get -y install apache2
RUN echo "Dockerfile Test on Apache2" > /var/www/html/index.html
EXPOSE 80
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
# build image ⇒ docker build -t [image name]:[tag] .
root@bizantum:~# docker build -t bizantum.lab/debian-apache2:latest ./
Sending build context to Docker daemon 18.43kB
Step 1/8 : FROM debian
---> 49081a1edb0b
Step 2/8 : MAINTAINER Bizantum <admin@bizantum.lab>
---> Running in 96b14acc8751
Removing intermediate container 96b14acc8751
---> 8c66e9445174
Step 3/8 : RUN apt-get update
.....
.....
Removing intermediate container 80ec238dedae
---> 431c51e7819a
Successfully built 431c51e7819a
Successfully tagged bizantum.lab/debian-apache2:latest
root@bizantum:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bizantum.lab/debian-apache2 latest 431c51e7819a About a minute ago 252MB
bizantum.lab/debian-nginx latest 5a202ab0ab76 6 minutes ago 153MB
debian latest 49081a1edb0b 9 days ago 116MB
# run container
root@bizantum:~# docker run -d -p 8081:80 bizantum.lab/debian-apache2
bc96f9eae7cf186114e33599f1c95704b9545faa36d22ae4743864f97432014b
root@bizantum:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc96f9eae7cf bizantum.lab/debian-apache2 "/usr/sbin/apachectl…" 10 seconds ago Up 9 seconds 0.0.0.0:8081->80/tcp, :::8081->80/tcp hungry_mahavira
# verify accesses
root@bizantum:~# curl localhost:8081
Dockerfile Test on Apache2
The format of Dockerfile is [INSTRUCTION arguments] . Refer to the following description for INSTRUCTION.
Instruction | Description |
---|---|
FROM | It sets the Base Image for subsequent instructions. |
MAINTAINER | It sets the Author field of the generated images. |
RUN | It will execute any commands when Docker image will be created. |
CMD | It will execute any commands when Docker container will be executed |
ENTRYPOINT | It will execute any commands when Docker container will be executed. |
LABEL | It adds metadata to an image. |
EXPOSE | It informs Docker that the container will listen on the specified network ports at runtime. |
ENV | It sets the environment variable. |
ADD | It copies new files, directories or remote file URLs. |
COPY | It copies new files or directories. The differences of [ADD] are that it's impossible to specify remote URL and also it will not extract archive files automatically. |
VOLUME | It creates a mount point with the specified name and marks it as holding externally mounted volumes from native host or other containers. |
USER | It sets the user name or UID. |
WORKDIR | It sets the working directory. |
Use External Storage
When containers are removed, data in them are also lost, so it's necessary to use external filesystem in containers as persistent storages if you need.
Step [1]It's possible to mount a directory on Docker Host into containers.
# create a directory for containers data
root@bizantum:~# mkdir -p /var/lib/docker/disk01
root@bizantum:~# echo "persistent storage" >> /var/lib/docker/disk01/testfile.txt
# run a container with mounting the directory above on [/mnt]
root@bizantum:~# docker run -it -v /var/lib/docker/disk01:/mnt debian /bin/bash
root@55c3e6fe614d:/# df -hT
Filesystem Type Size Used Avail Use% Mounted on
overlay overlay 77G 2.0G 71G 3% /
tmpfs tmpfs 64M 0 64M 0% /dev
shm tmpfs 64M 0 64M 0% /dev/shm
/dev/mapper/debian--vg-root ext4 77G 2.0G 71G 3% /mnt
tmpfs tmpfs 7.9G 0 7.9G 0% /proc/acpi
tmpfs tmpfs 7.9G 0 7.9G 0% /sys/firmware
root@55c3e6fe614d:/# cat /mnt/testfile.txt
persistent storage
Step [2]It's also possible to configure external storage by Docker Data Volume command.
# create [volume01] volume
root@bizantum:~# docker volume create volume01
volume01
# display volume list
root@bizantum:~# docker volume ls
DRIVER VOLUME NAME
local volume01
# display details of [volume01]
root@bizantum:~# docker volume inspect volume01
[
{
"CreatedAt": "2023-06-22T02:22:59-05:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/volume01/_data",
"Name": "volume01",
"Options": {},
"Scope": "local"
}
]
# run a container with mounting [volume01] to [/mnt] on container
root@bizantum:~# docker run -it -v volume01:/mnt debian
root@9f61dffe1e07:/# df -hT /mnt
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/debian--vg-root ext4 77G 2.0G 71G 3% /mnt
root@9f61dffe1e07:/# echo "Docker Volume test" > /mnt/testfile.txt
root@9f61dffe1e07:/# exit
root@bizantum:~# cat /var/lib/docker/volumes/volume01/_data/testfile.txt
Docker Volume test
# possible to mount from other containers
root@bizantum:~# docker run -v volume01:/var/volume01 debian /usr/bin/cat /var/volume01/testfile.txt
Docker Volume test
# to remove volumes, do like follows
root@bizantum:~# docker volume rm volume01
Error response from daemon: remove volume01: volume is in use - [9f61dffe1e079b99c6d01a2e723b06acb44deff300be05fb900c08afe0bfd0b8, 23b8a81a4d8baaa294d1bf99529a6eecfb80265a68d1326dc8dc0c55107ec4b9]
# if some containers are using the volume you'd like to remove like above,
# it needs to remove target containers before removing a volume
root@bizantum:~# docker rm 9f61dffe1e079b99c6d01a2e723b06acb44deff300be05fb900c08afe0bfd0b8
root@bizantum:~# docker rm 23b8a81a4d8baaa294d1bf99529a6eecfb80265a68d1326dc8dc0c55107ec4b9
root@bizantum:~# docker volume rm volume01
volume01
Use External Storage (NFS)
This is an example to use NFS External Storage.
Step [1] NFS server is required to be running on your LAN, refer to here. On this example, configure [/home/nfsshare] directory on [nfs.bizantum.lab] as a shared directory.
Step [2]Create a volume for NFS and use it.
# create [nfs-volume] volume
root@bizantum:~# docker volume create \
--opt type=nfs \
--opt o=addr=10.0.0.35,rw,nfsvers=4 \
--opt device=:/home/nfsshare nfs-volume
nfs-volume
# display volume list
root@bizantum:~# docker volume ls
DRIVER VOLUME NAME
local nfs-volume
# display details of [nfs-volume]
root@bizantum:~# docker volume inspect nfs-volume
[
{
"CreatedAt": "2023-06-22T02:27:22-05:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nfs-volume/_data",
"Name": "nfs-volume",
"Options": {
"device": ":/home/nfsshare",
"o": "addr=10.0.0.35,rw,nfsvers=4",
"type": "nfs"
},
"Scope": "local"
}
]
# run container with mounting [nfs-volume] to [/nfsshare] on container
root@bizantum:~# docker run -it -v nfs-volume:/nfsshare debian
root@7a09e30a9c8d:/# df -hT /nfsshare
Filesystem Type Size Used Avail Use% Mounted on
:/home/nfsshare nfs4 28G 1.3G 26G 5% /nfsshare
# verify reading and writing
root@7a09e30a9c8d:/# echo "NFS Volume Test" > /nfsshare/testfile.txt
root@7a09e30a9c8d:/# cat /nfsshare/testfile.txt
NFS Volume Test
Use Docker Compose
To Install Docker Compose, it's easy to configure and run multiple containers as a Docker application.
Step [1]Install Docker Compose.
root@bizantum:~# apt -y install docker-compose
Step [2]For example, Configure an application that has Web and DB services with Docker Compose.
# define Web service container
root@bizantum:~# vi Dockerfile
FROM debian
MAINTAINER Bizantum <admin@bizantum.lab>
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get -y install tzdata
RUN apt-get -y install apache2
EXPOSE 80
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
# define application configuration
root@bizantum:~# vi docker-compose.yml
version: '3'
services:
db:
image: mariadb
volumes:
- /var/lib/docker/disk01:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: debian
MYSQL_PASSWORD: password
MYSQL_DATABASE: debian_db
ports:
- "3306:3306"
web:
build: .
ports:
- "80:80"
volumes:
- /var/lib/docker/disk02:/var/www/html
# build and run
root@bizantum:~# docker-compose up -d
Building web
Sending build context to Docker daemon 18.43kB
Step 1/8 : FROM debian
---> 49081a1edb0b
Step 2/8 : MAINTAINER Bizantum <admin@bizantum.lab>
---> Using cache
---> 8c66e9445174
Step 3/8 : ENV DEBIAN_FRONTEND=noninteractive
.....
.....
Creating root_db_1 ... done
Creating root_web_1 ... done
root@bizantum:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4cc26d0b967b mariadb "docker-entrypoint.s…" 54 seconds ago Up 53 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp root_db_1
2eb596d5bdf9 root_web "/usr/sbin/apachectl…" 54 seconds ago Up 53 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp root_web_1
# verify accesses
root@bizantum:~# mysql -h 127.0.0.1 -u root -p -e "show variables like 'hostname';"
Enter password:
+---------------+--------------+
| Variable_name | Value |
+---------------+--------------+
| hostname | 4cc26d0b967b |
+---------------+--------------+
root@bizantum:~# mysql -h 127.0.0.1 -u debian -p -e "show databases;"
Enter password:
+--------------------+
| Database |
+--------------------+
| debian_db |
| information_schema |
+--------------------+
root@bizantum:~# echo "Hello Docker Compose World" > /var/lib/docker/disk02/index.html
root@bizantum:~# curl 127.0.0.1
Hello Docker Compose World
Step [3]Other basic operations of Docker Compose are follows.
# verify state of containers
root@bizantum:~# docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------
root_db_1 docker-entrypoint.sh Up 0.0.0.0:3306->3306/tcp,:::3306->3306/tcp
root_web_1 /usr/sbin/apachectl -D FOR Up 0.0.0.0:80->80/tcp,:::80->80/tcp
# show logs of containers
root@bizantum:~# docker-compose logs
Attaching to root_db_1, root_web_1
db_1 | 2023-06-22 07:32:58+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.0.2+maria~ubu2204 started.
db_1 | 2023-06-22 07:32:58+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
db_1 | 2023-06-22 07:32:58+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.0.2+maria~ubu2204 started.
db_1 | 2023-06-22 07:32:58+00:00 [Note] [Entrypoint]: Initializing database files
.....
.....
db_1 | 2023-06-22 7:33:03 0 [Note] mariadbd: ready for connections.
db_1 | Version: '11.0.2-MariaDB-1:11.0.2+maria~ubu2204' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
web_1 | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.2. Set the 'ServerName' directive globally to suppress this message
# run any commands inside a container
# container name is just the one set in [docker-compose.yml]
root@bizantum:~# docker-compose exec db /bin/bash
root@4cc26d0b967b:/#
# stop application and also shutdown all containers
root@bizantum:~# docker-compose stop
Stopping root_db_1 ... done
Stopping root_web_1 ... done
# start a service alone in application
# if set dependency, other container starts
root@bizantum:~# docker-compose up -d web
Starting root_web_1 ... done
root@bizantum:~# docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------
root_db_1 docker-entrypoint.sh Exit 0
root_web_1 /usr/sbin/apachectl -D FOR Up 0.0.0.0:80->80/tcp,:::80->80/tcp
# remove all containers in application
# if a container is running, it won't be removed
root@bizantum:~# docker-compose rm
Going to remove root_db_1
Are you sure? [yN] y
Removing root_db_1 ... done
Use Registry
Install Docker-Registry to build Private Registry for Docker images.
Step [1]Install Registry.
root@bizantum:~# apt -y install docker-registry
Step [2] Configure Registry. This is the settings to use HTTP connection and no-authentication.
root@bizantum:~# vi /etc/docker/registry/config.yml
# comment out [auth] section like follows
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/docker-registry
delete:
enabled: true
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
#auth:
# htpasswd:
# realm: basic-realm
# path: /etc/docker/registry
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
root@bizantum:~# systemctl restart docker-registry
# verify possible to access from any clients
# for HTTP connection, it needs to add [insecure-registries] setting
root@bizantum:~# vi /etc/docker/daemon.json
# create new
# add hosts to allow HTTP connection
{
"insecure-registries":
[
"docker.internal:5000",
"dlp.bizantum.lab:5000"
]
}
root@bizantum:~# systemctl restart docker
# [push] from localhost
root@bizantum:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bizantum.lab/debian-apache2 latest b7891f747bd5 18 hours ago 227MB
bizantum.lab/debian-nginx latest 51f5190bb9d9 18 hours ago 170MB
debian latest 2dc39ba059dc 6 days ago 77.8MB
root@bizantum:~# docker tag debian dlp.bizantum.lab:5000/debian:my-registry
root@bizantum:~# docker push dlp.bizantum.lab:5000/debian:my-registry
root@bizantum:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bizantum.lab/debian-apache2 latest b7891f747bd5 18 hours ago 227MB
bizantum.lab/debian-nginx latest 51f5190bb9d9 18 hours ago 170MB
dlp.bizantum.lab:5000/debian my-registry 2dc39ba059dc 6 days ago 77.8MB
debian latest 2dc39ba059dc 6 days ago 77.8MB
# [pull] from another node
root@node01:~# docker pull dlp.bizantum.lab:5000/debian:my-registry
root@node01:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dlp.bizantum.lab:5000/debian my-registry 2dc39ba059dc 6 days ago 77.8MB
Step [3]To enable Basic authentication, Configure like follows.
root@bizantum:~# apt -y install apache2-utils
root@bizantum:~# vi /etc/docker/registry/config.yml
# uncomment [auth] section and specify passwd file
.....
.....
auth:
htpasswd:
realm: basic-realm
path: /etc/docker/registry/.htpasswd
.....
.....
root@bizantum:~# systemctl restart docker-registry
# add users
# add [-c] at initial file creation
root@bizantum:~# htpasswd -Bc /etc/docker/registry/.htpasswd debian
New password:
Re-type new password:
Adding password for user debian
# verify possible to access
# an error is shown if access with no-authentication
root@node01:~# docker pull dlp.bizantum.lab:5000/debian:my-registry
Error response from daemon: Head http://dlp.bizantum.lab:5000/v2/nginx/manifests/my-registry: no basic auth credentials
# authenticate by a user added with [htpasswd]
root@node01:~# docker login dlp.bizantum.lab:5000
Username: debian
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
root@node01:~# docker pull dlp.bizantum.lab:5000/debian:my-registry
root@node01:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dlp.bizantum.lab:5000/debian my-registry 2dc39ba059dc 6 days ago 77.8MB
Step [4] To access via HTTPS and use valid certificates like from Let's Encrypt and so on, Configure like follows. This example is based on the environment that certificates have been gotten under the [/etc/letsencrypt/live/dlp.bizantum.lab].
root@bizantum:~# mkdir /etc/docker/certs.d
root@bizantum:~# cp -p /etc/letsencrypt/live/dlp.bizantum.lab/{fullchain,privkey}.pem /etc/docker/certs.d/
root@bizantum:~# chown docker-registry /etc/docker/certs.d/{fullchain,privkey}.pem
root@bizantum:~# vi /etc/docker/registry/config.yml
# add [tls] section under the [http] section like follows
.....
.....
http:
addr: :5000
tls:
certificate: /etc/docker/certs.d/fullchain.pem
key: /etc/docker/certs.d/privkey.pem
headers:
X-Content-Type-Options: [nosniff]
.....
.....
root@bizantum:~# systemctl restart docker-registry
# verify possible to access
# on HTTPS connection, it does not need to add [insecure-registries] on Docker
root@node01:~# docker pull dlp.bizantum.lab:5000/debian:my-registry
root@node01:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
debian latest 7e0aa2d69a15 2 weeks ago 72.7MB
dlp.bizantum.lab:5000/debian my-registry 62d49f9bab67 4 weeks ago 133MB
Step [5] To access via HTTPS and use self signed certificates, Configure like follows. This example is based on the environment that certificates have been created under the [/etc/ssl/private].
root@bizantum:~# mkdir -p /etc/docker/certs.d/dlp.bizantum.lab:5000
root@bizantum:~# cp -p /etc/ssl/private/server.{crt,key} /etc/docker/certs.d/dlp.bizantum.lab:5000/
root@bizantum:~# chown docker-registry /etc/docker/certs.d/dlp.bizantum.lab:5000/server.{crt,key}
root@bizantum:~# vi /etc/docker/registry/config.yml
# add [tls] section under the [http] section like follows
.....
.....
http:
addr: :5000
tls:
certificate: /etc/docker/certs.d/dlp.bizantum.lab:5000/server.crt
key: /etc/docker/certs.d/dlp.bizantum.lab:5000/server.key
headers:
X-Content-Type-Options: [nosniff]
.....
.....
root@bizantum:~# systemctl restart docker-registry
# verify possible to access
# an error is shown because of self signed certificate
root@node01:~# docker pull dlp.bizantum.lab:5000/debian:my-registry
Error response from daemon: Get https://dlp.bizantum.lab:5000/v2/: x509: certificate signed by unknown authority
# copy certificate on registry server to client
root@node01:~# mkdir -p /etc/docker/certs.d/dlp.bizantum.lab:5000
root@node01:~# scp root@bizantum.bizantum.lab:"/etc/docker/certs.d/dlp.bizantum.lab:5000/server.crt" /etc/docker/certs.d/dlp.bizantum.lab:5000/ca.crt
root@node01:~# docker pull dlp.bizantum.lab:5000/debian:my-registry
root@node01:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
debian latest 7e0aa2d69a15 2 weeks ago 72.7MB
dlp.bizantum.lab:5000/debian my-registry 62d49f9bab67 4 weeks ago 133MB
Docker Network
This is the basic usage to configure Docker Network.
Step [1]When running containers without specifying network, default [bridge] network is assigned.
# display network list
root@bizantum:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
11b02877db72 bridge bridge local
7e5fccb8cd81 host host local
a58e9ea6ddae none null local
e9c682aa11d5 root_default bridge local
# display details of [bridge]
root@bizantum:~# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "11b02877db7276c9f302ec6211591ee67e674efda4f34637125191d58fe82d4f",
"Created": "2023-06-22T01:56:04.398417557-05:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
# [bridge] is assigned as container network by default
root@bizantum:~# docker run debian /bin/bash -c "apt-get update; apt-get -y install iproute2; /usr/sbin/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@bizantum:~# docker commit $(docker ps -a|head -2|tail -1|awk '{print $1}') bizantum.lab/debian-iproute
Step [2]If you'd like to assign another network, set like follows.
# create network [network01] with [192.168.100.0/24] subnet
root@bizantum:~# docker network create --subnet 192.168.100.0/24 network01
5a736efe2fc4abcc70fd27198bf48a384fb854ea0422bf111b6c28bfa719931c
root@bizantum:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
11b02877db72 bridge bridge local
7e5fccb8cd81 host host local
5a736efe2fc4 network01 bridge local
a58e9ea6ddae none null local
e9c682aa11d5 root_default bridge local
# run a container with specifying [network01]
root@bizantum:~# docker run --net network01 bizantum.lab/debian-iproute /usr/sbin/ip route
default via 192.168.100.1 dev eth0
192.168.100.0/24 dev eth0 proto kernel scope link src 192.168.100.2
# to attach the network to existing running container, set like follows
root@bizantum:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
752707cb6701 bizantum.lab/debian-nginx "/usr/sbin/nginx -g …" 8 seconds ago Up 7 seconds 0.0.0.0:8081->80/tcp, :::8081->80/tcp friendly_williams
root@bizantum:~# docker exec 752707cb6701 /usr/sbin/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
# attach network to specify an IP address in the subnet
root@bizantum:~# docker network connect --ip 192.168.100.10 network01 752707cb6701
root@bizantum:~# docker exec 752707cb6701 /usr/sbin/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
192.168.100.0/24 dev eth1 proto kernel scope link src 192.168.100.10
# to disconnect the network, set like follows
root@bizantum:~# docker network disconnect network01 752707cb6701
root@bizantum:~# docker exec 752707cb6701 /usr/sbin/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
Step [3]To remove docker networks, set like follows.
root@bizantum:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
11b02877db72 bridge bridge local
7e5fccb8cd81 host host local
5a736efe2fc4 network01 bridge local
a58e9ea6ddae none null local
e9c682aa11d5 root_default bridge local
# remove [network01]
root@bizantum:~# docker network rm network01
network01
Step [3]To connect to Host network, set like follows.
root@bizantum:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
11b02877db72 bridge bridge local
7e5fccb8cd81 host host local
a58e9ea6ddae none null local
e9c682aa11d5 root_default bridge local
root@bizantum:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bizantum.lab/debian-iproute latest 2b1c5b7c483d 5 minutes ago 151MB
root_web latest d2928f1806c2 22 minutes ago 252MB
bizantum.lab/debian-apache2 latest 431c51e7819a 48 minutes ago 252MB
bizantum.lab/debian-nginx latest 5a202ab0ab76 53 minutes ago 153MB
mariadb latest 99833200524a 6 days ago 403MB
debian latest 49081a1edb0b 9 days ago 116MB
# run a container with [host] network
root@bizantum:~# docker run -d --net host bizantum.lab/debian-apache2
63b4e21a4647a1a9ec3ed9eb9baace67b61e3a49db9ca4e5314a7d3f9c4efa9d
root@bizantum:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63b4e21a4647 bizantum.lab/debian-apache2 "/usr/sbin/apachectl…" 10 seconds ago Up 9 seconds nice_sinoussi
# the port [apache2] service listens on container is used on Host network
root@bizantum:~# ss -napt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
.....
.....
LISTEN 0 511 *:80 *:* users:(("apache2",pid=15703,fd=4),("apache2",pid=15702,fd=4),("apache2",pid=15701,fd=4))
root@bizantum:~# curl localhost
index.html on Aapche2
Display Container resource usage
You can check percentage of CPU, memory, network I/O for Containers.
Step [1]Check the resource usage of each container.
# display usage statistics with streaming
root@bizantum:~# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
247708e86d14 stoic_shirley 0.00% 21.53MiB / 15.62GiB 0.13% 656B / 0B 0B / 8.19kB 56
b56ecadaa98a nervous_ride 0.00% 5.902MiB / 15.62GiB 0.04% 946B / 0B 0B / 4.1kB 9
# display without streaming
root@bizantum:~# docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
247708e86d14 stoic_shirley 0.00% 21.53MiB / 15.62GiB 0.13% 796B / 0B 0B / 8.19kB 56
b56ecadaa98a nervous_ride 0.00% 5.902MiB / 15.62GiB 0.04% 1.02kB / 0B 0B / 4.1kB 9
# display for a specific container
root@bizantum:~# docker stats b56ecadaa98a --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
b56ecadaa98a nervous_ride 0.00% 5.902MiB / 15.62GiB 0.04% 1.09kB / 0B 0B / 4.1kB 9
# display with specific format
root@bizantum:~# docker stats --no-stream --format "table {{.ID}} {{.CPUPerc}} {{.MemPerc}}"
CONTAINER ID CPU % MEM %
247708e86d14 0.00% 0.13%
b56ecadaa98a 0.00% 0.04%
Step [2]
Step [3]
Swarm Cluster
Configure Docker Swarm to create Docker Cluster with multiple Docker nodes. On this example, Configure Swarm Cluster with 3 Docker nodes like follows. There are 2 roles on Swarm Cluster, those are [Manager nodes] and [Worker nodes]. This example shows to set those roles like follows.
-----------+---------------------------+--------------------------+------------ | | | eth0|10.0.0.51 eth0|10.0.0.52 eth0|10.0.0.53 +----------+------------+ +----------+------------+ +---------+-------------+ | [node01.bizantum.lab] | | [node02.bizantum.lab] | | [node03.bizantum.lab] | | Manager | | Worker | | Worker | +-----------------------+ +-----------------------+ +-----------------------+
Step [1] Install and run Docker service on all nodes, refer to here.
Step [2] Disable live-restore feature on all Nodes. (because it can not use live-restore feature on Swarm mode)
root@node01:~# vi /etc/docker/daemon.json
# create new
{
"live-restore": false
}
root@node01:~# systemctl restart docker
Step [3]Configure Swarm Cluster on Manager Node.
root@node01:~# docker swarm init
Swarm initialized: current node (p8b0irmy3elmj1vrdsonfiv40) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2lxb5xwdxogw3esn78wahhcw8sj3p47wyan0xlla0vy288ofxb-ew6kbqs3qnj2p2nmqm2hdoa80 10.0.0.51:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Step [4] Join in Swarm Cluster on all Worker Nodes. It's OK to run the command which was shown when running swarm init on Manager Node.
root@node02:~# docker swarm join \
--token SWMTKN-1-2lxb5xwdxogw3esn78wahhcw8sj3p47wyan0xlla0vy288ofxb-ew6kbqs3qnj2p2nmqm2hdoa80 10.0.0.51:2377
This node joined a swarm as a worker.
Step [5]Verify with a command [node ls] that worker nodes could join in Cluster normally.
root@node01:~# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
p8b0irmy3elmj1vrdsonfiv40 * node01.bizantum.lab Ready Active Leader 20.10.24
pda4o1jnkcka35rup801abljf node02.bizantum.lab Ready Active 20.10.24
bqwt9t82vklehlyrlos7neueq node03.bizantum.lab Ready Active 20.10.24
Step [6]After creating Swarm Cluster, configure services the Swarm Cluster provides. For example, create a Nginx container to configure Swarm service. Generally, it is used a container image on a rgistry on all Nodes, but on this example, create container images on each Node to verify settings and accesses for Swarm Cluster.
root@node01:~# vi Dockerfile
FROM debian
MAINTAINER Bizantum <admin@bizantum.lab>
RUN apt-get update
RUN apt-get -y install nginx
RUN echo "Nginx on node01" > /var/www/html/index.html
EXPOSE 80
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
root@node01:~# docker build -t nginx-server:latest .
Step [7] Configure service on Manager Node. After succeeding to configure service, access to the Manager node's Hostname or IP address to verify it works normally. Access requests to worker nodes are load-balanced with round-robin like follows.
root@node01:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-server latest 396adbbc737d About a minute ago 160MB
debian latest 7e0aa2d69a15 2 weeks ago 72.7MB
# create a service with 2 replicas
root@node01:~# docker service create --name swarm_cluster --replicas=2 -p 80:80 nginx-server:latest
vnj5f8bzgqctnpbo7e21vhx7a
overall progress: 2 out of 2 tasks
1/2: running
2/2: running
verify: Service converged
# show service list
root@node01:~# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
vnj5f8bzgqct swarm_cluster replicated 2/2 nginx-server:latest *:80->80/tcp
# inspect the service
root@node01:~# docker service inspect swarm_cluster --pretty
ID: vnj5f8bzgqctnpbo7e21vhx7a
Name: swarm_cluster
Service Mode: Replicated
Replicas: 2
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Update order: stop-first
RollbackConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Rollback order: stop-first
ContainerSpec:
Image: nginx-server:latest
Init: false
Resources:
Endpoint Mode: vip
Ports:
PublishedPort = 80
Protocol = tcp
TargetPort = 80
PublishMode = ingress
# show service state
root@node01:~# docker service ps swarm_cluster
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
i8kqhuro1i0a swarm_cluster.1 nginx-server:latest node02.bizantum.lab Running Running about a minute ago
mp2run84lhsi swarm_cluster.2 nginx-server:latest node01.bizantum.lab Running Running about a minute ago
# verify it works normally
root@node01:~# curl node01.bizantum.lab
Nginx on node02
root@node01:~# curl node01.bizantum.lab
Nginx on node01
root@node01:~# curl node01.bizantum.lab
Nginx on node02
root@node01:~# curl node01.bizantum.lab
Nginx on node01
Step [8]If you'd like to change the number of replicas, configure like follows.
# change replicas to 3
root@node01:~# docker service scale swarm_cluster=3
swarm_cluster scaled to 3
overall progress: 3 out of 3 tasks
1/3: running
2/3: running
3/3: running
verify: Service converged
root@node01:~# docker service ps swarm_cluster
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
i8kqhuro1i0a swarm_cluster.1 nginx-server:latest node02.bizantum.lab Running Running 2 minutes ago
mp2run84lhsi swarm_cluster.2 nginx-server:latest node01.bizantum.lab Running Running 2 minutes ago
avioamhacach swarm_cluster.3 nginx-server:latest node03.bizantum.lab Running Running 14 seconds ago
# verify accesses
root@node01:~# curl node01.bizantum.lab
Nginx on node03
root@node01:~# curl node01.bizantum.lab
Nginx on node02
root@node01:~# curl node01.bizantum.lab
Nginx on node01
- Get link
- X
- Other Apps
Comments
Post a Comment
Thank you for your comment! We appreciate your feedback, feel free to check out more of our articles.
Best regards, Bizantum Blog Team.