File size: 5,426 Bytes
c5a8881
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9ad43d6
 
fed4685
c5a8881
 
e26a175
c5a8881
e26a175
c5a8881
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9ad43d6
c5a8881
 
 
 
 
 
 
 
 
e26a175
c5a8881
 
 
 
 
 
 
 
 
 
 
 
9c1d45f
c5a8881
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e26a175
c5a8881
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

# ========== 阶段1:构建环境 ==========
FROM node:22-bookworm AS builder

ENV LANG=zh_CN.UTF-8 \
    LANGUAGE=zh_CN:zh \
    LC_ALL=zh_CN.UTF-8 \
    DEBIAN_FRONTEND=noninteractive

# 安装构建依赖(包含编译工具和 Python 完整环境)
RUN apt-get update && apt-get install -y --no-install-recommends \
    git openssh-client build-essential python3-full python3-pip python3-venv \
    ca-certificates curl unzip \
    libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
    libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 \
    libgbm1 libpango-1.0-0 libcairo2 libasound2 \
    fonts-noto-cjk fonts-noto-color-emoji locales \
    gnupg2 \
    && sed -i 's/^# \(zh_CN.UTF-8\)/\1/' /etc/locale.gen && locale-gen \
    && apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 871920D1991BC93C || true \
    && rm -rf /var/lib/apt/lists/*

# 创建 Python 虚拟环境并安装所需包
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
RUN pip install --no-cache-dir --upgrade pip \
#    && pip install --no-cache-dir huggingface_hub jupyterlab \
    && pip cache purge

# 安装 Bun
RUN curl -fsSL https://bun.sh/install | bash
ENV BUN_INSTALL=/root/.bun
ENV PATH="${BUN_INSTALL}/bin:${PATH}"

# 安装 UV
RUN curl -LsSf https://astral.sh/uv/install.sh | sh \
    && mv /root/.local/bin/uv /usr/local/bin/uv

# 安装 OpenClaw 核心到自定义目录(避免污染系统全局)
RUN npm install --prefix /opt/openclaw -g openclaw@latest --unsafe-perm && npm cache clean --force

# 安装 Playwright(指定版本,下载浏览器)
ARG PLAYWRIGHT_VERSION=1.50.1
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@latest --activate \
    && printf '{"name":"openclaw-app","private":true}' > package.json \
    && pnpm add -D playwright@${PLAYWRIGHT_VERSION} \
    && pnpm exec playwright install chromium \
    && pnpm store prune


# ---------- 写入您的原始启动脚本 start-openclaw ----------
RUN echo '#!/bin/bash\n\
set -e\n\
# 默认环境变量填充\n\
export OPENAI_API_BASE="${OPENAI_API_BASE:-https://openrouter.ai/api/v1}"\n\
export OPENAI_API_KEY="${OPENAI_API_KEY:-sk-yourapikey}"\n\
export MODEL="${MODEL:-openrouter/free}"\n\
export PORT="${PORT:-18789}"\n\
\n\
mkdir -p /root/.openclaw\n\
\n\

\n\
# 处理 BaseUrl 格式\n\
CLEAN_BASE=$(echo "$OPENAI_API_BASE" | sed "s|/chat/completions||g" | sed "s|/v1/|/v1|g" | sed "s|/v1$|/v1|g")\n\
\n\
# 动态生成 openclaw.json\n\
cat <<EOF > /root/.openclaw/openclaw.json\n\
{\n\
  "models": {\n\
    "providers": {\n\
      "nvidia": {\n\
        "baseUrl": "$CLEAN_BASE",\n\
        "apiKey": "$OPENAI_API_KEY",\n\
        "api": "openai-completions",\n\
        "models": [{ "id": "$MODEL", "name": "PrimaryModel", "contextWindow": 128000 }]\n\
      }\n\
    }\n\
  },\n\
  "agents": { "defaults": { "model": { "primary": "$MODEL" } } },\n\
  "gateway": {\n\
    "mode": "local", "bind": "lan", "port": $PORT,\n\
    "trustedProxies": ["0.0.0.0/0", "10.0.0.0/8", "172.16.0.0/12", "10.233.64.0/18", "100.64.0.0/10", "127.0.0.1/8"],\n\
    "auth": { "mode": "token" },\n\
    "controlUi": { "enabled": true, "dangerouslyAllowHostHeaderOriginFallback": true, "allowInsecureAuth": true, "dangerouslyDisableDeviceAuth": true}\n\
  }\n\
}\n\
EOF\n\
\n\

# 动态查找 playwright 的 chromium 路径并设置 CHROME_PATH(若未指定或不存在)\n\
if [ ! -f "$CHROME_PATH" ]; then\n\
    CHROME_PATH=$(find /root/.cache/ms-playwright -name chrome -type f 2>/dev/null | head -1)\n\
    export CHROME_PATH\n\
fi\n\
\n\
openclaw doctor --fix || true\n\
echo "🚀 Starting OpenClaw on port $PORT..."\n\
exec openclaw gateway run --port $PORT\n\
' > /usr/local/bin/start-openclaw && chmod +x /usr/local/bin/start-openclaw

# ========== 阶段2:最终运行镜像 ==========
FROM node:22-bookworm

ENV LANG=zh_CN.UTF-8 \
    LANGUAGE=zh_CN:zh \
    LC_ALL=zh_CN.UTF-8 \
    DEBIAN_FRONTEND=noninteractive

# 安装运行时必需的库、locales 并生成中文环境
RUN apt-get update && apt-get install -y --no-install-recommends \
    ca-certificates curl \
    libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
    libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 \
    libgbm1 libpango-1.0-0 libcairo2 libasound2 \
    fonts-noto-cjk fonts-noto-color-emoji \
    python3-minimal python3-venv \
    locales \
    && sed -i 's/^# \(zh_CN.UTF-8\)/\1/' /etc/locale.gen \
    && locale-gen \
    && rm -rf /var/lib/apt/lists/*

# 从构建阶段复制 Python 虚拟环境
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# 复制 Bun
COPY --from=builder /root/.bun /root/.bun
ENV BUN_INSTALL=/root/.bun
ENV PATH="${BUN_INSTALL}/bin:${PATH}"

# 复制 UV
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uv

# 复制 OpenClaw(自定义安装目录)并添加到 PATH
COPY --from=builder /opt/openclaw /opt/openclaw
ENV PATH="/opt/openclaw/bin:${PATH}"

# 复制 Playwright 浏览器
COPY --from=builder /root/.cache/ms-playwright /root/.cache/ms-playwright
ENV PLAYWRIGHT_BROWSERS_PATH=/root/.cache/ms-playwright
# 不在这里设置 CHROME_PATH 静态值,由启动脚本动态查找


COPY --from=builder /usr/local/bin/start-openclaw /usr/local/bin/start-openclaw

WORKDIR /app

ARG PORT=18789
ENV PORT=${PORT}
EXPOSE ${PORT}

CMD ["/usr/local/bin/start-openclaw"]