-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
175 lines (172 loc) · 9.43 KB
/
Copy pathdocker-compose.yml
File metadata and controls
175 lines (172 loc) · 9.43 KB
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# ================================================================
# Botler Docker 部署(docker compose)
#
# 快速开始:
# cp backend/config.example.yaml backend/config.yaml
# cp backend/.env.example backend/.env # 填入 GITLAB_BOT_TOKEN 等凭据
# touch backend/botler.db # SQLite 库(首次运行自动建表)
# docker compose up -d --build
#
# 可调参数(环境变量,均有默认值):
# BOTLER_HTTP_PORT=8000 宿主机映射端口
# BOTLER_DATA_DIR=./data 数据目录前缀(config.yaml/.env/botler.db/workspace/logs 的挂载来源,
# 默认 ./data = 部署目录下 data/ 文件夹,如 /home/ckd/codes/botler/data)
#
# 说明:
# - 前端已打进镜像(多阶段构建),FastAPI 直接托管,无需 nginx
# - 容器内已装 claude CLI,ANTHROPIC_* 凭据经 backend/.env 注入
# (后端 load_dotenv 加载后由执行器子进程继承)
# - config.yaml 为可写挂载:Web UI 设置页会写回
# - 时区固定 Asia/Shanghai(TZ 环境变量 + 镜像内 tzdata 时区库)
# - 换数据目录后 botler.db/config.yaml 需一并迁移
# ================================================================
services:
botler:
build:
context: .
dockerfile: Dockerfile
args:
# 国内无法访问 Docker Hub 时设置环境变量 NODE_IMAGE / RUNTIME_IMAGE
# 覆盖为基础镜像(如 docker.m.daocloud.io/library/node:20-alpine)
NODE_IMAGE: ${NODE_IMAGE:-node:20-alpine}
RUNTIME_IMAGE: ${RUNTIME_IMAGE:-node:20-bookworm-slim}
image: botler:latest
container_name: botler
restart: unless-stopped
ports:
- "${BOTLER_HTTP_PORT:-8000}:8000"
environment:
# 后端启动时读取(config.py / database.py 均支持环境变量覆盖)
BOTLER_CONFIG: /app/backend/config.yaml
BOTLER_DB: /app/backend/botler.db
BOTLER_LOG_DIR: /app/logs
PYTHONPATH: /app/backend
# 部署时区固定为亚洲/上海(镜像内已装 tzdata,TZ 环境变量即时生效)
TZ: Asia/Shanghai
# 容器内 git(执行器 clone/push 仓库)凭据:强制 store helper 读取
# 挂载的凭据文件(容器内无 libsecret/D-Bus,宿主 credential.helper
# 配置不可用;镜像以 root 运行,凭据文件固定挂载为 /root/.git-credentials)
GIT_CONFIG_COUNT: "1"
GIT_CONFIG_KEY_0: credential.helper
GIT_CONFIG_VALUE_0: store --file=/root/.git-credentials
# hermes 引擎 SDK(issue #171 起进程内集成):hermes-agent 源码
# 挂载路径(docker-entrypoint.sh 启动时 editable 安装到 /opt/venv,
# 幂等)。未挂载源码时 hermes 引擎按 SDK 未安装处理(提示安装指引)。
HERMES_SOURCE_DIR: ${HERMES_SOURCE_DIR:-/opt/hermes/hermes-agent}
# Web 终端(issue #183):/api/terminal/* 反向代理到独立终端服务
# 进程(compose 网络内 terminal:8765,不对外暴露端口,安全隔离)
BOTLER_TERM_UPSTREAM: http://terminal:8765
# hermes 数据目录(LLM 配置 / 会话状态,runner 进程内读写):默认
# 走 hermes 平台默认 ~/.hermes(容器内为 /root/.hermes),部署时
# 挂载宿主 ~/.hermes 或设置 HERMES_HOME 指向挂载的数据目录(详见
# docs/hermes-engine-deployment.md §4)。
volumes:
# 配置与凭据(挂载文件,改动即生效;.env 只读)
# 默认挂载源为 ./data/(部署目录下 data/ 文件夹,如
# /home/ckd/codes/botler/data),config.yaml / .env / botler.db /
# workspace / logs 全部集中在 data/ 下,便于备份与 gitignore 隔离
- ${BOTLER_DATA_DIR:-./data}/backend/config.yaml:/app/backend/config.yaml
- ${BOTLER_DATA_DIR:-./data}/backend/.env:/app/backend/.env:ro
# SQLite 数据库(仓库/任务记录,容器重建不丢失)
- ${BOTLER_DATA_DIR:-./data}/backend/botler.db:/app/backend/botler.db
# 仓库工作区与任务执行日志
- ${BOTLER_DATA_DIR:-./data}/workspace:/app/workspace
- ${BOTLER_DATA_DIR:-./data}/logs:/app/logs
# claude 会话文件(~/.claude,断点续跑依赖:容器重建后 --resume 才能
# 找到上次会话;目录不存在时 docker 自动创建)
- ${BOTLER_DATA_DIR:-./data}/claude-home:/root/.claude
# 备份包(backup API 写入;目录不存在时 docker 自动创建)
- ${BOTLER_DATA_DIR:-./data}/backups:/app/backend/backups
# SSO 会话签名密钥(issue #27:auth.py 懒生成持久化,容器重建不丢登录态)
- ${BOTLER_DATA_DIR:-./data}/backend/data:/app/backend/data
# 容器内 git 凭据(执行器 clone/push 用)。默认挂载 /dev/null 兜底
# (docker 对不存在的源路径会创建目录导致挂载错位,空凭据无害);
# 部署脚本 / verify 脚本 export GIT_CREDENTIALS_FILE 指向真实凭据
# 文件(优先宿主 ~/.git-credentials 或 CI 生成的 .git-credentials)
- ${GIT_CREDENTIALS_FILE:-/dev/null}:/root/.git-credentials:ro
# hermes-agent 源码(issue #171 SDK 进程内集成):宿主机 hermes-agent
# 源码目录只读挂载,entrypoint 启动时 editable 安装进 /opt/venv。
# 非 hermes 引擎部署可删掉这两条(hermes 引擎会提示 SDK 未安装)。
# - ${HERMES_DIR:-~/.hermes/hermes-agent}:/opt/hermes/hermes-agent:ro
# - ${HERMES_DATA_DIR:-~/.hermes}:/root/.hermes
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8000/api/health"]
interval: 30s
timeout: 5s
start_period: 60s
retries: 3
# ----------------------------------------------------------------
# MinIO 对象存储服务(issue #160):后端部署附属服务,docker compose
# 一并启动(pm2 部署形态见 deploy/botler.config.cjs 的 botler-minio app
# 与 deploy/install-minio.sh)。
#
# 可调参数(环境变量,均有默认值):
# MINIO_IMAGE=minio/minio:RELEASE.2025-04-22T22-12-26Z
# 镜像(国内无法访问 Docker Hub 时覆盖为
# 镜像源,如 docker.m.daocloud.io/minio/minio)
# MINIO_API_PORT=9000 宿主机 API 端口映射
# MINIO_CONSOLE_PORT=9001 宿主机 console 端口映射
# MINIO_ROOT_USER / MINIO_ROOT_PASSWORD
# 根凭据(默认 minioadmin/minioadmin,生产
# 环境务必覆盖;与 pm2 部署共用
# data/backend/.env 中的同名变量)
#
# 数据持久化:${BOTLER_DATA_DIR}/minio/data 挂载为容器 /data
# (与 botler 数据同根目录,备份/迁移一并处理,容器重建不丢失)。
# 健康检查:GET /minio/health/live(live 探针)。
# ================================================================
# ----------------------------------------------------------------
# Web 终端服务(issue #183):Tornado + terminado 独立进程,与主后端
# 共享用户验证(同一会话密钥文件 session_secret.key,经 data 卷共享)。
# 默认只监听容器内 0.0.0.0:8765(compose 网络内部可达,未映射宿主端口
# = 安全隔离,不对外暴露),对外统一经 botler 主后端 /api/terminal/*
# 反向代理(或 nginx 统一入口,见 deploy/nginx-terminal.conf)。
# 可调参数:TERM_IMAGE 覆盖镜像(默认复用 botler 构建产物)。
# ================================================================
terminal:
image: ${TERM_IMAGE:-botler:latest}
container_name: botler-terminal
restart: unless-stopped
command: ["/opt/venv/bin/python", "backend/terminal_service.py"]
environment:
# 与主后端共享会话密钥(token 校验同一密钥);监听 0.0.0.0 供
# compose 网络内 botler 反向代理访问(不映射宿主端口)
PYTHONPATH: /app/backend
BOTLER_TERM_PORT: "8765"
BOTLER_TERM_BIND: 0.0.0.0
TZ: Asia/Shanghai
volumes:
# 会话签名密钥(auth.py 懒生成持久化,与 botler 共享同一文件)
- ${BOTLER_DATA_DIR:-./data}/backend/data:/app/backend/data
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8765/terminal/health"]
interval: 30s
timeout: 5s
start_period: 30s
retries: 3
minio:
image: ${MINIO_IMAGE:-minio/minio:RELEASE.2025-04-22T22-12-26Z}
container_name: minio
restart: unless-stopped
command: server /data --console-address ":9001"
ports:
- "${MINIO_API_PORT:-9000}:9000"
- "${MINIO_CONSOLE_PORT:-9001}:9001"
environment:
# 根凭据:默认 minioadmin/minioadmin,生产环境务必用环境变量覆盖
# (与 pm2 部署共用 data/backend/.env 中的 MINIO_ROOT_USER /
# MINIO_ROOT_PASSWORD,保持一致)
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin}
# 部署时区与 botler 保持一致(容器内无需 tzdata,环境变量即时生效)
TZ: Asia/Shanghai
volumes:
# 数据目录固定在数据目录前缀下(默认 ./data = 部署目录 data/,
# 如 /home/ckd/codes/botler/data/minio/data),容器重建不丢
- ${BOTLER_DATA_DIR:-./data}/minio/data:/data
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:9000/minio/health/live"]
interval: 30s
timeout: 5s
start_period: 30s
retries: 3