File size: 3,994 Bytes
48afc01
0720e7c
 
 
 
 
48afc01
0720e7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48afc01
 
 
 
0720e7c
 
 
 
 
 
 
847098c
 
 
 
 
 
 
 
4e18209
8df073a
4e18209
0720e7c
4e18209
0720e7c
 
 
 
8df073a
0720e7c
8df073a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0720e7c
8df073a
0720e7c
 
4e18209
48afc01
 
0720e7c
4e18209
847098c
 
4e18209
48afc01
0720e7c
 
 
 
 
 
 
8df073a
 
 
4e18209
 
 
 
 
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
# 采用官方给定的核心底座
ARG HERMES_AGENT_VERSION=latest
FROM nousresearch/hermes-agent:${HERMES_AGENT_VERSION}

USER root

# 1. 完整保留原项目的全部系统依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
    ca-certificates \
    curl \
    jq \
    sudo \
    python3 \
    python3-venv \
    python3-pip \
    chromium \
    dbus \
    dbus-x11 \
    libnss3 \
    libatk1.0-0 \
    libatk-bridge2.0-0 \
    libdrm2 \
    libgbm1 \
    libxcomposite1 \
    libxdamage1 \
    libxrandr2 \
    libxkbcommon0 \
    libx11-6 \
    libxext6 \
    libxfixes3 \
    fonts-dejavu-core \
    fonts-liberation \
    fonts-noto-color-emoji \
    && (apt-get install -y --no-install-recommends libasound2 2>/dev/null \
        || apt-get install -y --no-install-recommends libasound2t64 2>/dev/null \
        || true) \
    && rm -rf /var/lib/apt/lists/*

# 2. 将 JupyterLab 注入到虚拟环境中以驱动原项目的 Terminal 终端
RUN uv pip install --python /opt/hermes/.venv/bin/python --no-cache-dir \
        "jupyterlab>=4.0,<5" \
        "tornado>=6.4" \
        "ipywidgets>=8.1" \
    && printf 'hermes ALL=(ALL) NOPASSWD: ALL\n' > /etc/sudoers.d/hermes \
    && chmod 0440 /etc/sudoers.d/hermes \
    && /usr/sbin/visudo -cf /etc/sudoers.d/hermes

# 3. 复制魔改项目的全部核心组件
COPY start.sh /opt/huggingmes/start.sh
COPY health-server.js /opt/huggingmes/health-server.js
COPY cloudflare-proxy-setup.py /opt/huggingmes/cloudflare-proxy-setup.py
COPY cloudflare-keepalive-setup.py /opt/huggingmes/cloudflare-keepalive-setup.py
COPY env-builder.html /opt/huggingmes/env-builder.html
COPY env-builder.js /opt/huggingmes/env-builder.js

# 4. 去除 Windows 换行符隐患并放开执行权限
RUN sed -i 's/\r$//' /opt/huggingmes/start.sh && \
    chmod -R 777 /opt/huggingmes

# 5. 保留原项目看板数据库迁移幂等补丁
RUN python3 - <<'PY'
import sys
try:
    from pathlib import Path

    p = Path("/opt/hermes/hermes_cli/kanban_db.py")
    if not p.exists():
        print("kanban patch: file not found, skipping")
        sys.exit(0)

    src = p.read_text(encoding="utf-8", errors="replace")
    sentinel = "# huggingmes: idempotent-alter"
    if sentinel in src:
        print("kanban patch: already applied, skipping")
        sys.exit(0)

    old = (
        '    conn.execute(\n'
        '        "ALTER TABLE tasks ADD COLUMN consecutive_failures "\n'
        '        "INTEGER NOT NULL DEFAULT 0"\n'
        '    )'
    )
    new = (
        f'    try:  {sentinel}\n'
        '        conn.execute(\n'
        '            "ALTER TABLE tasks ADD COLUMN consecutive_failures "\n'
        '            "INTEGER NOT NULL DEFAULT 0"\n'
        '        )\n'
        '    except Exception:\n'
        '        pass'
    )

    if old not in src:
        print("kanban patch: pattern not found, may be fixed upstream, skipping")
        sys.exit(0)

    p.write_text(src.replace(old, new), encoding="utf-8")
    print("kanban patch: applied")
except Exception as e:
    print(f"kanban patch: error ({e}), skipping", file=sys.stderr)
PY

# 确保环境变量 PATH 在全量挂载下正常工作
RUN echo 'export PATH="/opt/hermes/.venv/bin:/opt/data/.local/bin:$PATH"' \
    > /etc/profile.d/hermes-venv.sh

# 顺应底层用户身份
USER hermes

# 核心声明:直接将整个存储桶作为唯一的 HERMES_HOME 数据保存地
ENV HERMES_HOME=/opt/data \
    HUGGINGMES_APP_DIR=/opt/huggingmes \
    HERMES_AGENT_VERSION=${HERMES_AGENT_VERSION} \
    PYTHONUNBUFFERED=1 \
    PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium

EXPOSE 7861

HEALTHCHECK --interval=30s --timeout=5s --start-period=60s \
  CMD curl -fsS http://localhost:7861/health || exit 1

# 💥 关键修改:清空基础镜像的 ENTRYPOINT,不再走官方 s6-overlay 流程,彻底屏蔽 chown 权限地雷
ENTRYPOINT []

# 直接拉起我们的控制脚本作为 PID 1 独立执行
CMD ["/bin/bash", "/opt/huggingmes/start.sh"]