Files
WechatOnCloud/docker/Dockerfile
Gloridust c54d3ff18e fix(ci): 构建期精简 apt 源,根治 QEMU arm64 下 apt-get update OOM
v1.4.2 的「合并两层为一次 update」只降低了 OOM 概率,未除根因:单次 update 仍要解析
一堆构建用不到的源(deb-src 源码索引 / backports / docker / nodesource),QEMU 内存峰值仍可能爆
(download.docker.com InRelease 正是触发点)。

对策:构建期把 apt 源精简到只剩 debian main/updates/security(纯二进制)+ chromium 锚定快照,
装完原样恢复(docker.list/nodesource.list/backports 均还原,不改变最终镜像的源)。索引集从 ~13 降到 ~4。
本机原生 arm64 全新构建验证:Chromium 149 装成、包全解析、源已恢复。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 12:19:00 +08:00

108 lines
7.1 KiB
Docker
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WechatOnCloud —— 在浏览器里访问服务端微信
# 基于 linuxserver 的 KasmVNC 基础镜像(多架构 amd64/arm64
# 自带 Xvfb + openbox + KasmVNC + web 客户端(3000/3001)
FROM lscr.io/linuxserver/baseimage-kasmvnc:debianbookworm
# 微信本体不再在构建时下载/安装,改为运行时由面板点击下载、解压到数据卷 /config
#(见 wechat-ctl.sh。构建时只装中文字体、语言环境、下载工具以及微信运行所
# 需的全部系统库(这些需 root/apt必须 bake 进镜像)。
ENV DEBIAN_FRONTEND=noninteractive
# ⚠️ Chromium 版本锚定(架构守则 R1——绝不跟随 Debian 滚动:
# Debian 源只保留最新版 chromium而新版本在本容器栈KasmVNC/Xvnc + 软件渲染)上反复引入致命崩溃:
# · 149 收紧变换矩阵断言(叠加 DPI bug 全面崩溃v1.4.0 已修 DPI
# · 150 「非首次启动」路径与 --start-maximized 直接 SIGTRAP → 浏览器实例必黑屏(无任何 flag 可绕)。
# 故从 snapshot.debian.org 的固定快照安装验证过的版本。升级 chromium = 显式改下面两行(快照时间戳 +
# 版本号),并跑通 doc/dev/发布门禁.md 的全部探针后才允许合并。
ARG CHROMIUM_SNAPSHOT=20260704T180435Z
ARG CHROMIUM_VERSION=149.0.7827.196-1~deb12u1
# ⚠️ CI 的 QEMU arm64 模拟下 apt-get update OOM"Cannot allocate memory",触发点是解析
# download.docker.com InRelease导致实例镜像发不出去。根因是 apt 要解析一大堆【构建根本用不到】
# 的源deb-src 源码索引、backports、docker、nodesource内存峰值在模拟环境里爆掉。
# 对策:构建期把 apt 源精简到只剩「debian main/updates/security仅二进制+ chromium 锚定快照」,
# 装完再原样恢复;合并为单次 update+installLanguages=none 跳翻译、Retries 抗抖动。三管齐下从根上消除 OOM。
RUN set -eux; \
mkdir -p /woc-apt-bak; \
cp -a /etc/apt/sources.list /woc-apt-bak/; \
mv /etc/apt/sources.list.d/docker.list /etc/apt/sources.list.d/nodesource.list /woc-apt-bak/ 2>/dev/null || true; \
{ \
echo "deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware"; \
echo "deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware"; \
echo "deb http://security.debian.org/debian-security/ bookworm-security main contrib non-free non-free-firmware"; \
} > /etc/apt/sources.list; \
echo "deb [check-valid-until=no] https://snapshot.debian.org/archive/debian-security/${CHROMIUM_SNAPSHOT}/ bookworm-security main" \
> /etc/apt/sources.list.d/woc-chromium-pin.list; \
printf 'Package: chromium*\nPin: version %s\nPin-Priority: 1001\n' "${CHROMIUM_VERSION}" \
> /etc/apt/preferences.d/woc-chromium-pin; \
apt-get -o Acquire::Languages=none -o Acquire::Retries=3 update; \
apt-get install -y --no-install-recommends \
curl ca-certificates locales dpkg \
fonts-wqy-zenhei fonts-wqy-microhei fonts-noto-cjk fonts-noto-color-emoji \
libnss3 libgbm1 libasound2 libxss1 \
xz-utils \
chromium="${CHROMIUM_VERSION}" \
xdotool xclip \
xwallpaper xsettingsd \
# 微信原生版是 Qt 程序,依赖一组 xcb 平台库libxcb-cursor0 由 Qt 动态 dlopenldd 查不到,需主动装。
libatomic1 libxdamage1 libxkbcommon-x11-0 \
libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xkb1 libxcb-cursor0 \
# WeChatAppEx 是 Chromium 内核,需 GTK3 全家桶 + 一组 X 扩展 + cups
libgtk-3-0 libatk1.0-0 libatk-bridge2.0-0 libatspi2.0-0 libcups2 \
libxcomposite1 libxrandr2 libxfixes3 libxtst6 libxshmfence1 libdrm2; \
chromium --version; \
rm -f /etc/apt/sources.list.d/woc-chromium-pin.list /etc/apt/preferences.d/woc-chromium-pin; \
mv /woc-apt-bak/sources.list /etc/apt/sources.list; \
mv /woc-apt-bak/docker.list /woc-apt-bak/nodesource.list /etc/apt/sources.list.d/ 2>/dev/null || true; \
rm -rf /woc-apt-bak; \
sed -i 's/# zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen; \
locale-gen; \
apt-get clean; \
rm -rf /var/lib/apt/lists/*
# 字体/字体配置目录都在会话 HOME=/config 下(数据卷,运行时才挂载),故不在此预建;
# 由 autostart 在启动时按需 mkdir + 建 ~/.local/share/fonts → /config/.fonts 软链(见 docker/autostart
ENV LANG=zh_CN.UTF-8 \
LC_ALL=zh_CN.UTF-8 \
LIBGL_ALWAYS_SOFTWARE=1
# 改 KasmVNC web 客户端的 webpack 产物 dist/*.bundle.js
# (1) 默认开启 IME 输入模式:本地(客户端)输入法打中文,拼音联想在本地完成、只把成品汉字
# 发进容器,无需容器内装 IME。默认值仅在浏览器未存过该设置时生效不覆盖用户手动改过的偏好。
# (2) 修复 noVNC 中文 IME 输入:原实现靠隐藏 textarea 差分逐字符重发 keysym会泄漏中间拼音、
# 累积不 reset、退格风暴导致大量丢字 / ~21 字卡住 / 跨浏览器不稳。改为只在 compositionend
# 用 e.data 直发成品字符串(详见 woc-www-patch.sh / woc-ime.pl
# 注意:实际加载的是 webpack 产物 dist/main.bundle.jsapp/ui.js 是未打包源码、运行时不加载),故必须改 bundle。
COPY woc-www-patch.sh woc-ime.pl /woc/
RUN chmod 755 /woc/woc-www-patch.sh && chmod 644 /woc/woc-ime.pl && /woc/woc-www-patch.sh
# 微信下载/解压控制脚本(运行时由面板经 docker exec 触发,状态写入数据卷 /config/.woc-state
COPY wechat-ctl.sh /woc/wechat-ctl.sh
RUN chmod 755 /woc/wechat-ctl.sh
# v1.2.0 多应用应用定义app-defs.sh被 autostart/app-ctl 引用)+ 通用安装/状态控制app-ctl.sh
# 微信委托回 wechat-ctl.sh、其它应用各自实现。app-defs.sh 是被 source 的、不需可执行位。
COPY app-defs.sh app-ctl.sh /woc/
RUN chmod 644 /woc/app-defs.sh && chmod 755 /woc/app-ctl.sh
# openbox 会话启动时执行此脚本:等待微信就绪 + 常驻拉起微信 + 最小化自动复原看守
COPY autostart /defaults/autostart
RUN chmod 755 /defaults/autostart
# 启动钩子00给每个实例唯一且持久的 machine-id避免所有实例共用镜像里烤死的同一个
# 触发腾讯"设备农场"风控导致登录即被强制退出。须在 autostart拉起微信之前执行故用 00 前缀。
COPY woc-identity.sh /custom-cont-init.d/00-woc-identity
RUN chmod 755 /custom-cont-init.d/00-woc-identity
# 启动钩子01每次启动用镜像内最新 autostart 覆盖数据卷旧副本(否则旧实例升级后用不上新逻辑)
COPY woc-update-autostart /custom-cont-init.d/01-woc-autostart
RUN chmod 755 /custom-cont-init.d/01-woc-autostart
# 启动钩子02把容器环境 WOC_APP_TYPE 写入 /config/.woc-app供 autostart 选择启动哪个应用。
# 须在 autostart 之前执行;缺 WOC_APP_TYPE 则不写 → autostart 回退微信(向后兼容)。
COPY woc-app-init.sh /custom-cont-init.d/02-woc-app
RUN chmod 755 /custom-cont-init.d/02-woc-app
# 3000 = HTTP web 客户端, 3001 = HTTPS
EXPOSE 3000 3001