快轉到主要內容

我全都要!Distrobox使用教學,透過容器安裝其他Linux發行版的套件

· 民國114年乙巳年
·
切換繁體/簡體
分類   Linux系統 虛擬機與容器技術
標籤   Distrobox Podman Docker
目錄

本文讓Ivon為您解說如何使用「Distrobox」建立容器,安裝其他Linux發行版的套件,文末附上更多實際應用例子。

Linux的容器系統,最常見的有Docker和Podman,一般用途都是來開發軟體或者跑服務吧。容器的設計,使得不同Linux發行版要跑起服務的成本低了許多。

既然容器具有跨發行版的特性,能不能進一步利用容器的特性,使用特定發行版的軟體呢?有沒有可能…在Ubuntu用pacman和DNF裝軟體又不跟系統的套件管理器衝突呢?

這正是「Distrobox」的理念。

Distrobox是由Luca Di Maio開發的程式,利用容器技術,能夠在一個Linux系統安裝其他發行版的套件,不管你想要APT、DNF、Yum、Pacman、Zypper、XBPS、Portage都難不倒它。更棒的是,不只純文字工具,連圖形應用程式都能裝來用,甚至能跑桌面環境!

其實,Distrobox就是Podman/Docker的前端啦,技術上來說不需要裝這個也能靠打指令達到一樣效果。不過Distrobox簡化了打指令建立容器的過程,只要幾行指令,便可快速建立特定Linux發行版的容器,存取該發行版的套件管理員。用Distrobox建立Linux容器的話較易於管理、備份、升級。

現在,SteamOS和openSUSE MicroOS已經內建Distrobox,作為immutable系統的軟體補充來源。類似Distrobox的軟體尚有Fedora Silverblue內建的「Container Toolbox」。

1. 為什麼你會需要Distrobox
#

我需要那個酷東西

您需要的套件發行版尚未提供,不想拆deb、rpm包硬裝,更不想手動編譯軟體,且其他發行版有提供該套件的場合。

譬如,Ubuntu安裝Distrobox,建立Arch Linux的容器後,你就可以從包山包海的AUR安裝軟體,還可以把它加到桌面,像原生應用程式一樣啟動。

或者,你有一個特定版本的軟體,需要特定依賴系統版本才能啟動。

無需擔心弄壞宿主機系統!Distrobox不會把其他發行版的套件直接往您的系統塞,而是安裝到容器內部,需要的時候再拿二進位檔出來用即可。

還有,對於Debian Stable這類套件版本較舊的Linux發行版而言,Distrobox能夠裝到其他發行版提供的最新版軟體並加以利用,好比GCC,不用手動抓原始碼編譯。

就算你真的需要編譯軟體,也可以在容器裡面編譯測試,而不用怕弄壞宿主系統,跟用Docker開發軟體的原理是一樣的。


我的系統會咬我

Distrobox適合SteamOS (Steam Deck)、Fedora Silverblue、openSUSE MicroOS、VanillaOS、EndlessOS這類「immutable」的Linux發行版使用,這些發行版不會讓使用者動系統目錄;就算動了系統目錄一更新就會被覆蓋,所以得依賴容器技術來安裝軟體。除使用Flatpak外,缺少的套件可以從Distrobox的容器補充。

或者我們可以想像力更豐富一些:在Microsoft Windows的WSL子系統裝DistroBox,這樣就不用開一堆複雜的WSL容器了。


低成本的distro-hopping

有人戲稱Distrobox為「Linux Subsystem for Linux」,寫作LSW,因為概念跟Microsoft的WSL (Windows Subsystem for Linux) 很像。也有人認為,Distrobox是一種免虛擬機、最快速distro-hopping的一種方式。

根據開發者的表格,Distrobox不需要特製映像檔,支援使用現有的Linux發行版映像檔,例如AlmaLinux、AmazonLinux、Alpine Linux、Arch Linux、CentOS、Debian、deepin、EndlessOS、Fedora Silverblue、Fedora、Gentoo、Manjaro、NixOS、openSUSE、SUSE Linux、Orcale Linux、SteamOS、RHEL、Rocky Linux 、Ubuntu、Void Linux等等。

你還在distro-hopping?所有Linux發行版我全都要 ~ 下圖為Distrobox作者示範的圖片。

當然容器環境還是跟實體機的功能差很多啦!不能這樣類比。


使用Distrobox前的考量

Distrobox解決的是有distro-hopping經驗的Linux使用者會在意的問題。使用者必須知道如何調整workflow,懂得用容器工作。

使用Distrobox可以一定程度上削減宿主機的需求,再也不必為了跑特定發行版的程式而換系統。除了開發用途,Distrobox將其他發行版的圖形程式幹來用,但只將必要檔案暴露給宿主機,並與宿主機桌面環境整合的特性,使其成為第三方軟體的一個不錯補充來源。

安全性方面,值得注意的是,雖然是容器,但Distrobox建立的容器預設可以存取家目錄、USB裝置、X伺服器/Wayland、SSH設定檔、系統日誌等,因此不算完全隔離的檔案系統。

至少跟Flatpak相比,Distrobox容器並沒有明確的權限控管。它預設就是在目前的家目錄進入容器,僅容器本身的資料用docker volume另外儲存。

Distrobox可以選擇Docker或Podman當其後端,其中Podman支援rootless mode,適合無法變更系統檔案的發行版使用,整體限縮的權限也會較多。

2. 安裝Distrobox
#

使用Distrobox前要先在系統安裝Podman或Docker當做後端,二者可以共存。部份Linux發行版在安裝Distrobox的時候會自動選取Podman當作後端,因其daemonless的特性。

我們可以透過~/.config/distrobox/distrobox.conf設定檔指定要使用的後端。

使用Docker當後端
#

如果您有sudo權限,就用系統套件管理員安裝Distrobox。

  1. 請先安裝Docker,並啟動對應的系統服務。
sudo systemctl start docker
  1. 再來是Distrobox,許多發行版已收錄該套件。但請注意,有的發行版套件會強制拉取Podman當後端,而非使用Docker。若想強制用Docker的話請改用指令稿安裝。
# Debian/Ubuntu
sudo apt install distrobox

# Fedora
sudo dnf install distrobox

# Arch/Manjaro
sudo pacman -S distrobox

# openSUSE
sudo zypper install distrobox
  1. 你也可以用下載作者指令稿的方式安裝Distrobox:
# 安裝到~/.local
curl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sh -s -- --prefix ~/.local

# 將Distrobox加入到PATH
echo "PATH=$PATH:$HOME/.local/bin" >> ~/.bashrc

使用Podman當後端
#

如果您無法變更系統檔案,或是想要更安全的環境,使用rootless mode來安裝Distrobox。

  1. 如果要這麼做,請先以rootless模式安裝Podman

  2. 再用指令稿安裝Distrobox:

curl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sh -s -- --next --prefix ~/.local
  1. 將以下路徑加入到~/.bashrc
# Podman和Distrobox的路徑
PATH=$PATH:$HOME/.local/podman/bin:$HOME/.local/bin

# 允許所有應用程式顯示在螢幕上(需安裝xhost)
xhost +si:localuser:$USER

3. 用Distrobox建立容器
#

一切指令以Distrobox開發者文件為主。

預設distrobox create建立的是持續性Linux容器,意即建立的容器在退出shell後仍會存在系統。(如果指令顯示找不到,請嘗試把指令連在一起,如distrobox-create

直接打distrobox create不加任何參數,預設是建立一個最新版Fedora的容器。

  1. 下面是建立Debian 13的容器的最簡單語法。--image後面跟Docker指令寫法一樣,用debian:13指定要拉取的映像檔版本。
distrobox create --name debian13 --image debian:13

可以用的旗標
#

讓我們看一些重要的旗標(flags)。這些旗標可以疊加,為方便表示旗標我寫在最後面。

  1. Distrobox本身可以跑GUI程式。如果需要顯示卡加速,Intel/AMD顯示卡的用戶不需要特別裝什麼,但Nvidia用戶就有難了,除了Linux宿主機本身一定要裝Nvidia專有驅動外,建立Distrobox容器記得還要加上--nvidia旗標,容器裡面的程式才能使用宿主機的Nvidia顯示卡:
distrobox create --name debian13 \
--image debian:13 \
--nvidia

或者,有安裝Nvidia Container Toolkit的話,用這個比較好:

# Docker後端
distrobox create --name debian13 \
--additional-flags "--gpus all --device=nvidia.com/gpu=all" \
--image debian:13

# Podman後端
distrobox create --name debian13 \
--additional-flags "--device nvidia.com/gpu=all --security-opt=label=disable" \
--image debian:13
  1. Distrobox建立的容器預設是可以存取您家目錄下的所有檔案的,您可以用--home指定專門的家目錄來存放容器產生的檔案,防止設定檔污染。一個觀念:除非在建立容器的時候有專門新增家目錄的路徑,否則容器內的程式會直接讀取使用者的家目錄,設定檔也是直接從宿主機讀取。
distrobox create --name debian13 \
--image debian:13  \
--home ~/distrobox/debian13
  1. 預設Distrobox建立的容器指令權限與目前您的使用者權限相同。如果您真的需要賦予Distrobox容器root權限,那就加上--root,不要使用sudo distrobox
distrobox create --name debian13 \
--image debian:13 \
--root
  1. 我們還可以給容器添加環境變數:
distrobox create --name debian13 \
--image debian:13 \
--additional-flags "--env EDITOR=vim"
  1. 或是設定預先要安裝的套件,在初始化容器映像檔的時候執行。
distrobox create --name debian13 \
--image debian:13 \
--additional-packages "git tmux vim"
  1. 或是掛載Docker volume:
distrobox create --name debian13 \
--image debian:13 \
--volume /opt/my-dir:/usr/local/my-dir:rw
  1. 或是設定不要跟宿主機用一樣的網路IP:
distrobox create --name debian13 \
--image debian:13 \
--unshare-netns
  1. Distrobox內部可以使用init系統,包含systemd、OpenRC。例如加上--init讓容器預先安裝Systemd,便於控制容器內的服務。
distrobox create --name debian13 \
--image debian:13 \
--init \
--additional-packages "systemd libpam-systemd"
  1. 還可以利用hook修改檔案,讓容器以proxy連線:
# 指定容器的代理
proxy=http://my_proxy.domain.example:3128

#設定容器初始化執行指令,替換掉apt套件庫
t="echo 'Acquire::http::Proxy \\\""${proxy}"\\\";' > /etc/apt/apt.conf.d/proxy.conf; echo 'Acquire::https::Proxy \\\""${proxy}"\\\";' >> /etc/apt/apt.conf.d/proxy.conf;"
http_proxy="${proxy}"

# 建立Debian容器,把上面的內容加入容器初始化的過程(--pre-init-hooks)
distrobox create --image debian:13 \
--name debian13 \
--pre-init-hooks "${t}"

建立Debian容器的範例
#

  1. 這裡我建立一個Debian 13的容器,設定自訂家目錄路徑
distrobox create --name debian13 \
--image debian:13 \
--home ~/distrobox/debian13
  1. 按Enter建立容器,Distrobox會拉取映像檔。輸入distrobox enter debian13進入Debian的終端機,等待套件安裝完成。

  2. 接著就能使用APT指令安裝套件了,容器裡的sudo需要設定密碼。

  3. 如果你要登入容器後執行特定指令,請編輯容器家目錄下的.bashrc。這也是為何我要把容器家目錄跟宿主機家目錄分開的緣故。

  4. 欲登出容器請打exit,重新登入請打distrobox enter debian13

登出後容器仍未停止,需輸入distrobox stop <容器名稱>完全停止容器。

要完全移除容器,輸入distrobox rm <容器名稱>

順帶一提,Distrobox的容器也可以用docker相關的指令來管理。

4. 建立Distrobox程式捷徑
#

distrobox-export指令可為容器裡面的應用程式建立捷徑,例如讓Debian的Firefox顯示在桌面環境的應用程式列表。

另一方面,distrobox generate-entry則是建立快捷啟動「Distrobox容器終端機」的捷徑。

建立單一應用程式捷徑

要執行容器裡面的圖形應用程式,從終端機啟動:

firefox-esr

啟動的應用程式應會自動啟用硬體加速,並且跟著系統主題變化。

不過語言就得自行設定。

sudo apt install locales
sudo locale-gen zh_TW.UTF-8
sudo dpkg-reconfigure locales
sudo update-locale LANG="zh_TW.UTF-8" LANGUAGE="zh_TW"

Fcitx5輸入法的話可能會吃不到宿主機的,所以要在容器內自行安裝。


在容器內執行distrobox-export指令建立應用程式捷徑:

# 只匯出應用程式,並帶入啟動引數,建立捷徑
distrobox-export --app firefox-esr --extra-flags "--private-window "

# 匯出二進位檔路徑,並帶入啟動引數,在/home/user/.local/bin建立wrapper以便宿主機其他程式利用(需自行加入PATH)
distrobox-export --bin /usr/bin/firefox-esr --extra-flags "--private-window" --export-path /home/user/.local/bin

隨後您的應用程式列表就會出現容器程式的捷徑了

要收回捷徑,使用以下指令

distrobox-export --app firefox-esr --delete
# 或者
distrobox-export --bin /usr/bin/firefox-esr --export-path /home/user/.local/bin --delete

建立容器的快捷啟動捷徑

  1. 建立捷徑
distrobox generate-entry <容器名稱>
  1. 應用程式列表就會顯示該容器的圖示,點選會打開終端機

  2. 欲收回捷徑:

distrobox generate-entry  <容器名稱> --delete

5. 其他容器使用技巧
#

複製容器

複製容器可將現有的容器疊一層檔案系統上去,快速建立新的一個容器。在需要對該容器新增環境變數、entrypoint、家目錄的時候很有用。

在使用distrobox create指令時,加上--clone旗標,複製現有的debian13,新增一個叫做debian13-dev的新容器

# 停止原始容器
distrobox stop debian13

# 複製的時候需注意:旗標不會繼承,因此要開放Nvidia存取,這裡還是得加上去
distrobox create --clone debian13 \
--nvidia \
--home /home/user/distrobox/debian13-dev

建立用完就丟的容器

distrobox ephemeral 可建立暫時性的容器,此容器在命令完成後就會自動刪除,就像docker run --rm那樣。

語法為在--後面接上要容器執行的指令

distrobox ephemeral --image debian:13 -- cat /etc/os-release

distrobox ephemeral可以沿用distrobox create的旗標,例如掛載Docker volume給容器暫時存取:

distrobox ephemeral --image debian:13 --volume /opt:/opt -- touch /opt/file.txt

批次建立容器

distrobox aseemble透過讀取distrobox.ini檔案,按照裡面內容批次建立或移除容器。有點類似docker compose那樣。

  1. 寫一個distrobox.ini,填入要建立的容器內容
[ubuntu] #容器名字
additional_packages=git vim tmux nodejs
image=ubuntu:24.04
init=false
nvidia=false
pull=true
root=false
replace=true
start_now=false

[archlinux] #容器名字
additional_packages=git vim tmux nodejs
home=/tmp/home
image=archlinux:latest
init=false
start_now=true
init_hooks="touch /init-normal"
nvidia=true
pre_init_hooks="touch /pre-init"
pull=true
root=false
replace=false
volume=/tmp/test:/run/a /tmp/test:/run/b
  1. 建立容器使用此指令
distrobox assemble create --file ./distrobox.ini
  1. 移除容器使用此指令
distrobox assemble rm --file ./distrobox.ini

6. Distrobox設定檔位置
#

Distrobox的設定檔用於定義預設行為,設定檔路徑讀取順序如下:

  • /usr/share/distrobox/distrobox.conf
  • /usr/etc/distrobox/distrobox.conf
  • /etc/distrobox/distrobox.conf
  • ${HOME}/.config/distrobox/distrobox.conf
  • ${HOME}/.distroboxrc

我是以放在~/.config/distrobox/distrobox.conf的為優先,若該檔案不存在請自行新增:

mkdir ~/.config/distrobox

vim ~/.config/distrobox/distrobox.conf

該設定檔可以設定Distrobox的預設行為,例如:

# 自動拉取映像檔
container_always_pull="1"

# 自動在應用程式建立容器的捷徑

container_generate_entry=1
# 設定要使用的後端
container_manager="podman"

# distrobox create指令不加任何旗標,預設使用的發行版映像檔
container_image_default="registry.opensuse.org/opensuse/toolbox:latest"

# 預設容器名稱
container_name_default="test-name-1"

# 預設容器家目錄
container_user_custom_home="$HOME/.local/share/container-home-test"

# 自訂的init hook指令稿
container_init_hook="~/.local/distrobox/a_custom_default_init_hook.sh"

# 自訂的pre init hook指令稿
container_pre_init_hook="~/a_custom_default_pre_init_hook.sh"

# distrobox create指令額外加上的旗標
container_manager_additional_flags="--env-file /path/to/file --custom-flag"
non_interactive="1"
skip_workdir="0"
PATH="$PATH:/path/to/custom/podman"

7. 用圖形化界面管理Distrobox
#

如果您使用Docker當Distrobox後端,則市面上任一Docker的圖形界面都可以用來管理Distrobox所建立的容器,例如Portainer

需要專為Distrobox功能設計的GUI,請嘗試:

8. Distrobox實際應用例子
#

另請參閱
#

相關文章

Podlet:將docker-compose轉成Podman Quadlets,以Systemd管理容器
分類   資訊科技 虛擬機與容器技術
標籤   Systemd Podman Docker
從Docker遷移到Podman,能用Portainer網頁界面管理docker-compose嗎?
分類   Linux系統 Self-hosting自架
標籤   Podman Docker Rocky Linux OS-Tan
Cockpit教學:用網頁瀏覽器管理QEMU/KVM虛擬機,替代Virt Manager
分類   Linux系統 Self-hosting自架
標籤   Libvirt PCI Passthrough GPU Passthrough QEMU-KVM Podman Docker Linux

此處提供二種留言板。點選按鈕,選擇您覺得方便的留言板。

(留言板載入中)這是Giscus留言板,需要Github帳號才能留言。支援Markdown語法,若要上傳圖片請善用外部圖床。您的留言會在Github Discussions向所有人公開。

Click here to edit your comments.

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