拓冰建站拓冰建站
首页 / 资讯中心 / 正文

用 Docker 构建 v86 的 Alpine Linux 9p 镜像:从 Dockerfile 到浏览器启动

虚拟化JIT编译硬件仿真【免费下载链接】v86x86 PC emulator and x86-to-wasm JIT, running in the browser项目地址https://gitcode.com/gh_mirrors/v86/v86点击查看免费下载导读v86 是一款运行在浏览器中的 x86 PC 模拟器与 x86-to-WASM JIT 实现它支持通过 9pPlan 9 文件系统协议把宿主机的文件系统直接挂载给虚拟机中的 Linux 使用。本文以仓库中的 tools/docker/alpine/Readme.md 为主线完整讲解如何用 Docker 生成一个可被 v86 直接引导的 Alpine Linux 9p 根文件系统镜像覆盖 Dockerfile 定制、构建脚本执行、本地 Web 服务器启动以及可选的「预启动状态快照」优化方案让你在浏览器中体验一个可写、可持久化的完整 Linux 环境。一、为什么选择 Alpine 作为 v86 的 9p 根文件系统v86 支持通过 virtio-9p 设备把浏览器端以「扁平文件」形式存放的宿主文件系统挂载为虚拟机的根文件系统。浏览器无法直接读取普通磁盘镜像中的 ext4 等格式因此 v86 需要一种特殊的镜像布局一个fs.json元数据文件加一个按内容寻址content-addressed存储的扁平文件目录而 9p 正是连接这两端的关键协议。Alpine Linux 之所以成为 v86 官方推荐的操作系统候选核心原因有三个体积小巧基础包极少配合linux-virt内核virt是专为虚拟化场景裁剪的发行版内核体积远小于lts整体镜像可以被控制在很小的规模适合在浏览器中快速下载和引导。initramfs 可定制Alpine 的mkinitfs工具允许按需指定base virtio 9p等模块特性把 9p 与 virtio 支持打进 initramfs从而让内核在引导阶段就能挂载 9p 根文件系统。社区仓库默认启用在 Dockerfile 构建过程中可以方便地追加nodejs等额外软件包用于演示或运行脚本。二、Dockerfile 逐段解读内核、包、init 与网络仓库中用于构建 Alpine 9p 镜像的 Dockerfile 位于 tools/docker/alpine/Dockerfile构建基础镜像为docker.io/i386/alpine:3.21.0i386 架构通过环境变量提供两个可定制项环境变量默认值含义KERNELvirt内核 flavorvirt比lts更小更适合虚拟化场景ADDPKGSnodejs额外安装的软件包列表社区仓库community repo默认已启用Dockerfile 的完整内容与作用如下FROM docker.io/i386/alpine:3.21.0 ENV KERNELvirt ENV ADDPKGSnodejs # 安装基础系统、OpenRC 初始化框架、自动登录 getty、网络配置工具、 # 指定 flavor 的 Linux 内核、固件精简版以及额外软件包 RUN apk add openrc alpine-base agetty alpine-conf linux-$KERNEL linux-firmware-none $ADDPKGS # 将 tty1 上的 getty 替换为 root 自动登录的 agetty # 避免在 v86 的浏览器串口/终端中手动输入用户名密码 RUN sed -i s/getty 38400 tty1/agetty --autologin root tty1 linux/ /etc/inittab # 追加一个运行在串口 ttyS0115200 波特率上的自动登录 agetty # v86 侧可通过 serial 设备与该控制台交互 RUN echo ttyS0::respawn:/sbin/agetty --autologin root -s ttyS0 115200 vt100 /etc/inittab RUN echo root: | chpasswd # 设置主机名为 localhost保持与 v86 示例页面的一致 RUN setup-hostname localhost # 生成一个网络初始化脚本 # 先卸载/重载 ne2k-pci 与 virtio-net 网卡驱动应对 v86 中网卡类型变化 # 再同步硬件时钟最后自动配置所有网络接口 RUN echo -e rmmod ne2k-pci modprobe ne2k-pci\nrmmod virtio-net modprobe virtio-net\nhwclock -s\nsetup-interfaces -a -r /root/networking.sh chmod x /root/networking.sh # 写入一个测试脚本供用户在启动后执行 node 验证运行时环境 RUN echo console.log(Hello, world!); /root/hello.js # 按 Alpine 官方 chroot 初始化文档把 OpenRC 服务加入各运行级别 # sysinit: devfs dmesg mdev hwdriversboot: hwclock modules sysctl hostname syslog bootmisc # shutdown 级别killprocs shutdown RUN for i in devfs dmesg mdev hwdrivers; do rc-update add $i sysinit; done RUN for i in hwclock modules sysctl hostname syslog bootmisc; do rc-update add $i boot; done RUN rc-update add killprocs shutdown # 使用 mkinitfs 生成 initramfs显式指定特性 base virtio 9p # 确保引导阶段具备 9p 与 virtio 支持这是 9p 根文件系统能否挂载的关键 RUN mkinitfs -F base virtio 9p $(cat /usr/share/kernel/$KERNEL/kernel.release)关键点说明virtvslts如果你需要更多内核模块可以把KERNEL改为lts代价是 initramfs 与内核体积变大浏览器端下载时间相应增加。agetty --autologin root浏览器中的 v86 没有传统「登录界面」的体验需求自动登录让启动后直接进入 root shell配合ttyS0串口控制台可用 examples/serial.html 等页面直接观察启动日志。mkinitfs -F base virtio 9p这是整个 Dockerfile 中与 9p 根文件系统直接相关的关键一步。initramfs 只有包含 9p 与 virtio 模块内核才能在initrd阶段挂载roothost9p rootfstype9p。三、执行构建build.sh 干了什么在启动好dockerdpodman 亦可后运行仓库内的 tools/docker/alpine/build.sh 即可完成整个构建流程./build.sh该脚本set -euo pipefail按以下步骤工作定义输出路径所有产物输出到仓库根目录下的images/images/alpine-rootfs.tar—— 从容器导出的根文件系统 tar 包images/alpine-rootfs-flat/—— 按内容寻址存储的扁平文件目录images/alpine-fs.json—— 文件系统元数据目录树 每个文件的短哈希文件名。构建镜像docker build . --platform linux/386 --rm --tag i386/alpine-v86其中--platform linux/386保证在非 i386 主机上也能构建出 32 位 x86 容器。创建并导出容器docker create一个临时容器后用docker export将其文件系统导出为 tar 包得到的是不含层历史的完整根文件系统。删除.dockerenvtar 包中的.dockerenv标记文件会让容器内工具产生误导性行为参考 docker-to-linux 项目的已知问题因此用tar --delete显式移除若存在。生成 fs.json调用 tools/fs2json.py--zstd启用 Zstandard 压缩把 tar 包转成 v86 需要的文件系统元数据../../../tools/fs2json.py --zstd --out $OUT_FSJSON $OUT_ROOTFS_TAR生成扁平文件目录调用 tools/copy-to-sha256.py同样带--zstd把 tar 中每个普通文件按sha256 前 10 位 .bin.zst的命名方式散列存放../../../tools/copy-to-sha256.py --zstd $OUT_ROOTFS_TAR $OUT_ROOTFS_FLAT这里的核心思路值得展开v86 不能像虚拟机监控器那样按 inode 直接读取宿主文件系统而是要求所有文件以「内容寻址」方式扁平存放——fs.json记录了完整目录树、权限、属主、符号链接目标以及每个文件对应的短哈希文件名真正的字节内容则按哈希去重后存放在alpine-rootfs-flat/下。相同的文件内容只会存储一份天然具备去重效果配合 zstd 压缩后体积更小浏览器端通过 lib/filesystem.js 与 lib/9p.js 按需取用。关于工具脚本的两个补充事实来自源码tools/fs2json.py 同时支持「目录路径」与「tar 包」两种输入os.path.isfile(path)判断并支持--exclude排除路径其 JSON 结构包含fsroot、version当前为 3、size字段文件节点用 7 元数组表示名称、大小、mtime、mode、uid、gid、目标/子节点/文件名。tools/copy-to-sha256.py 的HASH_LENGTH 10与 fs2json 保持一致且会在文件已存在时跳过Exists, skipped便于增量重建。zstd 压缩依赖 Pythonzstandard模块Python ≥ 3.14 时使用内置的compression.zstd否则脚本会提示pip install zstandard后退出。四、本地启动与浏览器验证构建完成后仓库根目录下的Makefile提供了最简单的静态服务器方式make run其实际执行的是python3 -m http.server 2 /dev/null见 Makefile。然后在浏览器中打开http://localhost:8000/examples/alpine.htmlexamples/alpine.html 是官方配套的 Alpine 演示页面其V86实例配置如下var emulator new V86({ wasm_path: ../build/v86.wasm, memory_size: 512 * 1024 * 1024, vga_memory_size: 8 * 1024 * 1024, screen_container: document.getElementById(screen_container), bios: { url: ../bios/seabios.bin }, vga_bios: { url: ../bios/vgabios.bin }, filesystem: { baseurl: ../images/alpine-rootfs-flat, basefs: ../images/alpine-fs.json, }, autostart: true, bzimage_initrd_from_filesystem: true, cmdline: rw roothost9p rootfstype9p rootflagstransvirtio,cacheloose modulesvirtio_pci tscreliable, //initial_state: { url: ../images/alpine-state.bin.zst }, });配置要点filesystem.baseurl指向扁平文件目录filesystem.basefs指向fs.json二者必须与build.sh的产物一一对应bzimage_initrd_from_filesystem: true表示 bzImage 与 initramfs 都从该 9p 文件系统内读取而不是单独提供bzimage/initrd文件内核命令行roothost9p rootfstype9p rootflagstransvirtio,cacheloose告诉内核通过 virtio transport 以 9p 协议挂载宿主机提供的根文件系统cacheloose使用松散缓存换取性能memory_size与vga_memory_size分别设置 512MB 内存与 8MB 显存。启动后你将得到一个可直接输入命令的 root shell。构建时写入的/root/networking.sh可一键完成网卡驱动重载与接口配置对应 v86 的 ne2k-pci / virtio-net 模拟网卡/root/hello.js则可用node /root/hello.js验证 Node.js 是否可用。五、进阶用 build-state.js 生成启动状态快照首次引导 Linux初始化磁盘、启动 OpenRC、首次运行服务在浏览器中通常需要数十秒。为了优化体验仓库提供了 tools/docker/alpine/build-state.js它直接在 Node.js 中运行一个无头无屏幕V86 实例等待系统启动完成后把内存状态序列化保存为快照下次启动可直接从快照恢复。运行前需要先构建出 v86 的库文件脚本第 9 行明确提示Dont forget to runmake allbefore running this script随后node tools/docker/alpine/build-state.js该脚本的核心逻辑以V86模块build/libv86.mjs创建无头实例内存 512MB内核参数与alpine.html基本一致额外追加了init_on_freeon监听串口输出当串口文本以localhost:~#结尾时判定系统已引导完成依次发送sync; echo 3 /proc/sys/vm/drop_caches刷盘并丢弃页缓存减小快照体积、保证一致性等待 10 秒后调用emulator.save_state()获取状态二进制写入images/alpine-state.bin调用make images/alpine-state.bin.zst生成 zstd 压缩版。生成快照后按 Readme 第 4 步的说明在 examples/alpine.html 中取消initial_state注释或新增initial_state: { url: ../images/alpine-state.bin.zst },即可让浏览器直接恢复到「已引导完成的 Alpine」状态大幅缩短等待时间。快照机制对应的保存/恢复实现见 src/state.js它序列化 CPU、内存、设备等完整虚拟机状态因此能实现毫秒级恢复。六、从文件系统镜像到 9p 挂载的完整数据链路把上面的构建与运行串起来可以得到 v86 Alpine 9p 镜像的完整工作链路构建期build.sh用 Docker 构建 i386 Alpine 容器 →docker export导出根文件系统 tar →fs2json.py生成alpine-fs.json目录树元数据→copy-to-sha256.py生成alpine-rootfs-flat/内容寻址文件仓库。引导期浏览器加载v86.wasm与 BIOSbios/seabios.bin、bios/vgabios.bin→ 按cmdline中的 9p 内核参数v86 的 virtio-9p 设备lib/virtio.js、lib/virtio_net.js 所在设备层把baseurlbasefs描述的宿主文件系统暴露给客户机 → 内核通过 initramfs 内的 9p 模块挂载roothost9p。运行期客户机内的所有读写都通过 9p 协议转发到浏览器侧的扁平文件仓库实现持久化build-state.js则把整个运行状态含已挂载的 9p 根文件系统固化为快照。如果你希望了解 9p 在内核侧的更多配置细节如CONFIG_NET_9P、CONFIG_9P_FS、CONFIG_VIRTIO_PCI等内核选项以及基于 initcpio/mkinitcpio 的自定义 9p 根挂载钩子可以参考仓库中的 docs/linux-9p-image.md文中给出了完整的 9p 内核配置片段与 initramfs hook 脚本示例与本文的 Alpine 方案互为补充。七、常见问题与排查要点docker build 平台不匹配务必保持--platform linux/386与基础镜像i386/alpine一致构建机若非 32 位需要 Docker 的 QEMU 模拟支持binfmt。fs.json 与 flat 目录不配套alpine-fs.json与alpine-rootfs-flat/必须来自同一次构建。若手工重跑脚本注意copy-to-sha256.py会跳过已存在的文件删除旧文件请谨慎操作避免新旧混用。initramfs 缺 9p 模块如果客户机内核报VFS: Unable to mount root fs via 9p请回查 Dockerfile 中mkinitfs -F base virtio 9p是否生效以及KERNEL是否为包含 9p 模块的 flavor。快照不生效确认先执行过make all生成build/libv86.mjs且initial_state的 URL 与build-state.js输出的images/alpine-state.bin.zst路径一致若使用旧版页面还需同步更新cmdline中的内核参数如init_on_freeon。串口无输出确认 Dockerfile 中追加的ttyS0agetty 行存在并使用支持 serial 的页面如examples/serial.html或观察 VGA 屏幕上的 tty1 输出。八、小结通过tools/docker/alpine/下的 Dockerfile、build.sh、build-state.js三个文件即可从零生成一个浏览器可引导、可持久化、支持 9p 根文件系统的 Alpine Linux 环境Dockerfile 负责系统定制与 initramfs 组装build.sh负责把容器文件系统转换为 v86 的fs.json 扁平文件布局build-state.js负责把完整启动状态固化为秒级恢复的快照。整个过程无需手动编译内核开箱即用是体验 v86 文件系统支持docs/filesystem.md最直接的实战路径。赞分享虚拟化JIT编译硬件仿真【免费下载链接】v86x86 PC emulator and x86-to-wasm JIT, running in the browser项目地址https://gitcode.com/gh_mirrors/v86/v86点击查看免费下载相关推荐在 v86 浏览器 x86 虚拟机中运行 Debian XFCE 桌面基于 Docker 的镜像构建与 Raw Disk / 9p 双启动方案在 v86 浏览器 x86 虚拟机中运行 Debian XFCE 桌面基于 Docker 的镜像构建与 Raw Disk / 9p 双启动方案 本指南围绕仓库虚拟化JIT编译硬件仿真v86 9p 文件系统实战构建可挂载 9p 根文件系统的 Linux 镜像v86 9p 文件系统实战构建可挂载 9p 根文件系统的 Linux 镜像 v86 是一个运行在浏览器中的 x86 模拟器它通过 virtio 传输层实现了虚拟化JIT编译硬件仿真Alpine Linux Docker 镜像构建终极指南从源代码到镜像的完整流程揭秘Alpine Linux Docker 镜像构建终极指南从源代码到镜像的完整流程揭秘 Alpine Linux Docker 镜像以其极致的轻量化和高效性在容云原生运维上一篇curl-to-go核心功能解析深入理解数据、头部和认证的转换原理下一篇如何用Mihon打造终极Android漫画阅读体验从本地管理到跨设备同步的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门