Skip to content

Docker

https://www.cherryservers.com/v3/assets/blog/2022-12-20/02.png

build

docker build --no-cache --progress=plain . 2>&1 | tee build.log

multi-stage builds

container

docker container prune

容器與訊號

當你在執行 Docker 容器時,主要執行程序(Process)的 PID 將會是 1,只要這個程序停止,容器就會跟著停止。

以 docker stop 為例,這個命令實質上是對容器中的 PID 1 送出一個 SIGTERM 訊號,如果程序本身並沒有處理 Signal 的機制,就會直接忽略這類訊號,這就會導致 docker stop 等了 10 秒之後還不結束,然後 Docker Engine 又會對 PID 1 送出另一個 SIGKILL 訊號,試圖強迫砍掉這個程序,這才會讓容器徹底停下來。

mknod

systemd inside the docker container

That being said, there are also lots of reasons not to run systemd in containers. The main one is that systemd/journald controls the output of containers, whereas tools like Kubernetes and OpenShift expect the containers to log directly to stdout and stderr. So, if you are going to manage your containers via Orchestrator like these, then you should think twice about using systemd-based containers. Additionally, the upstream community of Docker and Moby were often hostile to the use of systemd in a container. How to run systemd in a container | Red Hat Developer

It is generally recommended that you separate areas of concern by using one service per container. That service may fork into multiple processes (for example, Apache web server starts multiple worker processes). It’s ok to have multiple processes - Run multiple services in a container | Docker Documentation

If your process falls into this category, you can use the --init option when you run the container. The --init flag inserts a tiny init-process into the container as the main process, and handles reaping of all processes when the container exits. Handling such processes this way is superior to using a full-fledged init process such as sysvinit, upstart, or systemd to handle process lifecycle within your container.

for example nginx

root@2b8cf1261323:/# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0   8932  5708 ?        Ss   08:55   0:00 nginx: master process nginx -g daemon off;
nginx         29  0.0  0.0   9320  2668 ?        S    08:55   0:00 nginx: worker process
nginx         30  0.0  0.0   9320  2668 ?        S    08:55   0:00 nginx: worker process
nginx         31  0.0  0.0   9320  2668 ?        S    08:55   0:00 nginx: worker process
nginx         32  0.0  0.0   9320  2668 ?        S    08:55   0:00 nginx: worker process
root          33  0.0  0.0   4164  3580 pts/0    Ss   08:56   0:00 bash
root         383  0.0  0.0   6760  3076 pts/0    R+   08:58   0:00 ps aux

for example ubuntu

upermicro@supermicro-Virtual-Machine:~/srccode/dockerize-xcat$ docker run ubuntu bash -c 'ps aux'
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0   7060  1548 ?        Rs   09:03   0:00 ps aux

for example redis

root@dc49d0761c3f:/data# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
redis          1  0.1  0.1  53676 13532 ?        Ssl  09:05   0:00 redis-server *:6379
root          34  0.0  0.0   4156  3484 pts/0    Ss   09:05   0:00 bash
root         855  0.0  0.0   6760  3008 pts/0    R+   09:10   0:00 ps aux
root@dc49d0761c3f:/data# cat /etc/issue
Debian GNU/Linux 11 \n \l

image

docker image prune
docker image ls | awk 'NR>1 {print $1":"$2}' | xargs -I {} sh -c 'echo "Inspecting image: {}"; docker image inspect {}

save and load

network

host

port

env, arg

permission

volume

/var/lib/docker/volumes
docker volume ls

volume propagation behavior

#!/bin/bash


sudo ls -la /var/lib/docker/volumes/ng-vol/_data


# run a container which creates a new volume
docker volume rm ng-vol
docker run -d --name nginx1 --mount source=ng-vol,target=/usr/share/nginx/html nginx
docker exec nginx1 ls -la /usr/share/nginx/html
docker exec nginx1 ls -la /app
docker exec nginx1 touch /usr/share/nginx/html/abc.html
sudo ls -la /var/lib/docker/volumes/ng-vol/_data


# /app not exist
docker run -d --name nginx2 --mount source=ng-vol,target=/app nginx
docker exec nginx2 ls -la /app
sudo ls -la /var/lib/docker/volumes/ng-vol/_data


# mount a non-empty volume into a directory in the container in which some files or directories exist, 
# these files or directories are obscured by the mount
docker run -d --name nginx3 --mount source=ng-vol,target=/usr/share/nginx/html nginx
docker exec nginx3 ls -la /usr/share/nginx/html
sudo ls -la /var/lib/docker/volumes/ng-vol/_data


# A given volume can be mounted into multiple containers simultaneously


# create file in a container and show in another container
docker exec nginx3 touch /usr/share/nginx/html/ng3-abc.html
docker exec nginx2 ls -la /app
sudo ls -la /var/lib/docker/volumes/ng-vol/_data


docker stop nginx1 nginx2 nginx3
docker rm nginx1 nginx2 nginx3
docker volume rm ng-vol

docker compose

``` docker= version: "3" services: redis: container_name: "project-name-redis" image: "redis:3.2.4-alpine" ports: - "6379:6379" mariadb: container_name: "project-name-config-db" image: "mariadb:10.4" ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: example MYSQL_DATABASE: project_name_alpha_0706 MYSQL_USER: project MYSQL_PASSWORD: project volumes: - ./mariadb:/docker-entrypoint-initdb.d command: ['mysqld', '--character-set-server=utf8', '--collation-server=utf8_general_ci'] elasticsearch: container_name: "project-name-es" image: "docker.elastic.co/elasticsearch/elasticsearch:6.8.18" ports: - "127.0.0.1:9200:9200" - "127.0.0.1:9300:9300" environment: discovery.type: single-node kibana: image: "docker.elastic.co/kibana/kibana:6.8.18" container_name: "project-name-kibana" environment: SERVER_NAME: kibana-server ELASTICSEARCH_URL: http://elasticsearch:9200 depends_on: - elasticsearch ports: - "127.0.0.1:5601:5601"

There is a file such as init.sql in mariadb directory
``` sql=
GRANT ALL PRIVILEGES ON *.* TO 'project'@'%';
CREATE DATABASE  IF NOT EXISTS `project_name_alpha_0706`;
USE `project_name_alpha_0706`;

build

Build subsection is present for a service, it is valid for a Compose file to miss an Image attribute for corresponding service, as Compose implementation can build image from source. Compose file build reference | Docker Documentation

networks

multiple compose files

healthcheck

mysql

awesome image

sameersbn/bind - Docker Image | Docker Hub

version: '3.5'

services:
  bind9:
    image: sameersbn/bind:latest
    ports:
    - "53:53/udp"
    - "53:53/tcp"
    - "10000:10000"
    volumes:
    - ./docker_data:/data
    restart: always

sonatype/nexus3 - Docker Image | Docker Hub

Use a docker volume

services:
  nexus:
    image: sonatype/nexus3
    container_name: nexus
    ports:
      - "8081:8081"
      # https://blog.yowko.com/nexus-docker-image-rergistry/
      - "8082:8082"
    volumes:
      - nexus-data:/nexus-data

volumes:
  nexus-data:
    name: nexus-data

Mount a host directory as the volume.

version: "3.9"
services:
  nexus:
    image: sonatype/nexus3
    ports:
    - "8081:8081"
    # https://blog.yowko.com/nexus-docker-image-rergistry/
    - "8082:8082"
    volumes:
    - ./host-nexus-data:/nexus-data
    restart: always

Run Docker Container · dbeaver/cloudbeaver Wiki · GitHub

for quick test and the volume will be removed after stop

docker run --name cloudbeaver --rm -ti -p 9090:8978 -v /opt/cloudbeaver/workspace dbeaver/cloudbeaver:latest

version: "3.9"
services:
  cloudbeaver:
    image: dbeaver/cloudbeaver:latest
    ports:
    - "9527:8978"
    volumes:
    - cloudbeaver-data:/opt/cloudbeaver/workspace
    restart: always
volumes:
  cloudbeaver-data:

GitHub - mermaid-js/mermaid-live-editor: Edit, preview and share mermaid charts/diagrams. New implementation of the live editor.

quick test

docker run --name mermaid-live-editor --platform linux/amd64 -d --rm --publish 3000:8080 ghcr.io/mermaid-js/mermaid-live-editor

git clone https://github.com/mermaid-js/mermaid-live-editor.git
cd mermaid-live-editor
docker compose up -d

docker安裝老牌「會議室預約系統(MRBS)」 - 咖啡偶-IT日常

GitHub - aquasecurity/trivy: Find vulnerabilities, misconfigurations, secrets, SBOM in containers, Kubernetes, code repositories, clouds and more

docker run aquasec/trivy image 3x3cut0r/tftpd-hpa

TFTP and DHCP for PXE

- [3x3cut0r/isc-dhcp-server - Docker Image | Docker Hub](https://hub.docker.com/r/3x3cut0r/isc-dhcp-server)
- [3x3cut0r/tftpd-hpa - Docker Image | Docker Hub](https://hub.docker.com/r/3x3cut0r/tftpd-hpa)
version: '3.9'

services:
  tftpd-hpa:
    image: 3x3cut0r/tftpd-hpa
    environment:
        CREATE: 1
        VERBOSE: 1
    volumes:
      - /tftpboot:/tftpboot
    ports:
      - 69:69/udp

  isc-dhcp-server:
    image: 3x3cut0r/isc-dhcp-server:latest
    environment:
        IFACE: "ens160 ens256"
        PROTOCOL: 4
    volumes:
        - /etc/dhcp/dhcpd.conf:/etc/dhcp/dhcpd.conf
    network_mode: host

GitHub - cturra/docker-ntp: 🕒 Chrony NTP Server running in a Docker container (without the priviledged flag)

httpd

用Docker建構開箱可用的Nextcloud  / Deploying a Ready-to-Use Nextcloud Instance with Docker - 布丁布丁吃什麼?

basic

docker run -dit --name my-apache-app -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4

# alpine
docker run -dit --name my-apache-app -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:alpine

SSL enable

openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout server.key -out server.crt -days 30

docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > my-httpd.conf
sed -i \
        -e 's/^#\(Include .*httpd-ssl.conf\)/\1/' \
        -e 's/^#\(LoadModule .*mod_ssl.so\)/\1/' \
        -e 's/^#\(LoadModule .*mod_socache_shmcb.so\)/\1/' \
        conf/my-httpd.conf
docker run -dit --name my-apache-app \
-p 8080:80 -p 443:443 \
-v "$PWD":/usr/local/apache2/htdocs/ \
-v "$PWD"/config/server.key:/usr/local/apache2/conf/server.key \
-v "$PWD"/config/server.crt:/usr/local/apache2/conf/server.crt \
-v "$PWD"/config/my-httpd.conf:/usr/local/apache2/conf/httpd.conf \
httpd:alpine

nginx

basic

docker run --name some-nginx -p 8088:80 -v "$PWD"/test_html:/usr/share/nginx/html:ro -d nginx

# alpine
docker run --name some-nginx -p 8088:80 -v "$PWD"/test_html:/usr/share/nginx/html:ro -d nginx:stable-alpine-slim

auto index

:::info autoindex on; :::

nginx_auto_index.conf

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        autoindex on;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

docker run --name some-nginx -p 8088:80 -v "$PWD"/test_html/config/nginx_auto_index.conf:/etc/nginx/conf.d/default.conf:ro -v "$PWD"/test_html:/usr/share/nginx/html:ro -d nginx:stable-alpine-slim

SSL enable

:::info listen 443 ssl; :::

:::info ssl_certificate cert/server.crt; ssl_certificate_key cert/server.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; :::

nginx_ssl_enable.conf

server {
    listen       80;
    listen  [::]:80;
    listen 443 ssl;

    ssl_certificate cert/server.crt;
    ssl_certificate_key cert/server.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;

    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        autoindex on;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

docker run --name some-nginx -p 8088:80 -p 443:443 -v "$PWD"/test_html/config/nginx_ssl_enable.conf:/etc/nginx/conf.d/default.conf:ro -v "$PWD"/cert:/etc/nginx/cert:ro -v "$PWD"/test_html:/usr/share/nginx/html:ro -d nginx:stable-alpine-slim

GitHub - semaphoreui/semaphore: Modern UI and powerful API for Ansible, Terraform, OpenTofu, PowerShell and other DevOps tools.

GitHub - rundeck/rundeck: Enable Self-Service Operations: Give specific users access to your existing tools, services, and scripts

install

docker run --name rundeck-demo -d \
  -p 4440:4440 \
  -v rundeck-data:/home/rundeck/server/data \
  -e RUNDECK_GRAILS_URL=http://172.19.57.10:4440 \
  rundeck/rundeck:5.11.1

# access http://172.19.57.10:4440/ with admin/admin

install with Welcom project

wget https://github.com/rundeck/welcome-project-community/archive/refs/heads/main.zip && unzip main.zip
cd welcome-project-community-main/
# modify RUNDECK_GRAILS_URL and ciao port if 3000 is used
# RUNDECK_GRAILS_URL: http://172.19.57.10:4440
# ciao:
#         container_name: ciao
#         image: brotandgames/ciao
#         ports:
#           - '3001:3000'
docker compose up -d

offiline install

# Ubuntu 22 offiline docker installation
wget https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/docker-ce_26.1.1-1~ubuntu.22.04~jammy_amd64.deb
wget https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/containerd.io_1.6.31-1_amd64.deb
wget https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/docker-ce-cli_26.1.1-1~ubuntu.22.04~jammy_amd64.deb
sudo dpkg -i *.deb

MTU

for docker default bridge

/lib/systemd/system/docker.service
/etc/docker/daemon.json

sudo systemctl daemon-reload
sudo systemctl restart docker.service

/etc/docker/daemon.json

{ "mtu": 1400 }

for docker compose

docker-compose.yml

networks:
  default:
    driver: bridge
    driver_opts:
      com.docker.network.driver.mtu: 1400