OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 129

Distrobox image and container lifecycles

Use complete commands to manage creation, entry, upgrades, deletion, and temporary userspaces.

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 have been checked against the official Distrobox 1.8.2.5 scripts. Image tags and distribution package names are examples; before using them, confirm that the image is still supported, its repositories are available, and the versions match your system. The examples have not been tested by running them.

This article is a handbook-style reference for everyday Distrobox use, covering image pulls, container creation, entering and exiting containers, lifecycle management, and special container modes. All commands use the full parameter forms; the original Chinese notes explain each flag.

1. Image management#

Where images come from

Distrobox does not maintain its own operating system images. It directly uses container images compatible with the OCI (Open Container Initiative) standard. Sources include:

Image source Example Description
Docker Hub ubuntu:24.04, archlinux:latest Default source; no registry needs to be specified
Quay.io quay.io/toolbx/ubuntu-toolbox:24.04 Images built specifically for the Toolbx family
GitHub Container Registry ghcr.io/ublue-os/arch-toolbox:latest Maintained by communities such as Universal Blue
Fedora Registry registry.fedoraproject.org/fedora:40 Official Fedora images

When --image is omitted, Distrobox uses the configured default image. It does not infer Ubuntu from --name ubuntu. The name and image are independent parameters. Specify the image explicitly in production; version tags can still be updated, so strict pinning requires an image digest and package repository snapshots.

Pulling images

When creating a container, Distrobox automatically pulls the corresponding image from the registry if it is not available locally:

# 创建容器时自动拉取镜像
distrobox create --name dev-ubuntu --image ubuntu:24.04

# 如果本地已有镜像,跳过拉取;若想强制重新拉取,使用 --pull
distrobox create --name dev-ubuntu --image ubuntu:24.04 --pull

You can also pull the image manually before creating the container:

# 使用 podman 拉取镜像(Distrobox 底层)
podman pull ubuntu:24.04
podman pull registry.fedoraproject.org/fedora:40
podman pull docker.io/archlinux:latest

# 使用 docker 拉取(如果容器后端是 Docker)
docker pull ubuntu:24.04

The risk of the :latest tag :latest is a floating tag: each pull may retrieve a different version. Always pin the version number in production:

  • Recommended: ubuntu:24.04
  • Avoid: ubuntu:latest

Distrobox 1.7.0 automatically appends :latest to images without a tag, so --image ubuntu is equivalent to --image ubuntu:latest and is likewise not recommended.

Viewing downloaded images

# 查看本地已有镜像(podman 方式)
podman images

# 查看本地已有镜像(docker 方式)
docker images

# 查看由 Distrobox 管理的容器列表(间接反映已用镜像)
distrobox list --verbose

distrobox list does not list images on their own; it lists containers created from those images. To manage the images themselves, use the underlying container engine's commands (podman images / docker images).


2. Container lifecycle (core commands)#

These are the five groups of core commands you will use every day. Mastering them covers 90% of routine operations.

distrobox create: create a container

Full syntax:

distrobox create --name <名称> --image <镜像> [可选参数...]

Parameters you should specify explicitly

Flag Long form Description
-n --name The container name, which must be unique. Use a human-readable name (such as dev-ubuntu or gpu-box), unlike Docker's hexadecimal hash
-i --image OCI image address. This can be a fully qualified name such as ubuntu:24.04 or registry.fedoraproject.org/fedora:40

Common optional parameters

Flag Long form Description Example
-H --home Assign a separate home directory to the container to isolate dotfiles --home ~/.distrobox/dev-home
-ap --additional-packages A list of additional packages to install during initial setup --additional-packages "build-essential curl git"
-Y --yes Skip all interactive confirmations and create immediately --yes
-p --pull Force a fresh pull from the registry, even if the image already exists locally --pull
--init Enable systemd / an init system inside the container --init
--volume Mount an additional directory inside the container; may be used multiple times --volume /mnt/data:/data
-r --root Create a rootful container instead of using rootless mode --root
--additional-flags Additional flags passed to the underlying container engine (podman/docker) --additional-flags "--dns 192.0.2.53" (documentation example address; replace it before use)
--unshare-netns Do not share the host's network namespace; give the container its own network stack --unshare-netns
--unshare-ipc Do not share the host's IPC namespace --unshare-ipc
--unshare-process Do not share the host's PID namespace --unshare-process
--unshare-devsys Do not export /dev and /sys from the host into the container --unshare-devsys

Practical examples

# 1. 最简创建:名称 + 镜像
distrobox create --name mybox --image fedora:latest

# 2. 指定独立的 Home 目录(dotfiles 与宿主隔离)
distrobox create --name dev --image archlinux:latest \
  --home ~/.distrobox/dev-home

# 3. 创建时预装开发工具链
distrobox create --name gpu-box --image ubuntu:22.04 \
  --additional-packages "build-essential curl git vim"

# 4. 非交互式创建(脚本/自动化场景)
distrobox create --name test --image alpine:latest --yes

# 5. 创建带 systemd 的容器(运行 systemd 服务)
distrobox create --name server-box --image ubuntu:24.04 --init --additional-packages "systemd"

# 6. 挂载额外卷
distrobox create --name data-box --image ubuntu:24.04 \
  --volume /mnt/nas:/nas \
  --volume /mnt/scratch:/scratch

# 7. 从指定 registry 创建
distrobox create --name fedora-toolbox --image registry.fedoraproject.org/fedora-toolbox:40

# 8. 创建 rootful 容器(需要宿主机 root 权限)
distrobox create --name root-box --image ubuntu:24.04 --root

About --additional-packages Distrobox automatically detects the distribution's package manager inside the container (apt/dnf/pacman/apk/zypper, etc.) and uses it to install the packages you specify. You generally do not need to install these basic tools manually afterward, but create itself only creates the container. Package installation happens during the first enter/initialization process; assemble's start/export operations may also trigger initialization.

--root vs rootless --root makes the backend use host root privileges and separate rootful container storage. The guest's login user is a separate setting. Use the default rootless mode for the vast majority of everyday tasks (omit --root); it matches the host user's privileges and is safer.


distrobox enter: enter a container

Full syntax:

distrobox enter <名称> [-- 命令 [参数...]]

Parameter descriptions

Flag Long form Description
-n --name Name of the container to enter
-r --root Select a container from the rootful backend; this does not switch the guest user to root
--no-workdir Do not automatically switch to the host's current directory (by default, entering a container automatically changes to the container path corresponding to the host's current path)
-- (Separator) Everything after the separator is treated as a single command to execute. Exit the container when it finishes, without opening an interactive shell

Practical examples

# 1. 进入容器的交互式 shell
distrobox enter mybox

# 2. 普通容器内以 root 身份运行一个命令
distrobox enter mybox -- sudo whoami
# 若容器由 rootful 后端创建,访问时再选择 --root
# distrobox enter --root root-box

# 3. 在容器中执行单条命令后退出
distrobox enter mybox -- whoami

# 4. 在容器中执行带参数的命令
distrobox enter mybox -- python3 --version

# 5. 在容器中执行 shell 组合命令
distrobox enter mybox -- bash -c "sudo apt update && sudo apt upgrade -y"

# 6. 在容器中启动一个服务/应用
distrobox enter mybox -- code --new-window

# 7. 从容器中运行带管道和重定向的复杂命令
distrobox enter mybox -- bash -c "find /usr -name '*.so' | wc -l"

Checking whether you are inside a container After entering a container, you can check the following environment variables:

  • $CONTAINER_ID: contains the container name (such as mybox); empty outside the container
  • $DISTROBOX_ENTER_PATH: the host's working directory path when you entered the container
  • The output of hostname includes the container name

Use echo $CONTAINER_ID to quickly check whether you are currently inside a Distrobox container.

When to use --no-workdir By default, distrobox enter tries to map the host's current $PWD to the same path inside the container and automatically cd there. This is very convenient in the following scenario:

cd ~/my-project   # 在宿主上
distrobox enter dev   # 进入容器后自动进入 ~/my-project

If that path does not exist inside the container, however (for example, a custom host path), Distrobox falls back to $HOME. Use --no-workdir to skip this automatic mapping behavior.


distrobox list: view containers

# 基本列表
distrobox list

# 调试输出(verbose 不等于更多业务列)
distrobox list --verbose

Output columns

Column name Meaning
ID Short hexadecimal representation of the underlying engine's container ID
NAME Container name (the --name specified at creation; human-readable)
STATUS Runtime status: Up (running) or Exited (stopped)
IMAGE OCI image address used at creation

Example output:

ID           | NAME                 | STATUS                         | IMAGE
123abc       | dev-ubuntu           | Up 2 hours                     | ubuntu:24.04
456def       | gpu-box              | Exited (0) 3 days ago          | nvidia/cuda:12.4.1-devel-ubuntu22.04

For everyday operations, the container name is sufficient. The short IDs in the list come from the underlying OCI container engine; they are not sequential numbers assigned by Distrobox.


distrobox stop / distrobox rm: stop and remove containers

# 停止指定容器
distrobox stop mybox

# 停止所有容器
distrobox stop --all

# 删除指定容器(必须先停止)
distrobox rm mybox

# 强制删除(可删除运行中的容器,确认已备份)
distrobox rm mybox --force

# 删除所有已停止的容器
distrobox stop --all
distrobox rm --all
Flag Description
--all Supported by both stop and rm; applies only to the selected backend and root mode
--force / -f Force removal (rm); use --yes to skip interactive confirmation

Check your data before removing a container distrobox rm permanently deletes the container and its filesystem changes (excluding the home directory shared through a mount). Before removing it, check:

  • Whether custom configuration inside the container has been backed up
  • Whether important uncommitted data has been moved to the host

The home directory is shared by default, so files under ~ on the host are not lost when a container is removed. If you use a separate --home, however, you are responsible for managing that path; --rm-home deletes qualifying custom home directories, which need separate backups. rm also asks the backend to remove associated anonymous volumes, so check volume data separately.


distrobox upgrade: upgrade containers

# 升级单个容器内的所有软件包
distrobox upgrade mybox

# 升级所有容器
distrobox upgrade --all

What does upgrade actually do? Distrobox automatically detects the distribution inside the container and uses its native package manager to run update + upgrade:

Distribution Equivalent command
Ubuntu / Debian apt update && apt upgrade -y
Fedora dnf upgrade -y
Arch Linux pacman -Syu --noconfirm
Alpine apk update && apk upgrade
openSUSE zypper update -y

The upgrade targets the guest's package database and filesystem; it does not upgrade NixOS through the host's package manager. Package scripts may still access the shared HOME, sockets, network, or host-exec. “Complete isolation” is not a security guarantee.

Flag Description
--all Upgrade all existing containers
--root Upgrade rootful containers

3. Special container modes#

Ephemeral containers (disposable temporary containers)

distrobox-ephemeral creates disposable containers and automatically removes the temporary container when you exit. This does not undo changes to the image cache, shared HOME, volumes, or host.

Full syntax:

distrobox-ephemeral --image <镜像> [可选参数] [-- 命令]

Parameter descriptions

distrobox-ephemeral accepts almost the same parameters as distrobox create (--name, --image, --additional-packages, --home, --root, etc.), with these differences:

  • No need to specify --name (a random name is generated automatically if omitted)
  • After you exit, the container is destroyed automatically; there is no need to run distrobox rm

Practical examples

# 1. 进入临时 Fedora 容器玩耍,exit 后容器消失
distrobox-ephemeral --image fedora:latest

# 2. 运行单个命令,执行完后自动退出并销毁
distrobox-ephemeral --image alpine:latest -- uname -a

# 3. 比较临时用户空间的发行版信息;不是安全沙箱
distrobox-ephemeral --image ubuntu:24.04 -- cat /etc/os-release

# 4. 临时容器中安装并运行一个工具,用完即走
distrobox-ephemeral --image python:3.12-slim \
  --additional-packages "ffmpeg" \
  -- python3 -c "import sys; print(sys.version)"

# 5. 在临时容器中 clone 仓库并做一次性编译测试
distrobox-ephemeral --name build-test --image ubuntu:24.04 \
  --additional-packages "gcc make git" \
  -- bash -c "git clone https://github.com/example/project /tmp/p && cd /tmp/p && make"

Best uses for ephemeral containers

  • Disposable userspace experiments: test only trusted programs; dangerous commands can still affect shared host data
  • One-off builds: fetch the source, compile it, and take the output without leaving build dependencies behind
  • Version comparisons: quickly run the same command on different distributions and compare behavior
  • Tool isolation: temporarily use a tool that is not installed on the host (such as ffmpeg), then discard the container

Every ephemeral container starts fresh from the image, so network download overhead depends on whether --image is already cached locally.


distrobox-host-exec: run host commands from inside a container

This is a special tool: while inside a container, you can use it to run commands on the host.

Full syntax (used inside the container):

distrobox-host-exec <宿主的命令和参数>

Practical examples

# 先从宿主进入容器
distrobox enter mybox

# === 以下命令在容器内部执行 ===

# 1. 在容器内打开宿主上的 Obsidian
distrobox-host-exec flatpak run md.obsidian.Obsidian

# 2. 在容器内查看宿主 systemd 用户服务状态
distrobox-host-exec systemctl --user status pipewire

# 3. 在容器内使用宿主安装的浏览器打开 URL
distrobox-host-exec firefox https://wiki.archlinux.org

# 4. 把容器内的数据通过宿主的工具处理
some-command | distrobox-host-exec wl-copy   # 复制到宿主 Wayland 剪贴板

# 5. 在容器内控制宿主 Flatpak 应用
distrobox-host-exec flatpak list
distrobox-host-exec flatpak run com.visualstudio.code

Why use host-exec? A core principle of Distrobox containers is close integration with the host (sharing HOME, X11/Wayland, D-Bus, and more), but the guest's package database and running services are separate from the host's. To manage the host's Flatpak or systemd, explicitly invoke commands on the host so that you do not mistake guest administration commands for host operations.

distrobox-host-exec provides this "bridge": while working inside a container, you can seamlessly invoke host GUI applications, service management commands, clipboard tools, and more.

Inside the container, it is implemented as a shell script at /usr/bin/distrobox-host-exec (the guest injection path used by the 1.8.2.5 creation process).

host-exec uses host-spawn as a bridge. Commands actually execute on the host, and their privileges and effects on data belong to the host as well. If the guest's working directory is a path such as /run/host/... that does not exist on the host, explicitly choose a directory available on the host rather than misreading ENOENT as a missing program.

Comparison with exporting applications to the host

Method Direction Description
distrobox-host-exec Container → host Invoke host commands from inside a container
distrobox-export (covered in the next article) Container → host Export container applications/binaries to the host desktop

4. Everyday tips#

Quickly enter frequently used containers

Typing distrobox enter mybox every time is a little tedious. Set up a shell alias instead:

# fish shell (~/.config/fish/config.fish)
alias db-dev="distrobox enter dev-ubuntu"
alias db-arch="distrobox enter arch-box"

# bash (~/.bashrc)
alias db-dev="distrobox enter dev-ubuntu"
alias db-arch="distrobox enter arch-box"

You can then enter your development container with the single command db-dev.

Create and enter in one sequence

distrobox create does not enter the container by default, and --yes is not a switch for “do not enter after creation.” To create and then enter, explicitly chain the commands on success:

distrobox create --name newbox --image ubuntu:24.04 && distrobox enter newbox

A successful create only means that the container definition has been established; the first enter starts and initializes it.

Environment variables for detecting whether you are inside a container

The two key environment variables mentioned earlier are especially useful for checking container status in scripts:

# 判断是否在 Distrobox 容器内
if [ -n "$CONTAINER_ID" ]; then
    echo "当前在容器: $CONTAINER_ID"
else
    echo "当前在宿主环境"
fi

This information is particularly handy when customizing your shell prompt:

# 在 ~/.bashrc 或 ~/.config/fish/config.fish 中添加
# bash 版本
if [ -n "$CONTAINER_ID" ]; then
    PS1="📦 [$CONTAINER_ID] \w $ "
fi

# fish 版本
if set -q CONTAINER_ID; and [ -n "$CONTAINER_ID" ]
    function fish_prompt
        echo -n "📦 [$CONTAINER_ID] "(prompt_pwd)" \$ "
    end
end

File sharing and home directory separation

Distrobox shares the host's HOME directory with the container by default. This means:

  • Running ls ~/Documents inside the container shows the files on the host
  • If you git clone into ~/projects/ in the container, the files are also visible back on the host
  • Different containers naturally share files through the HOME directory

Sharing HOME also has a drawback: dotfiles from different distributions can conflict. For example, Arch and Ubuntu may expect different configuration in ~/.bashrc.

The solution is to assign a separate HOME directory to each distribution.

# Arch 容器使用独立的 HOME
distrobox create --name arch-box --image archlinux:latest \
  --home ~/.distrobox/arch-home

# Ubuntu 开发容器使用另一个 HOME
distrobox create --name dev-ubuntu --image ubuntu:24.04 \
  --home ~/.distrobox/ubuntu-dev-home

Separate HOME vs shared HOME: trade-offs

Mode Advantages Disadvantages
Shared HOME (default) Files are shared naturally, with no extra configuration Distribution-specific dotfiles may interfere with one another
Separate HOME (--home) Clean separation of dotfiles; suitable for using multiple distributions side by side Changes HOME's default location; the host's original home is still mounted, so this does not provide file security isolation

Recommended approach: share HOME for your main everyday container and use a separate HOME for special-purpose containers, such as those used to test behavior across distributions.

Custom HOME + --volume: organize configuration and project paths

--home changes the guest's HOME and the default location of its dotfiles, but 1.8.2.5 still mounts the host's original home, which can be identified through DISTROBOX_HOST_HOME. The following volume therefore provides an additional convenient path; it does not reopen the only route to your files or provide security isolation:

distrobox create \
  --name arch \
  --image quay.io/toolbx/arch-toolbox:latest \
  --home ~/distrobox-homes/arch \
  --volume /home/user:/host-home

After entering the container:

  • cd ~ → enter the container's separate ~/distrobox-homes/arch
  • cd /host-home → access the host's actual home directory

Give a project an explicit mount path (this does not mean it is the only directory exposed):

distrobox create \
  --name arch \
  --image quay.io/toolbx/arch-toolbox:latest \
  --home ~/distrobox-homes/arch \
  --volume /home/user/projects:/projects

Explicitly share configuration files (append the following arguments to the create command; the guest destination must be inside the actual custom HOME):

--volume "$HOME/.config/starship.toml:$HOME/distrobox-homes/arch/.config/starship.toml:ro"
--volume "$HOME/.config/fish:$HOME/distrobox-homes/arch/.config/fish:ro"

This lets you keep a separate container home while still using your carefully tuned terminal configuration, reducing configuration conflicts without sacrificing convenient file access.

The equivalent in distrobox.ini (commonly used by NixOS users):

xdg.configFile."distrobox/distrobox.ini".text = ''
  [arch]
  image=quay.io/toolbx/arch-toolbox:latest
  home=~/.local/share/distrobox-homes/arch
  volume=/home/user:/host-home
  volume=/home/user/projects:/projects
'';

The manifest field is volume, which accepts repeated declarations or a space-separated list; it is not additional_volumes or a semicolon-separated list.

Key points to watch

  • --volume is read-write by default, so changes inside the container are reflected on the host. Add :ro for read-only access.
  • With rootless Podman, UID mappings match by default, so reading and writing the home directory generally works without issues.
  • --home determines where $HOME points; --volume determines which additional directories are exposed. They are independent and can be combined.
  • After changing volume in the ini file, run distrobox rm arch and recreate the container for the change to take effect.
  • A plain distrobox rm arch does not delete the separate home directory (~/distrobox-homes/arch); that happens only when you add --rm-home.

Accessing host hardware from inside the container

By default, Distrobox exports the following host resources to the container:

Resource How it is exported Description
GPU (including NVIDIA/AMD) Share visible devices; optionally use --nvidia/CDI for NVIDIA Drivers, libraries, permissions, and hardware support must each be verified
Sound (PulseAudio/PipeWire) Shared socket Play audio inside the container
Display (X11/Wayland) Shared socket GUI application windows display normally
USB devices /dev/bus/usb mount Some USB devices can be accessed directly
D-Bus session bus Shared socket Communicate with host desktop services

These automatic integrations make Distrobox containers feel very close to a "native environment", without the tedious manual --device and --volume mounts typically required by Docker.


Command quick reference#

Task Command
Create a container distrobox create -n <name> -i <image>
Enter a container distrobox enter <name>
Enter and execute a single command distrobox enter <name> -- <command>
List containers distrobox list
Enable debug output distrobox list --verbose
Stop a container distrobox stop <name>
Stop all containers distrobox stop --all
Remove a container distrobox rm <name>
Force removal distrobox rm <name> --force
Upgrade a container distrobox upgrade <name>
Upgrade all containers distrobox upgrade --all
Create a temporary container distrobox-ephemeral -i <image>
Run a command in a temporary container distrobox-ephemeral -i <image> -- <command>
Invoke a host command from inside a container distrobox-host-exec <command>

Coming next#

This article covered the full container lifecycle and everyday operations. The next article, Application export and integration, explains how to export container applications to the host desktop: install VS Code, Firefox, or any GUI tool inside a container, then open it from the host launcher just like a native application.


References & further reading

  1. Distrobox security implications ↗
  2. Distrobox create ↗
  3. Distrobox enter ↗
  4. Distrobox rm ↗
  5. Distrobox ephemeral ↗
  6. Distrobox host-exec ↗
  7. Distrobox list ↗

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 desktop discovery and background-service integration

Handle app/bin export verification and the separate lifecycle of init services independently.