快轉到主要內容

從Docker遷移到Podman,能用網頁界面管理docker-compose嗎?

分類   Linux系統 Self-hosting自架
標籤   Podman Docker Rocky Linux
🗓️ 民國113年 甲辰年
✍ 切換正體/簡體字
目錄

Podman是2018年開始發展的容器技術,可作為Docker的替代品。

記得2021年在屏大的時候,教Linux的電通系劉教授請來業師演講,就說過Podman要取代Docker了,似乎是因為Kubernetes捨棄Docker的原因。網路上也很多人說Docker過氣了!

快上船…你帶我走吧!圖片來自Podman Desktop官網

當時我對Linux還停留在Android手機Termux打打指令的概念,所以只弱弱的問了業師:Docker對桌面用戶有什麼好處呢…?我到底在工三小,ㄟ!現在看來也沒有錯,Podman跟Flatpak你敢說沒關係麼(轉真硬)

啊結果嘞?到現在Docker也還沒消失嘛!

Docker是2013年就開始發展的技術,圍繞著Docker開發的東西相對成熟許多。2019年我開始學著用Docker在Ubuntu跑 self-hosted服務,見到了許多自由軟體的開發者慣於使用Docker發表成品,只要幾條指令就能架起伺服器服務。

直到現在2024年,在用RHEL系Linux發行版的時候發現,RedHat似乎不愛Docker,加上Fedora Silverblue、RHEL、Rocky Linux預設就安裝了Podman,所以學著換用Podman。

測試環境:

  • Rocky Linux 9
  • Docker 27.3.1
  • Podman 4.9.4

1. 遷移到Podman之前的需求考量
#

目前我在Linux伺服器上跑的東西:Docker搭配Portainer,用網頁管理許多docker-compose,方便一鍵開關selt-hosted服務。並且搭配Nvidia Container Toolkit在容器中跑CUDA。

我需要跑這些容器服務:

  • Portainer
  • Jellyfin
  • Immich
  • Nextcloud
  • qBittorrent + Gluetun VPN
  • Minecraft基岩版伺服器
  • ReDroid
  • Ollama Open WebUI
  • Stable Diffusion ComfyUI

一直覺得docker run的指令加一堆引數很醜,所以比較喜歡用docker-compose.yaml定義服務內容,一清二楚。

又,用指令管理這些服務很麻煩,所以希望有個漂亮的網頁來管理,那就是Portainer。它本身也是個容器服務。

切換到Podman能不能滿足需求呢?是否要整個stack換掉?

2. Podman相較於Docker的優點
#

目前找到的很多捧Podman的資料都是RedHat提供的,他們甚至出了一本 The Container Commandos兒童著色本讓你認識Podman……這是什麼"JavaScript for Kids"書籍的變體嗎!?

就我的觀察,Podman優點如下:

  • 同為開源軟體,Podman比較傾向自由軟體,而不像Docker那樣商業味濃厚。(屁啦也不想想RedHat是什麼公司)
  • Podman指令跟Docker長得很像,甚至有比較誇張的說法:設一條alias指令就能無縫從Docker轉換到Podman。
  • Podman因為沒有常駐程式(daemonless),所以跟Systemd整合更好,不會像Dockerd一樣跟Systemd打架,並且迴避掉Docker單點故障的問題。若要讓Podman容器開機自動啟動,可以用Podman Quadlet將其設定為Systemd服務,統一用Systemd指令管理。
  • Podman可以跟Kubernetes整合,Docker很難。
  • Podman支援rootless模式執行,提升安全性。這點有點類似Flatpak,讓普通用戶也能任意安裝程式。
  • 許多RHEL系的Linux發行版內建Podman,不像Docker需要額外安裝。
  • 託管容器映像檔的Docker Hub是一家商業平台,2023年曾經發生過趕走開源軟體開發者的事情。那麼RedHat建立的Quay.io又如何呢?很抱歉,它也是商業平台,而且收費更貴,不過它伺服器是開源的,允許使用者自架Docker Registry。
  • Podman主要支援的是Linux,至於其他系統,透過完全開源的Podman Desktop程式,讓Windows和macOS用戶也能用Podman,取代閉源的Docker Desktop。

3. 安裝Podman
#

Podman跟Docker是可以共存的。

大部分Linux發行版的套件庫都有收,Rocky Linux的安裝方法:

sudo dnf install podman

Podman指令請參考 官方手冊,大部分都跟Docker類似。

4. Podman的權限問題
#

比較讓我困惑的是Docker只要將一般使用者加入docker群組就能直接執行docker指令,拉取的映像檔會存在同一個位置,因此docker runsudo docker run是沒差的。

換成Podman,得加--privileged或者sudo podman才能確保容器能存取所有裝置,而不會有權限不足或是無法使用低位數通訊埠的問題。這樣下來,podman runsudo podman就會出現差異,二者的映像檔會存在不同的位置,並且權限也有差異。

因為伺服器主要是我一個人管理的,故使用個別使用者能自行管理的rootless podman沒什麼意義,還得調一堆參數開放權限給一般使用者。

所以我就索性所有指令都用sudo podman跑了。是的,雖然這是個人伺服器,但是我不會什麼指令都用root使用者操作。

還有一點要注意:RHEL系Linux發行版有很嚴格的SELinux規則,即使用sudo podman,容器有時仍會在存取特定目錄的時候跳出權限不足的錯誤,得用引數--security-opt label=disable繞過。

5. Podman開機自動啟動容器
#

因為Podman是daemonless,所以無法像Docekr一樣在dockerd服務啟動後,就自動帶起所有--restart=always引數的容器。

得自行寫Systemd Unit設定容器自動啟動,用Systemd去管理容器服務。專為Podman設計的Systemd Unit稱為「Quadlet」,取代舊版的podman-generate-systemd。Quadlet可以使用Systemd來設定多個容器之間的啟動依賴關係。

不過手寫Quadlet檔案有點麻煩,所以用 Podlet工具來自動生成吧。

例如,要新增一個開機啟動的hello-world容器:

# 叫Podlet按照指令`podman run hello-world`生成一個Quadlet檔
podlet --file .  --install --description "Hello World" podman run hello-world

cat hello-world.container

# 安裝到Systemd專為容器設計的目錄
sudo mv hello-world.container /etc/containers/systemd/

sudo systemctl daemon-reload

# 讓Quadlet檢查要啟動的容器
sudo /usr/libexec/podman/quadlet --dryrun

# 設定開機自動啟動hello-world容器
sudo systemctl enable --now hello-world.service

sudo systemctl status hello-world.service

6. Podman有docker-compose嗎?
#

儘管Podman的指令跟Docker很像,但講到docker-compose就不是那麼一回事了。

Podman得安裝「podman-compose」才能用docker-compose來啟動容器,或者改用Podman的「Pods」來做事,後者有一套類似docker-compose的yaml格式能用。

但很多開發者主流還是Docker呀!他們發表專案的時候只會提供docker-compose範本,整個重寫為Pods太麻煩了,還是用docker-compose吧。

用系統套件管理器安裝 podman-compose,這是個Python封裝的前端。

然後podman-compose指令的用法就跟docker compose一樣了。

cd "/含有docker-compose.yaml的目錄"

sudo podman-compose pull

sudo podman-compose up -d

如果要開機自動啟動,則得安裝 Podlet,讓它依照docker-compose內容轉換為Systemd Unit。轉換過程可能會出錯,得自行調整為Qualdet的語法。

podlet compose docker-compose.yaml

不過,實務上我不太會這樣用指令啟動docker-compose,多半都是透過Portainer網頁界面啟動,如此一來就不用費心去轉換docker-compose了。

7. Podman的網頁管理界面?
#

RHEL系Linux發行版內建多功能的 Cockpit網頁界面

Cockpit是有叫做cockpit-podman的模組啦,但界面很陽春,只能建立Pods,目前還不支援podman-compose。

我覺得還是Portainer功能比較齊全。

所幸,根據 官方文件,Portainer可以連線到Podman的socket,所以網頁界面是可以沿用的:

sudo systemctl enable --now podman.socket

sudo podman run -d \
-p 9443:9443 \
--name portainer \
--restart=always \
--privileged \
-v /run/podman/podman.sock:/var/run/docker.sock \
-v portainer_data:/data portainer/portainer-ce:2.23.0

不過Docker的socket跟Podman不一樣,Portainer的備份功能又僅限同一部機器復原,不能用Backup匯出舊有Portainer資料,所以得手動遷移舊有的Stacks (docker-compose)。

之後就能在Portainer頁面使用docker-compose啟動容器了。

上面提過Podman容器不會在開機後自動啟動,Portainer對此也無能為力。它能夠啟動與停止Podman容器,但是要讓Podman容器開機自動啟動,你就得自己設定Quadlet。

所以,我折衷的作法就是給Portainer容器設定開機自動啟動,再從Portainer的界面去手動啟動容器。

podlet --file .  --install --description "Portainer" podman run -d \
-p 9443:9443 \
--name portainer \
--restart=always \
--privileged \
-v /run/podman/podman.sock:/var/run/docker.sock \
-v portainer_data:/data portainer/portainer-ce:2.23.0

sudo mv portainer.container /etc/containers/systemd/

sudo systemctl daemon-reload

sudo systemctl enable --now portainer.service

8. Docker轉Podman後服務都正常嘛?
#

至少大部分服務都正常執行,Nvidia Container Tooklit也能夠讓Podman跑CUDA。

僅ReDroid因為架構特殊,需要自訂binfderfs的核心所以比較難處理。此問題與Podman無關,而是Rocky Linux核心本身的問題。

最大的問題還是Podman本身與Docker做事的方法本就不太一樣,或許Portainer還能保持一點相容性,但若要善用Podman的潛力,就得將服務模式調整為Pods的工作方式。

可是這樣要架服務就滿麻煩的了,以後就不能直接抄開發者給的docker-compose啦。

相關文章

Cockpit教學:用網頁瀏覽器管理QEMU/KVM虛擬機,替代Virt Manager
分類   Linux系統 Self-hosting自架
標籤   Libvirt PCI Passthrough GPU Passthrough QEMU-KVM Podman Docker Linux
開源友好的主機供應商「PikaPods」,一鍵架設Docker雲端服務
分類   Linux系統 Self-hosting自架
標籤   Nextcloud Docker Podman
用網頁圖形化界面管理Docker容器 ~ Portainer安裝教學,一鍵啟動docker-compose、管理image
分類   Linux系統 Self-hosting自架
標籤   Docker Podman

留言板

此處提供二種留言板。點選按鈕,選擇您覺得方便的留言板。要討論程式碼請用Giscus,匿名討論請用Disqus。

這是Giscus留言板,需要Github帳號才能留言。支援markdown語法,若要上傳圖片請貼Imgur或Postimages。您的留言會在Github Discussions向所有人公開。

這是Disqus留言板,您可能會看到Disqus強制投放的廣告。為防止垃圾內容,有時留言可能會被系統判定需審核,導致延遲顯示,請見諒。若要上傳圖片請善用圖床網站。