# =============================================================================
# OpenClaw Base Image - 基础设施镜像
# =============================================================================
# 包含:SSH / uv / bun / pnpm / npm全局包 / pip包 / playwright chromium
#
# 构建参数:
#
# 使用方式:
#   docker build -t openclaw:base-2026.5.22 -f Dockerfile.openclaw-base .
# =============================================================================

FROM node:24-bookworm AS uv-install
ARG OPENCLAW_NODE_IMAGE
# Docker Desktop Linux VM 无法直接访问 GitHub,改用 pip 安装 uv
RUN rm -rf /etc/apt/sources.list.d/* /var/lib/apt/lists/* && \
    echo 'deb https://mirrors.aliyun.com/debian/ bookworm main contrib non-free non-free-firmware' > /etc/apt/sources.list && \
    echo 'deb https://mirrors.aliyun.com/debian-security/ bookworm-security main contrib non-free' >> /etc/apt/sources.list && \
    echo 'deb https://mirrors.aliyun.com/debian/ bookworm-updates main contrib non-free' >> /etc/apt/sources.list && \
    apt-get update && \
    DEBIAN_FRONTEND=noninteractive \
    apt-get install -y --no-install-recommends \
        curl python3-pip && \
    pip3 install --break-system-packages \
        -i https://mirrors.aliyun.com/pypi/simple \
        uv && \
    mkdir -p /root/.local/bin && \
    cp "$(which uv)" /root/.local/bin/uv && \
    chmod +x /root/.local/bin/uv && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

FROM node:24-bookworm AS openclaw-base
ARG OPENCLAW_BASE_TAG=latest

# 标签
LABEL org.opencontainers.image.title="OpenClaw Base"
LABEL org.opencontainers.image.description="OpenClaw 基础设施镜像:SSH/uv/bun/pnpm/npm全局包/pip包/playwright"
LABEL org.openclaw.version="${OPENCLAW_BASE_TAG}"

USER root
COPY --from=uv-install /root/.local/bin/uv /usr/local/bin/uv
RUN chmod +x /usr/local/bin/uv && \
    ln -sf /usr/local/bin/uv /usr/local/bin/uvx

# 替换为阿里云镜像源;安装 gosu + Chromium 依赖 + ffmpeg
RUN rm -rf /etc/apt/sources.list.d/* /var/lib/apt/lists/* && \
    echo 'deb https://mirrors.aliyun.com/debian/ bookworm main contrib non-free non-free-firmware' > /etc/apt/sources.list && \
    echo 'deb https://mirrors.aliyun.com/debian-security/ bookworm-security main contrib non-free' >> /etc/apt/sources.list && \
    echo 'deb https://mirrors.aliyun.com/debian/ bookworm-updates main contrib non-free' >> /etc/apt/sources.list && \
    apt-get update && \
    DEBIAN_FRONTEND=noninteractive \
    apt-get install -y --no-install-recommends --fix-missing \
        procps hostname curl git lsof openssl \
        openssh-server python3 python3-pip python3-venv \
        iputils-ping vim unzip \
        gosu \
        ffmpeg \
        libxfixes3 \
        libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 \
        libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 \
        libxrandr2 libgbm1 libpango-1.0-0 libcairo2 \
        libasound2 libatspi2.0-0 libwayland-client0 \
        rsync && \
    apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*

# SSH(Port 2222,禁用密码登录)
RUN mkdir -p /run/sshd && \
    sed -i 's/#Port 22/Port 2222/' /etc/ssh/sshd_config && \
    sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config && \
    sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

# ── 环境变量 ──────────────────────────────────────────────────────────────
ENV PATH="/root/.bun/bin:/usr/local/bin:$PATH"
ENV UV_SYSTEM_PYTHON=1

# ── bun(npm 全局安装)────────────────────────────────
RUN npm config set registry https://registry.npmmirror.com && \
    npm install -g bun --legacy-peer-deps && \
    mkdir -p /root/.bun/bin && \
    ln -sf /usr/local/bin/bun /root/.bun/bin/bun && \
    chmod +x /root/.bun/bin/bun

# ── pnpm ────────────────────────────────────────────────
RUN npm config set registry https://registry.npmmirror.com && \
    npm install -g pnpm --legacy-peer-deps

# ── npm 全局包(文档处理)───────────────────────────────
RUN npm config set registry https://registry.npmmirror.com && \
    npm install -g \
        pptxgenjs react-icons sharp docx xlsx \
        react react-dom @types/react @types/react-dom \
        --legacy-peer-deps || \
    npm install -g \
        pptxgenjs react-icons sharp docx xlsx \
        react react-dom @types/react @types/react-dom \
        --legacy-peer-deps

# ── pip 包 ───────────────────────────────────────────────
RUN python3 -m pip config set global.timeout 120 && \
    python3 -m pip config set global.retries 5 && \
    python3 -m pip install --break-system-packages \
        -i https://mirrors.aliyun.com/pypi/simple \
        --extra-index-url https://pypi.tuna.tsinghua.edu.cn/simple \
        --extra-index-url https://pypi.org/simple \
        markitdown[pptx] python-pptx python-docx \
        lxml openpyxl pillow pdf2image pdfminer.six

# ── Playwright Chromium(app + overlay 层迁移至此)─────
ARG http_proxy
ARG https_proxy
ARG PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT=300000
RUN mkdir -p /home/node/.cache/ms-playwright && \
    npm install -g playwright --legacy-peer-deps --no-cache && \
    PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright \
    PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT=${PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT} \
    http_proxy=${http_proxy} https_proxy=${https_proxy} \
    npx playwright install --with-deps chromium && \
    npm cache clean --force && \
    test -d /home/node/.cache/ms-playwright/chromium-* && echo "Chromium installed" && \
    chown -R node:node /home/node/.cache/ms-playwright

# ── Chromium 版本兼容符号链接 ────────────────────────────
RUN if [ -d /home/node/.cache/ms-playwright ]; then \
        latest=$(ls -d /home/node/.cache/ms-playwright/chromium-* 2>/dev/null | grep -v headless_shell | sort | tail -1); \
        if [ -n "$latest" ] && [ -d "$latest" ]; then \
            ln -sfn "$latest" /home/node/.cache/ms-playwright/chromium-latest; \
            chown -h node:node /home/node/.cache/ms-playwright/chromium-latest; \
        fi; \
    fi

# ── 运行时用户 ────────────────────────────────────────────
ARG OPENCLAW_UID=1000
ARG OPENCLAW_GID=1000
RUN groupadd -g ${OPENCLAW_GID} node 2>/dev/null || true && \
    useradd -m -u ${OPENCLAW_UID} -g node -s /bin/bash node 2>/dev/null || true
USER node