# 升級 Docker & Harbor on rhel9 * 升級 docker 26.0.0 -> 29.1.5 * 升級 docker compose v2.25.0 -> v5.0.1 * 升級 harbor v2.1.3 -> v2.10.1 - harbor 的升級路徑為 v2.1.3 -> v2.4.0 -> v2.6.0 -> v2.8.0 -> v2.10.1 ## rhel 安裝舊版本 Docker & Harbor ### 安裝 docker * 新增 docker repo ``` $ sudo dnf -y install dnf-plugins-core $ sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo ``` * 搜尋可安裝 docker 套件 ``` $ sudo dnf list docker-ce --showduplicates | sort -r Updating Subscription Management repositories. docker-ce.x86_64 3:29.0.2-1.el9 docker-ce-stable docker-ce.x86_64 3:29.0.1-1.el9 docker-ce-stable docker-ce.x86_64 3:29.0.0-1.el9 docker-ce-stable docker-ce.x86_64 3:28.5.2-1.el9 docker-ce-stable docker-ce.x86_64 3:28.5.1-1.el9 docker-ce-stable docker-ce.x86_64 3:28.5.0-1.el9 docker-ce-stable $ sudo dnf list docker-ce-cli --showduplicates | sort -r Updating Subscription Management repositories. Last metadata expiration check: 0:03:12 ago on Fri 21 Nov 2025 10:57:35 AM CST. docker-ce-cli.x86_64 1:29.0.2-1.el9 docker-ce-stable docker-ce-cli.x86_64 1:29.0.1-1.el9 docker-ce-stable docker-ce-cli.x86_64 1:29.0.0-1.el9 docker-ce-stable docker-ce-cli.x86_64 1:28.5.2-1.el9 docker-ce-stable docker-ce-cli.x86_64 1:28.5.1-1.el9 docker-ce-stable docker-ce-cli.x86_64 1:28.5.0-1.el9 docker-ce-stable $ sudo dnf list docker-compose-plugin --showduplicates | sort -r Updating Subscription Management repositories. Last metadata expiration check: 0:10:50 ago on Fri 21 Nov 2025 10:57:35 AM CST. Installed Packages docker-compose-plugin.x86_64 2.40.3-1.el9 docker-ce-stable docker-compose-plugin.x86_64 2.40.3-1.el9 @docker-ce-stable docker-compose-plugin.x86_64 2.40.2-1.el9 docker-ce-stable docker-compose-plugin.x86_64 2.40.1-1.el9 docker-ce-stable docker-compose-plugin.x86_64 2.40.0-1.el9 docker-ce-stable docker-compose-plugin.x86_64 2.39.4-1.el9 docker-ce-stable docker-compose-plugin.x86_64 2.39.2-1.el9 docker-ce-stable ``` * 下載舊版本 ``` $ mkdir old-package $ sudo yum install --downloadonly --downloaddir="$HOME"/old-package \ docker-ce-3:26.0.0-1.el9 \ docker-ce-cli-1:26.0.0-1.el9 \ containerd.io \ docker-buildx-plugin-0.13.1-1.el9 \ docker-compose-plugin-2.25.0-1.el9 ``` * 安裝舊版本 ``` $ sudo yum localinstall --nogpgcheck "$HOME"/old-package/*.rpm ``` ``` $ sudo systemctl enable --now docker ``` ``` $ sudo docker info Client: Docker Engine - Community Version: 26.0.0 Context: default Debug Mode: false Plugins: buildx: Docker Buildx (Docker Inc.) Version: v0.13.1 Path: /usr/libexec/docker/cli-plugins/docker-buildx compose: Docker Compose (Docker Inc.) Version: v2.25.0 Path: /usr/libexec/docker/cli-plugins/docker-compose Server: Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 26.0.0 Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: true Using metacopy: false Native Overlay Diff: true userxattr: false Logging Driver: json-file Cgroup Driver: systemd Cgroup Version: 2 Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog Swarm: inactive Runtimes: io.containerd.runc.v2 runc Default Runtime: runc Init Binary: docker-init containerd version: dea7da592f5d1d2b7755e3a161be07f43fad8f75 runc version: v1.3.4-0-gd6d73eb8 init version: de40ad0 Security Options: seccomp Profile: builtin cgroupns Kernel Version: 5.14.0-427.13.1.el9_4.x86_64 Operating System: Red Hat Enterprise Linux 9.4 (Plow) OSType: linux Architecture: x86_64 CPUs: 4 Total Memory: 7.505GiB Name: upgrade ID: 00d462e4-d14c-4c0e-b58b-81e0e6f50fcc Docker Root Dir: /var/lib/docker Debug Mode: false Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false ``` * 安裝 docker switch,目的是讓 docker compose 可以轉換成 docker-compose 指令 ``` $ sudo curl -fL https://github.com/docker/compose-switch/releases/latest/download/docker-compose-linux-amd64 -o /usr/local/bin/compose-switch $ sudo chmod +x /usr/local/bin/compose-switch $ sudo update-alternatives --install /usr/bin/docker-compose docker-compose /usr/local/bin/compose-switch 99 $ sudo docker-compose version Docker Compose version v2.25.0 ``` ### 安裝 Harbor ``` $ wget https://github.com/goharbor/harbor/releases/download/v2.1.3/harbor-offline-installer-v2.1.3.tgz $ tar xvf harbor-offline-installer-v2.1.3.tgz; cd harbor/ ``` ``` $ mkdir ssl;cd ssl $ wget https://raw.githubusercontent.com/cooloo9871/SelfSigned-RootCA/master/mk $ chmod +x mk $ ./mk create harbor.example.com 10.10.7.16 $ cd .. ``` ``` $ cp harbor.yml.tmpl harbor.yml $ nano harbor.yml # Configuration file of Harbor # The IP address or hostname to access admin UI and registry service. # DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients. hostname: harbor.example.com # http related config http: # port for http, default is 80. If https enabled, this port will redirect to https port port: 80 # https related config https: # https port for harbor, default is 443 port: 443 # The path of cert and key files for nginx certificate: /home/bigred/harbor/ssl/cert.pem private_key: /home/bigred/harbor/ssl/cert-key.pem ``` * 啟動 harbor ``` $ sudo ./install.sh --with-trivy ``` ## 準備離線檔 ### 準備 docker * 下載現在最新版本 ``` $ mkdir package $ sudo yum install --downloadonly --downloaddir="$HOME"/package \ docker-ce \ docker-ce-cli \ containerd.io \ docker-buildx-plugin \ docker-compose-plugin ``` ``` $ ls -l package/ 總用量 96640 -rw-r--r--. 1 root root 37088865 1月 21 15:42 containerd.io-2.2.1-1.el9.x86_64.rpm -rw-r--r--. 1 root root 17919221 1月 21 15:42 docker-buildx-plugin-0.30.1-1.el9.x86_64.rpm -rw-r--r--. 1 root root 23144731 1月 21 15:42 docker-ce-29.1.5-1.el9.x86_64.rpm -rw-r--r--. 1 root root 8744991 1月 21 15:42 docker-ce-cli-29.1.5-1.el9.x86_64.rpm -rw-r--r--. 1 root root 3602234 1月 21 15:42 docker-ce-rootless-extras-29.1.5-1.el9.x86_64.rpm -rw-r--r--. 1 root root 8446036 1月 21 15:42 docker-compose-plugin-5.0.1-1.el9.x86_64.rpm $ tar -zcvf docker.tar.gz package/ ``` ### 準備 Harbor ``` $ wget https://github.com/goharbor/harbor/releases/download/v2.4.0/harbor-offline-installer-v2.4.0.tgz $ wget https://github.com/goharbor/harbor/releases/download/v2.6.0/harbor-offline-installer-v2.6.0.tgz $ wget https://github.com/goharbor/harbor/releases/download/v2.8.0/harbor-offline-installer-v2.8.0.tgz $ wget https://github.com/goharbor/harbor/releases/download/v2.10.1/harbor-offline-installer-v2.10.1.tgz ``` ### 打包所有檔案 ``` $ tar -czvf harbor.tar.gz \ docker.tar.gz \ harbor-offline-installer-v2.4.0.tgz \ harbor-offline-installer-v2.6.0.tgz \ harbor-offline-installer-v2.8.0.tgz \ harbor-offline-installer-v2.10.1.tgz $ ls -lh harbor.tar.gz -rw-r--r--. 1 bigred bigred 2.6G Jan 21 16:28 harbor.tar.gz ``` ## 開始升級 ### 升級 docker 版本 * 安裝遇到 repo 報錯可以跳過有問題的 repo,添加參數`--disablerepo=rhel9.4-baseos,rhel9.4-appstream` ``` $ tar -zxvf harbor.tar.gz $ tar -zxvf docker.tar.gz $ sudo yum localinstall --nogpgcheck "$HOME"/package/*.rpm ``` ``` $ sudo systemctl daemon-reload $ sudo systemctl restart docker ``` ``` $ sudo docker info Client: Docker Engine - Community Version: 29.1.5 Context: default Debug Mode: false Plugins: buildx: Docker Buildx (Docker Inc.) Version: v0.30.1 Path: /usr/libexec/docker/cli-plugins/docker-buildx compose: Docker Compose (Docker Inc.) Version: v5.0.1 Path: /usr/libexec/docker/cli-plugins/docker-compose ``` ### 升級 harbor v2.1.3 -> v2.4.0 * 關閉 harbor 服務 ``` $ cd harbor $ sudo docker compose down ``` * 建立備份目錄,建議直接備份 VM ``` $ cd ~ $ sudo mkdir /harbor-backup ``` * 備份 harbor ``` $ sudo mv harbor /harbor-backup/harbor ``` * 備份資料庫 ``` $ sudo cp -r /data/database /harbor-backup/ ``` * 解包新版 harbor,並匯入新版 image ``` $ tar -zxvf harbor-offline-installer-v2.4.0.tgz $ sudo docker image load -i harbor/harbor.v2.4.0.tar.gz ``` * 升級 `harbor.yml` 文件,注意自己舊版的 `harbor.yml` 路徑,`migrate -i` 指令後面是放舊版 `harbor.yml` 位置,他會覆蓋掉原本的檔案,因此還要把他在做備份 ``` $ cp /harbor-backup/harbor/harbor.yml /harbor-backup/harbor/harbor2.yml $ sudo docker run -it --rm -v /:/hostfs goharbor/prepare:v2.4.0 migrate -i /harbor-backup/harbor/harbor.yml # 將升級好的 harbor.yml 複製到 harbor/ $ cp /harbor-backup/harbor/harbor.yml harbor/ ``` * 把原有憑證複製回來 ``` $ cp -r /harbor-backup/harbor/ssl harbor/ ``` * 安裝新版 harbor ``` $ cd harbor $ sudo ./install.sh --with-trivy ``` * 檢查升級狀態 ``` $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 88759773d8bd goharbor/nginx-photon:v2.4.0 "nginx -g 'daemon of…" 12 seconds ago Up 10 seconds (health: starting) 0.0.0.0:80->8080/tcp, [::]:80->8080/tcp, 0.0.0.0:443->8443/tcp, [::]:443->8443/tcp nginx 173cb6fbc783 goharbor/harbor-jobservice:v2.4.0 "/harbor/entrypoint.…" 12 seconds ago Up 10 seconds (health: starting) harbor-jobservice 539434c87afd goharbor/harbor-core:v2.4.0 "/harbor/entrypoint.…" 12 seconds ago Up 10 seconds (health: starting) harbor-core 651160f11dd0 goharbor/trivy-adapter-photon:v2.4.0 "/home/scanner/entry…" 12 seconds ago Up 10 seconds (health: starting) trivy-adapter ba62547d28aa goharbor/harbor-registryctl:v2.4.0 "/home/harbor/start.…" 12 seconds ago Up 11 seconds (health: starting) registryctl 6d53377e2d35 goharbor/redis-photon:v2.4.0 "redis-server /etc/r…" 12 seconds ago Up 11 seconds (health: starting) redis 4f3e024f5fa6 goharbor/registry-photon:v2.4.0 "/home/harbor/entryp…" 12 seconds ago Up 11 seconds (health: starting) registry ff09cef7d623 goharbor/harbor-portal:v2.4.0 "nginx -g 'daemon of…" 12 seconds ago Up 11 seconds (health: starting) harbor-portal 7817a34ed7f5 goharbor/harbor-db:v2.4.0 "/docker-entrypoint.…" 12 seconds ago Up 11 seconds (health: starting) harbor-db 5b74384c46f4 goharbor/harbor-log:v2.4.0 "/bin/sh -c /usr/loc…" 12 seconds ago Up 11 seconds (health: starting) 127.0.0.1:1514->10514/tcp ``` * 清理備份 ``` $ sudo rm -r /harbor-backup/* ``` ### 升級 harbor v2.4.0 -> v2.6.0 * 關閉 harbor 服務 ``` $ sudo docker compose down $ cd ~ ``` * 備份 harbor ``` $ sudo mv harbor /harbor-backup/harbor ``` * 備份資料庫 ``` $ sudo cp -r /data/database /harbor-backup/ ``` * 解包新版 harbor,並匯入新版 image ``` $ tar -zxvf harbor-offline-installer-v2.6.0.tgz $ sudo docker image load -i harbor/harbor.v2.6.0.tar.gz ``` * 升級 `harbor.yml` 文件,注意自己舊版的 `harbor.yml` 路徑,`migrate -i` 指令後面是放舊版 `harbor.yml` 位置,他會覆蓋掉原本的檔案,因此還要把他在做備份 ``` $ cp /harbor-backup/harbor/harbor.yml /harbor-backup/harbor/harbor2.yml $ sudo docker run -it --rm -v /:/hostfs goharbor/prepare:v2.6.0 migrate -i /harbor-backup/harbor/harbor.yml # 將升級好的 harbor.yml 複製到 harbor/ $ cp /harbor-backup/harbor/harbor.yml harbor/ ``` * 把原有憑證複製回來 ``` $ cp -r /harbor-backup/harbor/ssl harbor/ ``` * 安裝新版 harbor ``` $ cd harbor $ sudo ./install.sh --with-trivy ``` * 檢查升級狀態 ``` $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f98a19893c93 goharbor/nginx-photon:v2.6.0 "nginx -g 'daemon of…" 6 seconds ago Up 3 seconds (health: starting) 0.0.0.0:80->8080/tcp, [::]:80->8080/tcp, 0.0.0.0:443->8443/tcp, [::]:443->8443/tcp nginx dc6583e305bc goharbor/harbor-jobservice:v2.6.0 "/harbor/entrypoint.…" 6 seconds ago Up 2 seconds (health: starting) harbor-jobservice b3a3b8f12e1f goharbor/harbor-core:v2.6.0 "/harbor/entrypoint.…" 6 seconds ago Up 4 seconds (health: starting) harbor-core 9b4015223bb1 goharbor/trivy-adapter-photon:v2.6.0 "/home/scanner/entry…" 6 seconds ago Up 4 seconds (health: starting) trivy-adapter 9dfce4c75bac goharbor/redis-photon:v2.6.0 "redis-server /etc/r…" 6 seconds ago Up 5 seconds (health: starting) redis 82e81bd21793 goharbor/registry-photon:v2.6.0 "/home/harbor/entryp…" 6 seconds ago Up 5 seconds (health: starting) registry 095b9ceb1885 goharbor/harbor-db:v2.6.0 "/docker-entrypoint.…" 6 seconds ago Up 5 seconds (health: starting) harbor-db dc402a4c9a67 goharbor/harbor-portal:v2.6.0 "nginx -g 'daemon of…" 6 seconds ago Up 5 seconds (health: starting) harbor-portal d4059d90b0ee goharbor/harbor-registryctl:v2.6.0 "/home/harbor/start.…" 6 seconds ago Up 5 seconds (health: starting) registryctl 5727a3fa56ed goharbor/harbor-log:v2.6.0 "/bin/sh -c /usr/loc…" 6 seconds ago Up 5 seconds (health: starting) 127.0.0.1:1514->10514/tcp harbor-log ``` * 清理備份 ``` $ sudo rm -r /harbor-backup/* ``` ### 升級 harbor v2.6.0 -> v2.8.0 * 關閉 harbor 服務 ``` $ sudo docker compose down $ cd ~ ``` * 備份 harbor ``` $ sudo mv harbor /harbor-backup/harbor ``` * 備份資料庫 ``` $ sudo cp -r /data/database /harbor-backup/ ``` * 解包新版 harbor,並匯入新版 image ``` $ tar -zxvf harbor-offline-installer-v2.8.0.tgz $ sudo docker image load -i harbor/harbor.v2.8.0.tar.gz ``` * 升級 `harbor.yml` 文件,注意自己舊版的 `harbor.yml` 路徑,`migrate -i` 指令後面是放舊版 `harbor.yml` 位置,他會覆蓋掉原本的檔案,因此還要把他在做備份 ``` $ cp /harbor-backup/harbor/harbor.yml /harbor-backup/harbor/harbor2.yml $ sudo docker run -it --rm -v /:/hostfs goharbor/prepare:v2.8.0 migrate -i /harbor-backup/harbor/harbor.yml # 將升級好的 harbor.yml 複製到 harbor/ $ cp /harbor-backup/harbor/harbor.yml harbor/ ``` * 把原有憑證複製回來 ``` $ cp -r /harbor-backup/harbor/ssl harbor/ ``` * 安裝新版 harbor ``` $ cd harbor $ sudo ./install.sh --with-trivy ``` * 檢查升級狀態 ``` $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f1d634f75505 goharbor/harbor-jobservice:v2.8.0 "/harbor/entrypoint.…" 11 seconds ago Up 8 seconds (health: starting) harbor-jobservice 37a67f3e310b goharbor/nginx-photon:v2.8.0 "nginx -g 'daemon of…" 11 seconds ago Up 9 seconds (health: starting) 0.0.0.0:80->8080/tcp, [::]:80->8080/tcp, 0.0.0.0:443->8443/tcp, [::]:443->8443/tcp nginx e1f959fac081 goharbor/trivy-adapter-photon:v2.8.0 "/home/scanner/entry…" 11 seconds ago Up 9 seconds (health: starting) trivy-adapter 0ecbacc2295b goharbor/harbor-core:v2.8.0 "/harbor/entrypoint.…" 11 seconds ago Up 9 seconds (health: starting) harbor-core 6065f5c8c4d9 goharbor/harbor-registryctl:v2.8.0 "/home/harbor/start.…" 11 seconds ago Up 10 seconds (health: starting) registryctl 32e31ae860d7 goharbor/redis-photon:v2.8.0 "redis-server /etc/r…" 11 seconds ago Up 10 seconds (health: starting) redis 2427a30f17a5 goharbor/harbor-portal:v2.8.0 "nginx -g 'daemon of…" 11 seconds ago Up 10 seconds (health: starting) harbor-portal 399b274af332 goharbor/harbor-db:v2.8.0 "/docker-entrypoint.…" 11 seconds ago Up 10 seconds (health: starting) harbor-db 79e41b7824dd goharbor/registry-photon:v2.8.0 "/home/harbor/entryp…" 11 seconds ago Up 10 seconds (health: starting) registry ff2c1f8c6e56 goharbor/harbor-log:v2.8.0 "/bin/sh -c /usr/loc…" 11 seconds ago Up 10 seconds (health: starting) 127.0.0.1:1514->10514/tcp harbor-log ``` * 清理備份 ``` $ sudo rm -r /harbor-backup/* ``` ### 升級 harbor v2.8.0 -> v2.10.1 * 關閉 harbor 服務 ``` $ sudo docker compose down $ cd ~ ``` * 備份 harbor ``` $ sudo mv harbor /harbor-backup/harbor ``` * 備份資料庫 ``` $ sudo cp -r /data/database /harbor-backup/ ``` * 解包新版 harbor,並匯入新版 image ``` $ tar -zxvf harbor-offline-installer-v2.10.1.tgz $ sudo docker image load -i harbor/harbor.v2.10.1.tar.gz ``` * 升級 `harbor.yml` 文件,注意自己舊版的 `harbor.yml` 路徑,`migrate -i` 指令後面是放舊版 `harbor.yml` 位置,他會覆蓋掉原本的檔案,因此還要把他在做備份 ``` $ cp /harbor-backup/harbor/harbor.yml /harbor-backup/harbor/harbor2.yml $ sudo docker run -it --rm -v /:/hostfs goharbor/prepare:v2.10.1 migrate -i /harbor-backup/harbor/harbor.yml # 將升級好的 harbor.yml 複製到 harbor/ $ cp /harbor-backup/harbor/harbor.yml harbor/ ``` * 把原有憑證複製回來 ``` $ cp -r /harbor-backup/harbor/ssl harbor/ ``` * 安裝新版 harbor ``` $ cd harbor $ sudo ./install.sh --with-trivy ``` * 檢查升級狀態 ``` $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af05d85030db goharbor/nginx-photon:v2.10.1 "nginx -g 'daemon of…" 22 seconds ago Up 20 seconds (health: starting) 0.0.0.0:80->8080/tcp, [::]:80->8080/tcp, 0.0.0.0:443->8443/tcp, [::]:443->8443/tcp nginx 47a31a99de87 goharbor/harbor-jobservice:v2.10.1 "/harbor/entrypoint.…" 22 seconds ago Up 3 seconds (health: starting) harbor-jobservice 072b5df4adb4 goharbor/harbor-core:v2.10.1 "/harbor/entrypoint.…" 22 seconds ago Up 21 seconds (health: starting) harbor-core dc97efd93e4e goharbor/trivy-adapter-photon:v2.10.1 "/home/scanner/entry…" 22 seconds ago Up 21 seconds (health: starting) trivy-adapter 4f81432d6421 goharbor/redis-photon:v2.10.1 "redis-server /etc/r…" 22 seconds ago Up 21 seconds (health: starting) redis 34c1b778accf goharbor/harbor-db:v2.10.1 "/docker-entrypoint.…" 22 seconds ago Up 21 seconds (health: starting) harbor-db 4e9f94654f7c goharbor/harbor-registryctl:v2.10.1 "/home/harbor/start.…" 22 seconds ago Up 21 seconds (health: starting) registryctl f868269a3467 goharbor/harbor-portal:v2.10.1 "nginx -g 'daemon of…" 22 seconds ago Up 21 seconds (health: starting) harbor-portal 1ce6bb6887e0 goharbor/registry-photon:v2.10.1 "/home/harbor/entryp…" 22 seconds ago Up 21 seconds (health: starting) registry 84bde22878d4 goharbor/harbor-log:v2.10.1 "/bin/sh -c /usr/loc…" 22 seconds ago Up 22 seconds (health: starting) 127.0.0.1:1514->10514/tcp ``` * 清理備份 ``` $ sudo rm -r /harbor-backup ```