# syntax=docker/dockerfile:1 # 基础镜像版本必须与 uv.lock 中的 playwright 版本一致(当前 1.60.0), # 浏览器二进制与系统依赖已预装在 /ms-playwright。 FROM mcr.microsoft.com/playwright/python:v1.60.0-noble ENV DEBIAN_FRONTEND=noninteractive # X 虚拟桌面 + VNC/noVNC + 录屏/截图/图像匹配运行依赖 + 日文字体 + 进程编排 RUN apt-get update && apt-get install -y --no-install-recommends \ xvfb \ fluxbox \ x11vnc \ novnc \ websockify \ ffmpeg \ scrot \ libgl1 \ fonts-noto-cjk \ supervisor \ curl \ tzdata \ && rm -rf /var/lib/apt/lists/* COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/ WORKDIR /app # 私有 PyPI 索引(git.jerryyan.net)若需要认证,构建时传入: # docker build --build-arg UV_INDEX_JERRYYAN_USERNAME=xxx --build-arg UV_INDEX_JERRYYAN_PASSWORD=xxx . ARG UV_INDEX_JERRYYAN_USERNAME ARG UV_INDEX_JERRYYAN_PASSWORD # 依赖层缓存:仅复制依赖清单后同步,源码变更不触发依赖重装 COPY pyproject.toml uv.lock ./ RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev COPY src ./src COPY resources ./resources COPY .env.prod ./.env.prod # 容器配置模板:运行时若挂载的 /app/config 中无 accounts.yaml,entrypoint 会用它初始化 COPY deploy/config/accounts.yaml /app/deploy-defaults/accounts.yaml COPY docker/supervisord.conf /etc/supervisor/supervisord.conf COPY docker/entrypoint.sh /entrypoint.sh # 防御 Windows 仓库 CRLF 换行导致脚本无法执行 RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.sh ENV APP_ENV=prod \ TZ=Asia/Shanghai \ DISPLAY=:99 \ SCREEN_RES=1920x1080x24 \ ACCOUNTS_CONFIG_PATH=/app/config/accounts.yaml \ PYTHONUNBUFFERED=1 # 关键数据声明为卷(兜底):即使 docker run 时未显式挂载, # 浏览器登录态(accounts 的 user_data_dir 父目录)与账号配置也会落入匿名卷持久化。 # accounts.yaml 中每个账号的 user_data_dir 都应指向 /app/chrome-profile/ 下的子目录。 VOLUME ["/app/chrome-profile", "/app/config"] # 6080: noVNC web | 5900: 原生 VNC | 8080: 截图/账号配置 API EXPOSE 5900 6080 8080 # 启动需等待 Xvfb + 浏览器预热 + API 拉起 HEALTHCHECK --interval=30s --timeout=5s --start-period=120s --retries=3 \ CMD curl -fs "http://localhost:8080/api/screenshots?days=1" > /dev/null || exit 1 ENTRYPOINT ["/entrypoint.sh"]