OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 131

Distrobox declarative manifests and advanced workflows

Cover assemble, GPUs, multi-container collaboration, and platform-specific practices while distinguishing manifests from service-management contracts.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSDistrobox: userspace, desktop integration, and recoverable environments ↗
About 15 min readStart reading

The command interfaces in this article were checked against the official Distrobox 1.8.2.5 scripts. Image tags and distribution package names are examples; before using them, confirm that the images are still supported, the repositories are available, and your installed version matches your needs. The examples have not been tested by running them.

Scope of This Article: This article covers advanced Distrobox workflows: declarative batch management, running systemd services in init containers, GPU acceleration and hardware passthrough, multi-container collaboration architectures, and special environments such as desktop environments, virtualization, and ChromeOS. It is intended for readers already familiar with basic distrobox-create / distrobox-enter operations.


1. distrobox-assemble: Declarative Container Management#

distrobox-assemble is to Distrobox what Docker Compose is to Docker: it lets you create/destroy containers in batches using an INI-format manifest file. The default manifest path is ./distrobox.ini in the current working directory. Specify a file in the user configuration directory with --file; custom local paths and remote URLs are also supported.

1.1 Manifest Example with All Fields

# ~/.config/distrobox/distrobox.ini

[dev]
image=archlinux:latest
pull=true
init=false
entry=true
start_now=false
additional_packages="base-devel git neovim zsh bat ripgrep"
hostname="arch-dev"
exported_bins="/usr/bin/nvim"
exported_bins="/usr/bin/bat"
exported_bins="/usr/bin/rg"

[server]
image=ubuntu:22.04
pull=true
init=true
entry=false
start_now=false
additional_packages="nginx certbot python3-certbot-nginx postgresql systemd"
init_hooks="systemctl enable nginx && systemctl enable postgresql"
volume="/opt/data:/data"

[llvm-toolchain]
image=registry.fedoraproject.org/fedora:41
pull=false
init=false
additional_packages="clang lldb llvm cmake ninja-build gdb"

[cuda-dev]
image=nvidia/cuda:12.0-devel-ubuntu22.04
pull=false
init=false
nvidia=true
additional_packages="python3 python3-pip cmake"
hostname="cuda-box"

[libvirt-host]
image=registry.opensuse.org/opensuse/distrobox:latest
pull=true
init=true
root=true
unshare_all=true
additional_flags="-p 2222:22"
exported_apps="virt-manager"

1.2 Manifest Field Reference

Type definitions:

  • bool: true or false
  • string: a single-line string, such as home="/home/user/dbox"
  • string_list: multiple space-separated strings, such as additional_packages="htop vim git". Repeated declarations are accumulated automatically:
[ubuntu]
additional_packages="git vim tmux"
additional_packages="htop iftop iotop"   # 自动合并
Field Type Description
image string OCI image address (required)
pull bool Force a pull of the latest image before each create (default: false)
init bool Enable an init system (systemd / OpenRC)
entry bool Automatically generate a desktop entry (application launcher)
root bool Run the container in rootful mode
start_now bool Start the container immediately after creation
replace bool Force replacement of a container with the same name
clone string Copy the filesystem state of an existing container
include string Inherit properties from another manifest entry
additional_packages string_list Space-separated additional packages to install
additional_flags string_list Additional flags passed to the underlying container engine
init_hooks string_list Shell commands executed after container initialization (joined with &&)
pre_init_hooks string_list Commands executed before initialization
home string Custom HOME directory path
hostname string Set the container hostname
volume string_list Additional volume mounts (host_path:guest_path)
exported_apps string_list Automatically export desktop applications
exported_bins string_list Automatically export binaries
exported_bins_path string Destination for exported binaries (default: $HOME/.local/bin)
nvidia bool Enable NVIDIA GPU support
unshare_all bool Enable supported unshare options (devices/sysfs, supplementary groups, IPC, network, and processes); does not remove all mounts
unshare_netns bool Unshare only the network namespace
unshare_devsys bool Unshare only /dev
unshare_ipc bool Unshare only the IPC namespace
unshare_process bool Unshare only the PID namespace
unshare_groups bool Do not share the host user's supplementary groups

1.3 Clone and Include Examples

Clone (copy an existing, initialized container):

[ubuntu]
additional_packages="git vim tmux"
image=ubuntu:latest
init=false

[deno_ubuntu]
clone=ubuntu
pre_init_hooks=curl -fsSL https://deno.land/install.sh | sh;

[bun_ubuntu]
clone=ubuntu
pre_init_hooks=curl -fsSL https://bun.sh/install | bash;

The pre-init bootstrap example runs a downloaded script early in guest initialization. Review and pin the upstream script first; do not assume that all tools or the user's HOME are ready. The container being cloned must already be initialized and stopped. Cloning does not merely copy a manifest, nor is it a tool for switching images between distributions. To create an LLVM Fedora environment, create a Fedora container directly without setting clone=dev.

Include (inherit properties from another entry):

[ubuntu]
image=ubuntu:latest
additional_packages="git vim tmux nodejs htop zsh fish"

[ubuntu-nvidia]
include=ubuntu
nvidia=true

include inserts the referenced entry's fields into the current definition, supports recursion, and detects cycles. Duplicate keys are accumulated; this is not the usual “child overrides parent” behavior found in configuration languages. List fields can be merged, but avoid duplicates for single-value fields such as image/bool and inspect the dry-run output.

Custom login shell:

[ubuntu]
image=ubuntu:latest
pre_init_hooks="export SHELL=/bin/bash;"

1.4 assemble Commands

# 从当前目录 ./distrobox.ini 创建全部容器
distrobox assemble create

# 指定自定义 manifest 文件
distrobox assemble create --file ./my-distrobox.ini

# 从远程 URL 拉取 manifest 并创建(v1.8.0+)
distrobox assemble create --file https://example.com/distrobox.ini

# 只创建 manifest 中名为 "dev" 的容器
distrobox assemble create --name dev

# 预览模式:只打印将要执行的操作,不实际执行
distrobox assemble create --dry-run

# 强制替换已存在的同名容器
distrobox assemble create --replace

# 删除 manifest 中定义的全部容器
distrobox assemble rm

# 列出 manifest 中定义的容器及其当前状态
distrobox list

Multiple exported_bins can be specified with the space-separated list or repeated fields supported by the official documentation. Repeated fields make individual entries easier to review. This article does not repeat the unverified claim of a “1.16.x multiple-path bug”:

exported_bins="/usr/bin/typst"
exported_bins="/usr/bin/julia"

Exporting requires the relevant program to exist inside the initialized container. exported_services is not a supported field; manage background services separately.

Version-Controlled Manifests: Putting distrobox.ini in a dotfiles repository and using distrobox assemble create --file lets you recreate the same intended container setup, but image tags, package repositories, and download scripts can change. Remote manifests and hooks are trusted code inputs. Download and review them, pin their versions, then use a local --file.


2. Init Containers: Running systemd Inside a Container#

The --init flag enables a working init system inside the container, allowing you to run long-lived services that need process management, socket activation, or scheduled tasks.

2.1 Supported Init Systems

Init system Typical distributions
systemd Ubuntu, Debian, Fedora, Arch, openSUSE, etc.
OpenRC Alpine Linux

--init runs the guest distribution's init system and enables a separate process namespace; it is more than the lightweight reaper provided by the OCI backend's --init. Base images may not contain systemd/OpenRC, so choose a compatible image and install the relevant packages. Verify PID 1 and unit status after the first initialization completes.

2.2 Using Init Hooks

Commands in --init-hooks run after initialization steps such as package installation and user setup; this does not guarantee that systemd is already running. Join multiple commands with &&:

distrobox create --name dbserver --image ubuntu:22.04 --init \
  --additional-packages "postgresql nginx systemd" \
  --init-hooks "systemctl enable postgresql && systemctl enable nginx"

--pre-init-hooks runs before base package configuration, when additional_packages have not yet been installed. Work involving installed software's configuration files belongs in a later init hook, for example:

distrobox create --name webdev --image fedora:41 --init \
  --additional-packages "httpd php php-fpm mariadb-server systemd" \
  --init-hooks "printf 'ServerName localhost\n' >> /etc/httpd/conf/httpd.conf; systemctl enable httpd mariadb"

2.3 Starting an Init Container Automatically at Host Boot

Use a user-level systemd service to control container startup and shutdown:

# ~/.config/systemd/user/distrobox-dbserver.service
[Unit]
Description=Distrobox Container: dbserver
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/podman start dbserver
ExecStop=/usr/bin/podman stop dbserver
RemainAfterExit=yes

[Install]
WantedBy=default.target
# 启用服务
systemctl --user enable distrobox-dbserver.service
systemctl --user start distrobox-dbserver.service

Limitations of Init Containers

  • Some systemd features, such as PrivateTmp and ProtectSystem, require extra privileges and may fail inside a container
  • systemctl operations require root or --user mode. A rootless --init container can also use guest sudo to manage system services inside the container; a host user unit and a guest system unit operate at different levels
  • Some systemd units that require kernel modules, such as systemd-networkd, usually cannot work inside a container

2.4 Typical Use Cases

Scenario Example
Local web development stack nginx + php-fpm + mariadb, all in one init container
CI simulation environment A GitLab Runner / Jenkins agent inside the container, managed by systemd
Database services PostgreSQL / MySQL as persistent services, with the host connecting through sockets
Message queues Redis / RabbitMQ running inside an init container
Virtualization host libvirt/QEMU managing virtual machines inside the container (see Section 5)

3. GPU Acceleration and Hardware Passthrough#

3.1 NVIDIA GPU

NVIDIA GPU passthrough is Distrobox's most mature GPU acceleration solution. --nvidia attempts to integrate the host driver; CDI is another route, requiring the NVIDIA Container Toolkit to generate a usable CDI configuration.

# 方式一:使用 --nvidia flag(推荐)
distrobox create --name cuda-dev \
  --image nvidia/cuda:12.0-devel-ubuntu22.04 \
  --nvidia \
  --additional-packages "python3 python3-pip cmake"

# 方式二:通过 --additional-flags 手动指定
distrobox create --name ml-workspace \
  --image pytorch/pytorch:2.0-cuda11.7-cudnn8-devel \
  --additional-flags "--device nvidia.com/gpu=all" \
  --additional-packages "jupyter python3-pip"

Verify GPU availability:

# 进入容器后执行
distrobox enter cuda-dev

# NVIDIA 官方工具
nvidia-smi
# 应显示 GPU 型号、驱动版本、CUDA 版本

# OpenGL 验证
glxinfo | grep "OpenGL renderer"
# 应显示 NVIDIA 相关信息

# CUDA 可用性测试
python3 -c "import torch; print(torch.cuda.is_available())"

Verify NVIDIA prerequisites layer by layer: a working host driver, visible container devices, matching userspace driver libraries, and compatible CUDA/framework versions. The CDI example requires configuring toolkit/CDI according to NVIDIA's official documentation first; --nvidia does not universally require the toolkit. A working nvidia-smi does not mean Torch computation has been verified. The Torch test above also requires a compatible PyTorch installation first.

3.2 AMD / Intel GPU

AMD and Intel GPU passthrough is relatively straightforward because the open-source drivers (Mesa) access host devices shared with the container:

# AMD ROCm(AI/ML 计算)
distrobox create --name rocm-dev \
  --image rocm/dev-ubuntu-22.04:latest \
  --additional-flags "--device /dev/kfd --device /dev/dri" \
  --additional-packages "rocm-libs miopen-hip rocblas"

# Intel GPU(QSV 编解码 / OpenCL)
distrobox create --name intel-gpu \
  --image ubuntu:22.04 \
  --additional-flags "--device /dev/dri" \
  --additional-packages "intel-media-va-driver intel-opencl-icd"

Verify the AMD GPU:

# OpenGL
glxinfo | grep "OpenGL renderer"

# ROCm
rocm-smi
# 应显示 AMD GPU 信息

# Vulkan
vulkaninfo | grep "deviceName"

Wayland / X11 Graphics Acceleration: Distrobox automatically shares the host's Wayland socket ($XDG_RUNTIME_DIR/$WAYLAND_DISPLAY) and X11 socket (/tmp/.X11-unix) by default. This socket integration only establishes the display connection; graphics acceleration also requires guest graphics libraries, device permissions, and driver compatibility. ROCm/oneAPI support especially requires checking the specific hardware.

3.3 GPU Support Overview

GPU vendor Compute acceleration Graphics acceleration Additional configuration
NVIDIA CUDA, cuDNN, TensorRT GLX/EGL (matching host driver libraries) --nvidia or --device nvidia.com/gpu=all
AMD ROCm, HIP, OpenCL Mesa (automatically shared /dev/dri) Device permissions + supported hardware/ROCm version
Intel oneAPI, OpenCL Mesa (automatically shared /dev/dri) Device permissions + compatible oneAPI/OpenCL runtime

4. Multi-Container Collaboration Patterns#

4.1 Default Isolation and Sharing Semantics

Distrobox containers' default behavior provides the foundation for collaboration:

Resource Default behavior Meaning
$HOME Shared (bind mount) All containers see the same home directory, providing built-in file sharing
Network Shares the host network stack Containers communicate directly through localhost
Processes Ordinary containers share PID by default; --init/--unshare-process uses a separate namespace ps aux can see processes on the host and in all containers
Display Shares X11/Wayland sockets GUI applications from any container can display directly on the host desktop
Audio Shares PulseAudio/PipeWire sockets Container applications can play audio directly

4.2 Three Classic Collaboration Patterns

graph TB
    subgraph Host["宿主机 Host OS"]
        HOME["/home/$USER (共享)"]
        DISPLAY["X11/Wayland Display"]
        NET["Host Network Stack"]
        PULSE["PulseAudio / PipeWire"]
    end

    subgraph Pattern1["模式一:Dev 容器 + Service 容器"]
        DEV["dev-box<br/>Arch Linux<br/>neovim / tmux / git"]
        DB["db-box<br/>Ubuntu 22.04 --init<br/>PostgreSQL :5432<br/>Redis :6379"]
        DEV -->|"localhost:5432"| DB
    end

    subgraph Pattern2["模式二:按发行版分工"]
        AUR["aur-box<br/>Arch Linux<br/>yay / AUR packages"]
        APT["deb-box<br/>Ubuntu<br/>apt packages"]
        COPR["rpm-box<br/>Fedora<br/>copr / dnf packages"]
    end

    subgraph Pattern3["模式三:按项目隔离构建环境"]
        PROJ1["proj-alpha<br/>gcc-12 / cmake-3.25"]
        PROJ2["proj-beta<br/>clang-16 / bazel-6"]
        PROJ3["proj-gamma<br/>rustc-1.78 / cargo"]
    end

    HOME --> DEV
    HOME --> DB
    HOME --> AUR
    HOME --> APT
    HOME --> COPR
    HOME --> PROJ1
    HOME --> PROJ2
    HOME --> PROJ3

    DISPLAY --> DEV
    DISPLAY --> AUR
    DISPLAY --> APT
    DISPLAY --> COPR

    NET --> DEV
    NET --> DB
    NET --> AUR
    NET --> APT
    NET --> COPR
    NET --> PROJ1
    NET --> PROJ2
    NET --> PROJ3

    PULSE --> DEV
    PULSE --> AUR

Pattern One: Dev Container + Service Container

Dedicate one init container to background services (databases, caches, message queues) and another to development and editing. The two communicate through localhost:

# 创建服务容器(init,后台运行 PostgreSQL 和 Redis)
distrobox create --name svc-stack --image ubuntu:22.04 --init \
  --additional-packages "postgresql redis-server systemd" \
  --init-hooks "systemctl enable postgresql && systemctl enable redis-server"

# 创建开发容器(轻量,装编辑器/工具链)
distrobox create --name dev-box --image archlinux:latest \
  --additional-packages "neovim git tmux nodejs python"

# 开发时
distrobox enter dev-box
# 在 dev-box 内通过 localhost:5432 连接 svc-stack 的 PostgreSQL
psql -h localhost -U postgres

Pattern Two: Divide Work by Distribution

Different distributions excel in different areas. Create a separate container for each "package-manager ecosystem":

# Arch Linux:AUR 天堂
distrobox create --name aur-box --image archlinux:latest \
  --additional-packages "base-devel git"
# 首次进入后,审查 AUR PKGBUILD,以普通 guest 用户构建 yay/paru

# Ubuntu:Deb 生态与企业软件
distrobox create --name deb-box --image ubuntu:22.04 \
  --additional-packages "software-properties-common"

# Fedora:Copr 与前沿 RPM
distrobox create --name rpm-box --image fedora:41 \
  --additional-packages "dnf-plugins-core"

Pattern Three: Isolate Build Environments by Project

Separating package environments by project can reduce version conflicts, but pinned package versions must actually exist in the selected repositories. The following names and version expressions only illustrate the intent; there is no guarantee that historical repositories still provide these packages:

# 项目 A:GCC 12 + CMake 3.25
distrobox create --name proj-alpha --image ubuntu:22.04 \
  --additional-packages "gcc-12 g++-12 cmake=3.25*"

# 项目 B:Clang 16 + Bazel 6
distrobox create --name proj-beta --image fedora:41 \
  --additional-packages "clang16 lld bazel6"

# 项目 C:Rust nightly
distrobox create --name proj-gamma --image archlinux:latest \
  --additional-packages "rustup"
# 进容器后
rustup default nightly

Sharing Environment Variables Between Containers: Because $HOME is shared, you can put common environment variables in ~/.profile or ~/.bashrc, and every container can read them. Distrobox does not automatically read arbitrary *.conf files as per-container configuration. Set these values explicitly in hooks, actually supported backend arguments, or shell branches based on CONTAINER_ID.


5. Special Scenarios#

5.1 Running a Full Desktop Environment (DE) in Distrobox

You can run the latest GNOME / KDE Plasma / Hyprland inside a container and log in through a display manager session:

# 创建 init 容器(必须有 systemd)
distrobox create --name fedora-rawhide \
  --init \
  --additional-packages "systemd" \
  --image registry.fedoraproject.org/fedora:rawhide
distrobox enter fedora-rawhide

# 安装 GNOME
sudo dnf group install gnome-desktop

# 安装 KDE Plasma
# sudo dnf group install kde

Create a display manager session entry on the host (GNOME shown here):

# /usr/local/share/wayland-sessions/distrobox-gnome.desktop
[Desktop Entry]
Name=GNOME on Wayland (distrobox fedora-rawhide)
Comment=This session logs you into GNOME in a Distrobox container
Exec=/usr/local/bin/distrobox-enter -n fedora-rawhide -- /usr/bin/gnome-session
Type=Application
DesktopNames=GNOME
X-GDM-SessionRegisters=true

Do not fix desktop sessions by recursively running chown on /tmp/.X11-unix; this shared directory is managed by the host X server. Check DISPLAY, XAUTHORITY, actual socket permissions, and display manager logs, and prioritize correct authorization from the host session. Replace the distrobox-enter path in the entry above with the result of command -v distrobox-enter on your machine; on NixOS, declarative configuration supplies the path.

Experimental Support: Running a full DE inside a container is experimental. Some DE components, such as Bluetooth, power management, and Wi-Fi panels, depend on host-level dbus or hardware access and may not be available. It is not recommended for critical production environments.

5.2 Running libvirt/QEMU Virtualization in Distrobox

The following libvirt system connection setup requires elevated privileges. First prepare /dev/kvm permissions, guest packages, and services. Other approaches, such as qemu session, do not all require rootful mode; --unshare-all also does not remove all host file sharing:

distrobox create --name libvirtd \
  --root \
  --init \
  --unshare-all \
  --image registry.opensuse.org/opensuse/distrobox:latest \
  --additional-flags "-p 2222:22" \
  --init-hooks "zypper in -y --no-recommends openssh-server \
    patterns-server-kvm_server patterns-server-kvm_tools \
    qemu-arm qemu-ppc qemu-s390x qemu-extra && \
    systemctl enable sshd.service && \
    systemctl enable virtqemud.socket virtnetworkd.socket \
      virtstoraged.socket virtnodedevd.socket && \
    usermod -aG libvirt \$USER" \
  --additional-packages "virt-manager"

# 导出 virt-manager 到宿主机应用菜单
distrobox enter --root libvirtd -- distrobox-export --app virt-manager

The corresponding assemble manifest:

[libvirt]
image=registry.opensuse.org/opensuse/distrobox:latest
pull=true
init=true
root=true
unshare_all=true
additional_flags="-p 2222:22"
exported_apps="virt-manager"

qemu:///session vs qemu:///system: Inside a rootful container, qemu:///system may encounter a /dev/ptmx conflict (Issue # 1129). If this occurs, using the qemu:///session level usually works around it.

5.3 Steam Deck / SteamOS

SteamOS has a read-only root filesystem (with an A/B update mechanism). Distrobox is the preferred approach for installing additional software:

# SteamOS 图形访问依赖实际桌面会话,先检查 DISPLAY/XAUTHORITY
# 不要把无条件 xhost 放入每次读取的配置文件

distrobox create --name arch-extras \
  --image docker.io/archlinux:latest \
  --additional-packages "firefox vlc gimp"

# 导出到宿主应用菜单;Steam Game Mode 另需手动添加非 Steam 游戏入口
distrobox enter arch-extras -- distrobox-export --app firefox

Steam Deck users commonly use Distrobox to install:

  • Desktop applications (Firefox, VLC, LibreOffice)
  • Development tools (VS Code, Go, Rust toolchain)
  • System tools (htop, neofetch, rsync)
  • Emulators (through the RetroArch flatpak or a native installation)

5.4 ChromeOS (Crostini) Environment

In ChromeOS's Linux development environment (Crostini), Distrobox can nest other distributions inside the default Debian container:

# ChromeOS 先启用 Linux 开发环境(设置 > 开发者 > Linux)
# 默认得到 Debian 容器,在其中安装 distrobox
sudo apt update && sudo apt install podman distrobox

# 再套一层 Arch / Ubuntu / Fedora
distrobox create --name arch-on-chromeos --image archlinux:latest
distrobox enter arch-on-chromeos

5.5 immutable OS(Fedora Silverblue / Kinoite / openSUSE MicroOS)

Immutable distributions are an ideal companion for Distrobox:

# 在 Silverblue 上无需 rpm-ostree layer,直接用容器
distrobox create --name toolbox \
  --image registry.fedoraproject.org/fedora-toolbox:41 \
  --additional-packages "gcc gcc-c++ make git neovim"

# 日常使用就进容器
distrobox enter toolbox

A typical container layout for immutable OS users:

Container name Image Purpose
toolbox fedora-toolbox Everyday CLI tools and compilation
aur archlinux AUR packages (such as paru and yay)
ubuntu-dev ubuntu:22.04 Project builds requiring specific library versions
ml-gpu nvidia/cuda GPU-accelerated AI/ML training

6. Container Lifecycle Automation#

6.1 Automatically Updating All Containers

Use a systemd timer to periodically upgrade packages in every container. First confirm that automatic changes are acceptable and that backups exist. The paths shown are examples for traditional distributions; NixOS uses store/profile paths generated by configuration. Upgrade logs remain in the journal; inspect unit status on failure:

# ~/.config/systemd/user/distrobox-upgrade.service
[Unit]
Description=distrobox-upgrade: Automatic Container Update

[Service]
Type=oneshot
ExecStart=/usr/bin/distrobox-upgrade --all

# ~/.config/systemd/user/distrobox-upgrade.timer
[Unit]
Description=distrobox-upgrade: Weekly Update Trigger

[Timer]
OnCalendar=weekly
Persistent=true

[Install]
WantedBy=timers.target
systemctl --user daemon-reload
systemctl --user enable distrobox-upgrade.timer
systemctl --user start distrobox-upgrade.timer

6.2 The Boundary Between Podman Quadlet and assemble

Podman Quadlet generates systemd units from declarative .container files, but does not automatically reproduce Distrobox's guest initialization, mounts, or exports. Setting Exec=distrobox-init alone does not produce an equivalent Distrobox environment. The following is a separate, ordinary Podman development container example. Create the projects directory first, and check which Quadlet fields your installed Podman version supports:

# ~/.config/containers/systemd/plain-dev.container
[Container]
Image=docker.io/library/alpine:latest
ContainerName=plain-dev
Volume=%h/projects:/projects
WorkingDir=/projects
Exec=sleep infinity

[Service]
Restart=on-failure

[Install]
WantedBy=default.target

Do not mount the host Podman graphroot ~/.local/share/containers/storage as a guest development directory; this could corrupt the host's container storage. Quadlet-generated units are managed by systemd after daemon-reload. Follow the official documentation for startup and log inspection.

assemble or Quadlets?

  • assemble: designed specifically for Distrobox; automatically handles HOME sharing, display forwarding, package installation, and exports, reducing duplicate configuration
  • Quadlet: Podman's native solution, with finer-grained control; achieving the Distrobox experience requires implementing its full contract yourself

Key Takeaways#

What You Should Understand

  • The full field set of a distrobox.ini manifest and the assemble create/rm 与 distrobox list commands
  • The lifecycle of --init containers, init hook timing, and integration with systemd services
  • The differences between NVIDIA / AMD / Intel GPU passthrough approaches and how to verify them
  • Three multi-container collaboration patterns (Dev+Service / by distribution / per-project isolation)
  • Basic commands for special environments such as desktop environments, libvirt, Steam Deck / ChromeOS / immutable OS


References & further reading

  1. Distrobox security implications ↗
  2. Distrobox create ↗
  3. Distrobox enter ↗
  4. Distrobox assemble ↗
  5. Podman Quadlet ↗
  6. NVIDIA CDI ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

Distrobox: userspace, desktop integration, and recoverable environments

  1. 01Distrobox fundamentals: userspace and host integration
  2. 02Distrobox installation and backend configuration
  3. 03Distrobox image and container lifecycles
  4. 04What does Distrobox actually export?
  5. 05Distrobox desktop discovery and background-service integration
  6. 06Distrobox declarative manifests and advanced workflows
  7. 07Distrobox on NixOS: package environments and host paths
  8. 08Distrobox backups: images, package lists, and shared data
  9. 09Distrobox internals: packages, configuration, and command resolution
CONTINUE READING / NEXT ARTICLEDistrobox on NixOS: package environments and host paths

Configure a rootless backend on a declarative host and diagnose boundaries between Nix profiles, graphics, and traditional userspaces.