惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
小众软件
小众软件
S
SegmentFault 最新的问题
人人都是产品经理
人人都是产品经理
博客园 - 【当耐特】
博客园 - 三生石上(FineUI控件)
C
Check Point Blog
S
Schneier on Security
Microsoft Azure Blog
Microsoft Azure Blog
N
Netflix TechBlog - Medium
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
罗磊的独立博客
有赞技术团队
有赞技术团队
V
V2EX
Y
Y Combinator Blog
博客园 - 叶小钗
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
F
Fortinet All Blogs
W
WeLiveSecurity
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
The Cloudflare Blog
S
Security @ Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog
MyScale Blog
MyScale Blog
Hugging Face - Blog
Hugging Face - Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
www.infosecurity-magazine.com
www.infosecurity-magazine.com
PCI Perspectives
PCI Perspectives
H
Heimdal Security Blog
Schneier on Security
Schneier on Security
Security Latest
Security Latest
AWS News Blog
AWS News Blog
月光博客
月光博客
Security Archives - TechRepublic
Security Archives - TechRepublic
Recent Announcements
Recent Announcements
Google DeepMind News
Google DeepMind News
博客园 - Franky
Cisco Talos Blog
Cisco Talos Blog
T
Threat Research - Cisco Blogs
M
MIT News - Artificial intelligence
T
Troy Hunt's Blog
N
News and Events Feed by Topic
Cloudbric
Cloudbric
Scott Helme
Scott Helme
云风的 BLOG
云风的 BLOG
Attack and Defense Labs
Attack and Defense Labs

陈陈菌博客

如何在 podman 容器内使用 systemd 在 podman 运行 GUI 应用的经验总结 管理 podman 容器与镜像的导入或导出 用 xdg-dbus-proxy 解决容器的文件选择器的问题 解决 VSCodium 或 Code-Server 无法安装 GitHub Copilot 问题 不可变发行版 Fedora Silverblue 的体验记录 解决 apt 或 dnf 无法 tab 补全的问题 对 (MPA) 多页面切换实现丝滑动画的探索 让服务在非 Root 权限下使用 80 或 443 端口 AppImage 应用打包快速上手 Flatpak 使用和应用打包快速上手 如何用 webSocket 实现一个实时聊天应用 Linux 内核编译 | 快速上手 | deb 使用 debootstrap 构建 Debian 系根文件系统 高度可定制的 KDE 窗口装饰器 klassy 有关 docker、podman、nspawn、bwrap 的 Linux 容器图形性能测试 创建任意 Linux 容器并支持 GUI 程序 (Docker) 文件同步工具 rsync 的使用 玲珑 (Linyaps) 应用打包 RPM 打包指南 | 精简版 PBR 材质的各种贴图类型入门 APU | Stable-Diffusion 使用记录 如何在 Electron 上启用 WebGPU Grub 主题安装与配置 Fcitx5 主题安装与自定义 不使用 Nginx 的网站开发指南 如何自制一个简易的资源监控程序 SQL 常用 CRUD 语法记录 Debian 打包入门,与需要注意的问题 在 fedora 建立一个 Arch 容器 (bwrap) 在 fedora 上建立一个 debian 容器 (bwrap) i3wm | 自制一个极简的屏幕亮度调节器 在 Linux 下启用内存压缩技术 zram 搭建一个本地轻量级聊天 Ai 我又又又重新上线了博客 如何通过命令行管理 wine 容器 (包括 proton) Btrfs 文件系统创建 swap 文件的方法 如何创建适用于 Linux 桌面的程序启动文件 在 Linux 控制 intel CPU 调度的方法 Arch Linux 的基本安装
创建任意 Linux 容器并支持 GUI 程序 (nspawn)
GlumiStudio@ · 2025-07-29 · via 陈陈菌博客

通过 systemd-nspawn 创建 Arch、Debian 等轻量容器环境

2025-07-29 15:11:15

分类: Linux 标签: 容器


在有一段时间里我因为不同发行版环境问题而头疼,无论是开发、还是日常使用。编译时遇到 glibc、各种各样库版本不同等问题,那个发行版有二进制包呀这个发行版没有的。

尝试过 chroot (觉得不太得劲),又去研究 bwrap (据说 flatpak 也在用的方案) 跑了 debian 和 Arch 容器, https://blog.glumi.cn/bwrap-debianhttps://blog.glumi.cn/bwrap-arch 。但因为工具又太过于轻量,用起来比较麻烦。最近又尝试了另一种陌生的方案,也就是 systemd-nspawn

那这又是个什么东西呢,可以简单理解为同时兼顾 chroot 的易用性又有 bwrap 的灵活性且与 systemd 深度集成的容器工具。

它既可以作为轻量级的隔离环境快速启动,满足临时测试需求;又能支撑起完整的系统容器,跑起一整套带服务的发行版环境,可以在上面运行 GUI 程序,且带硬件加速,可共享宿主机接口资源,几乎没有什么性能损失。

安装准备


在开始前,以 Debian 系为例。需要安装 systemd-container 包获得相关工具。

sudo apt install systemd-container

接下来准备一个 rootfs ,(Arch 的话可以使用 pacstrap,这里我就不展开了,当然也可以使用符合 oci 标准的镜像:从 docker 或 podman 导出rootfs镜像来使用 ) 这里以 Debian 为示例,可以使用 debootstrap 来下载一个 debian rootfs

sudo debootstrap --arch amd64 sid /path/to/debian/ https://deb.debian.org/debian

其中 sid 为 unstable,也可以换成 bookworm 等版本代号。amd64 就是相当于 x86_64,可以是其他架构。

快速入门


systemd-nspawn 可以像 chroot 一样简单

其中 -D 代表 --directory 参数简写。

sudo systemd-nspawn -D rootfs

它默认会做一些基础的配置,能够直接使用宿主网络,且以 root 用户为起始。

如果你需要从普通用户启动,你需要提前在容器内做好 useradd 相关操作。

sudo systemd-nspawn -D rootfs  --user=用户名或UID 

容器内使用 sudo 提权也是没问题的,也仅限于容器内的提权,不会涉及到外部权限。

GUI 使用


回到本文标题,让我们跑 GUi 之前。我们可以再挂载以下内容。 参数较多,接下来为了排版直观,我编写一个 run.sh 文件为示例。

#!/bin/bash
container_path=./debian_bookworm
XAUTH=/tmp/container_xauth
DISPLAY=":1"
uid=1000
sudo systemd-nspawn  \
    --directory="$container_path" \
    -E XAUTHORITY="$XAUTH" \
    -E DISPLAY="$DISPLAY"  \
    -E XDG_RUNTIME_DIR="/run/user/$uid" \
    -E LANG="zh_CN.UTF-8" \
    -E PULSE_SERVER="unix:/run/user/$uid/pulse/native" \
    --hostname="Debian12" \
    --property=AppArmorProfile=unconfined \
    --bind="$XAUTH" \
    --bind="/dev/dri"  \
    --bind="/tmp/.X11-unix" \
    --bind="/dev/input"  \
    --bind="/run/user/$uid/pulse" \
    --bind="/run/user/$uid/bus"  \
    --user="$uid" \
    --bind-ro="/etc/resolv.conf"

这里面涉及到很多内容,其中 --bind 为挂载的意思,为了跑起 GUi,我们需要告诉容器需要用到哪个显示器(DISPLAY) 使用 -E DISPLAY="$DISPLAY" 其中 -E 就是传递变量的意思,根据个人情况来写,我这里是 :1

然后挂载 --bind="/tmp/.X11-unix" 让容器与宿主 X11 通信,而一般情况下 x 有个机制默认不允许非本机与 x 进行通信,而容器其实就相当于另一个主机。为了让它们建立连接,需要使用 xhost 去开放权限如:xhost +local: 其中 local 为本地主机的意思 + 为添加白名单 - 为移除。但是一般不推荐这么做(可能导致 X 服务器被未授权访问)。也可以使用了另一种方法。 首先输入:

touch /tmp/container_xauth | xauth nextract - ":1" | xauth -f /tmp/container_xauth nmerge  -

再增加一个 XAUTHORITY 变量指向 /tmp/container_xauth 即可

--hostname="Debian12" :的意思很明了,就是给容器设置一个主机名

--bind="/dev/dri" :将宿主 dri 挂载到容器以实现 GPU 加速

--property=AppArmorProfile=unconfined 如果GPU加速不正常,可能需要

Systemd


如果需要在容器用到 systemd 需要加上 --boot,可以模拟完整系统的启动。

想退出时,可以先按住 ctrl ,再按三次 ] 键退出容器。

需要注意:加上 --boot 参数后,传递的 -E 变量将无效。

音频支持


如果你需要音频,那必须得加入以下参数和 PulseAudio 进行通信:

--bind="/run/user/$uid/pulse"

-E PULSE_SERVER="unix:/run/user/$uid/pulse/native"

输入法


无法在容器使用输入法问题,可以在容器安装 fcitx5 框架,然后加入以下变量解决:

-E XMODIFIERS="@im=fcitx" \
-E QT_IM_MODULE="fcitx" \
-E GTK_IM_MODULE="fcitx" \

有关 /run/user/$uid/


如果想要图方便,可以直接 bind 宿主整个 $XDG_RUNTIME_DIR 能解决不少通信问题

DNS 问题


当你的网络不太正常,也许要手动挂载一下 /etc/resolv.conf , --bind-ro 是只读的

--bind-ro="/etc/resolv.conf"

准备完后,使用 chmod +x run.sh 给以执行权限,就可以跑了。以下为测试效果。

需要各种发行版?也没问题。

GUI 程序占用还不错(测试硬件 Ai9 365 )

有关 docker、podman、bwrap、nspawn 的 Linux 容器图形性能测试:

https://blog.glumi.cn/container_gpu_test

关于更详细教程推荐阅读:

https://wiki.archlinux.org/title/Systemd-nspawn

https://wiki.debian.org/nspawn