feat: Goosed 本地 Docker 构建方案
- scripts/verify-goosed-docker.sh: 一键本地构建脚本 - docker-compose.local.yml: 本地开发环境 - docs/goosed-docker-local-verification.md: 本地测试指南 - docs/goosed-local-build-delivery.md: 构建交付说明 - docs/goosed-phase1-local-plan.md: 实施计划 完全本地化,无 CI 依赖,手工构建交付。
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
# Goosed 实例 1
|
||||
goosed-1:
|
||||
build:
|
||||
context: ./tkmind_go
|
||||
dockerfile: Dockerfile.goosed
|
||||
container_name: goosed-1
|
||||
ports:
|
||||
- "18006:18006"
|
||||
environment:
|
||||
GOOSE_HOST: 0.0.0.0
|
||||
GOOSE_PORT: 18006
|
||||
GOOSE_SERVER__SECRET_KEY: ${GOOSE_SERVER__SECRET_KEY:-local-dev-secret-key}
|
||||
# 可选:Debug 日志
|
||||
RUST_LOG: ${RUST_LOG:-info}
|
||||
volumes:
|
||||
- goosed-1-data:/home/goose/.local/share/goose
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://127.0.0.1:18006/status"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 20s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- local-dev
|
||||
|
||||
# Goosed 实例 2(可选)
|
||||
goosed-2:
|
||||
build:
|
||||
context: ./tkmind_go
|
||||
dockerfile: Dockerfile.goosed
|
||||
container_name: goosed-2
|
||||
ports:
|
||||
- "18007:18006"
|
||||
environment:
|
||||
GOOSE_HOST: 0.0.0.0
|
||||
GOOSE_PORT: 18006
|
||||
GOOSE_SERVER__SECRET_KEY: ${GOOSE_SERVER__SECRET_KEY:-local-dev-secret-key}
|
||||
RUST_LOG: ${RUST_LOG:-info}
|
||||
volumes:
|
||||
- goosed-2-data:/home/goose/.local/share/goose
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://127.0.0.1:18006/status"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 20s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- local-dev
|
||||
depends_on:
|
||||
- goosed-1
|
||||
|
||||
volumes:
|
||||
goosed-1-data:
|
||||
goosed-2-data:
|
||||
|
||||
networks:
|
||||
local-dev:
|
||||
driver: bridge
|
||||
@@ -0,0 +1,304 @@
|
||||
# Goosed Docker 本地验证指南
|
||||
|
||||
> **目标:** 在本地完全验证 goosed Docker 镜像构建、运行、性能,然后再部署到 103。
|
||||
> **方案:** 完全本地化(git.tkmind.cn + 本地 Docker + 手工交付)。
|
||||
> **时间预期:** 1–2 周本地验证。
|
||||
|
||||
## 🚀 快速开始(5 分钟)
|
||||
|
||||
### 一键本地构建 + 验证
|
||||
|
||||
```bash
|
||||
cd /Users/john/PycharmProjects/test/test-memind
|
||||
|
||||
# 本地构建镜像 + 启动容器 + 健康检查
|
||||
bash scripts/verify-goosed-docker.sh local
|
||||
```
|
||||
|
||||
脚本执行流程:
|
||||
1. 构建 `tkmind/goosed:local` Docker 镜像
|
||||
2. 启动容器到 18006 端口
|
||||
3. 等待 `/status` 端点就绪(最多 30 秒)
|
||||
4. 显示容器日志和可用的测试命令
|
||||
5. 容器保持运行供手工测试
|
||||
|
||||
---
|
||||
|
||||
## 详细步骤
|
||||
|
||||
### 第一次构建(15 分钟)
|
||||
|
||||
#### 1. 检查环境
|
||||
|
||||
```bash
|
||||
# Docker 版本(需 20.10+)
|
||||
docker --version
|
||||
|
||||
# Docker Compose(需 2.0+)
|
||||
docker-compose --version
|
||||
|
||||
# 检查磁盘空间(Rust 编译需 ~2GB)
|
||||
docker system df
|
||||
```
|
||||
|
||||
#### 2. 本地构建镜像
|
||||
|
||||
```bash
|
||||
cd /Users/john/PycharmProjects/test/test-memind
|
||||
|
||||
# 方式 A:直接从 Dockerfile 构建(首次较慢)
|
||||
docker build -f tkmind_go/Dockerfile.goosed -t tkmind/goosed:local tkmind_go/
|
||||
|
||||
# 方式 B:使用 Docker Buildx 缓存加速(推荐)
|
||||
docker buildx build \
|
||||
-f tkmind_go/Dockerfile.goosed \
|
||||
-t tkmind/goosed:local \
|
||||
--load \
|
||||
tkmind_go/
|
||||
```
|
||||
|
||||
预期:**8–12 分钟**(首次较慢,后续有缓存)
|
||||
|
||||
输出示例:
|
||||
```
|
||||
=> exporting to docker image format 0.3s
|
||||
=> => exporting layers 0.2s
|
||||
=> => exporting manifest sha256:abc123... 0.0s
|
||||
=> => exporting config sha256:def456... 0.0s
|
||||
Successfully tagged tkmind/goosed:local
|
||||
```
|
||||
|
||||
#### 3. 验证镜像
|
||||
|
||||
```bash
|
||||
# 查看镜像大小
|
||||
docker images | grep goosed
|
||||
# tkmind/goosed local sha256:abc123 50MB
|
||||
|
||||
# 检查镜像层
|
||||
docker history tkmind/goosed:local
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第二步:启动 & 测试
|
||||
|
||||
#### 方式 A:脚本(推荐)
|
||||
|
||||
```bash
|
||||
bash scripts/verify-goosed-docker.sh local
|
||||
|
||||
# 输出应该显示:
|
||||
# ✅ 镜像构建完成
|
||||
# ✅ 容器已启动
|
||||
# ✅ 容器已就绪
|
||||
```
|
||||
|
||||
#### 方式 B:手工 docker run
|
||||
|
||||
```bash
|
||||
docker run -d --name goosed-test \
|
||||
-p 18006:18006 \
|
||||
-e GOOSE_HOST=0.0.0.0 \
|
||||
-e GOOSE_PORT=18006 \
|
||||
-e GOOSE_SERVER__SECRET_KEY=test-secret \
|
||||
-v goosed-test-data:/home/goose/.local/share/goose \
|
||||
tkmind/goosed:local
|
||||
```
|
||||
|
||||
#### 方式 C:Docker Compose(两个实例)
|
||||
|
||||
```bash
|
||||
# 启动两个 goosed 实例(18006 + 18007)
|
||||
docker-compose -f docker-compose.local.yml up -d
|
||||
|
||||
# 查看状态
|
||||
docker-compose -f docker-compose.local.yml ps
|
||||
|
||||
# 查看日志
|
||||
docker-compose -f docker-compose.local.yml logs -f goosed-1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 测试与验证
|
||||
|
||||
### 1. 健康检查
|
||||
|
||||
```bash
|
||||
# 检查 /status 端点
|
||||
curl http://127.0.0.1:18006/status
|
||||
|
||||
# 预期响应(JSON):
|
||||
# {"status": "ok", "version": "..."}
|
||||
```
|
||||
|
||||
### 2. 容器日志
|
||||
|
||||
```bash
|
||||
# 查看完整日志(最后 50 行)
|
||||
docker logs goosed-test | tail -50
|
||||
|
||||
# 持续流式日志
|
||||
docker logs -f goosed-test
|
||||
|
||||
# 搜索错误
|
||||
docker logs goosed-test 2>&1 | grep -i error
|
||||
```
|
||||
|
||||
### 3. 容器内部检查
|
||||
|
||||
```bash
|
||||
# 进入容器 shell
|
||||
docker exec -it goosed-test /bin/bash
|
||||
|
||||
# 在容器内检查
|
||||
cd /home/goose/.local/share/goose
|
||||
ls -la
|
||||
file goose.db # Session 数据库
|
||||
|
||||
# 检查网络
|
||||
netstat -tlnp | grep 18006
|
||||
|
||||
# 退出容器
|
||||
exit
|
||||
```
|
||||
|
||||
### 4. 资源使用
|
||||
|
||||
```bash
|
||||
# 监控资源使用(CPU、内存)
|
||||
docker stats goosed-test
|
||||
|
||||
# 预期:
|
||||
# CPU ~5–20%(空闲时)
|
||||
# MEM 100–300MB(依赖 session 规模)
|
||||
```
|
||||
|
||||
### 5. 性能测试(可选)
|
||||
|
||||
```bash
|
||||
# 如果有测试工具,可以测试并发连接
|
||||
# 示例:使用 Apache Bench(需安装 ab)
|
||||
ab -n 100 -c 10 http://127.0.0.1:18006/status
|
||||
|
||||
# 或使用 wrk(需安装)
|
||||
wrk -t4 -c100 -d10s http://127.0.0.1:18006/status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与 103 对接前的检查清单
|
||||
|
||||
在考虑部署到 103 前,在本地完成以下检查:
|
||||
|
||||
- [ ] ✅ 镜像构建成功,无编译错误
|
||||
- [ ] ✅ 容器启动无异常,`/status` 端点响应正常
|
||||
- [ ] ✅ Session 数据库(SQLite)正常创建和存储
|
||||
- [ ] ✅ 容器日志无 panic / segfault / 权限错误
|
||||
- [ ] ✅ 两个实例可同时运行(18006 + 18007),无端口冲突
|
||||
- [ ] ✅ Docker 卷挂载正常,数据持久化工作
|
||||
- [ ] ✅ 容器重启后数据不丢失
|
||||
- [ ] ✅ 与本地 Portal (server.mjs) 集成测试通过(可选,需代理配置)
|
||||
|
||||
完成上述检查后,记录以下信息供 103 部署参考:
|
||||
|
||||
```markdown
|
||||
## 镜像交付信息
|
||||
|
||||
- **镜像名称:** ghcr.io/your-org/memind/goosed:latest
|
||||
- **镜像大小:** ~50MB
|
||||
- **运行用户:** goose (UID 1000)
|
||||
- **开放端口:** 18006
|
||||
- **数据目录:** /home/goose/.local/share/goose
|
||||
- **所需环境变量:** GOOSE_SERVER__SECRET_KEY(必填)
|
||||
- **健康检查:** GET http://127.0.0.1:18006/status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1:构建失败 - "cargo not found"
|
||||
|
||||
**A:** Dockerfile 内部会安装 Rust,不需要本地 cargo。如果失败,检查:
|
||||
|
||||
```bash
|
||||
# 清空 Docker 构建缓存
|
||||
docker buildx prune -a
|
||||
|
||||
# 重新构建
|
||||
docker build --no-cache -f tkmind_go/Dockerfile.goosed -t tkmind/goosed:local tkmind_go/
|
||||
```
|
||||
|
||||
### Q2:容器启动后立即退出
|
||||
|
||||
**A:** 查看日志获得错误信息:
|
||||
|
||||
```bash
|
||||
docker logs <container-id>
|
||||
|
||||
# 常见原因:
|
||||
# 1. GOOSE_SERVER__SECRET_KEY 缺失
|
||||
# 2. 数据卷权限不足(goose 用户无写权限)
|
||||
# 3. SQLite 数据库损坏
|
||||
```
|
||||
|
||||
### Q3:容器内 /status 返回 404
|
||||
|
||||
**A:** goosed 服务可能未就绪或崩溃:
|
||||
|
||||
```bash
|
||||
# 检查进程
|
||||
docker exec goosed-test ps aux | grep goosed
|
||||
|
||||
# 检查监听端口
|
||||
docker exec goosed-test netstat -tlnp
|
||||
|
||||
# 查看完整日志
|
||||
docker logs goosed-test
|
||||
```
|
||||
|
||||
### Q4:Session 数据在哪里?
|
||||
|
||||
**A:** SQLite 数据库位置:
|
||||
|
||||
```bash
|
||||
# 卷挂载位置(宿主机)
|
||||
docker volume inspect goosed-test-data
|
||||
# 查看 "Mountpoint" 字段
|
||||
|
||||
# 容器内路径
|
||||
docker exec goosed-test ls -la /home/goose/.local/share/goose/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 清理
|
||||
|
||||
```bash
|
||||
# 停止单个容器
|
||||
docker stop goosed-test
|
||||
docker rm goosed-test
|
||||
docker volume rm goosed-test-data
|
||||
|
||||
# 或使用 Compose
|
||||
docker-compose -f docker-compose.local.yml down -v
|
||||
|
||||
# 清理所有本地镜像/容器(谨慎!)
|
||||
docker system prune -a
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 下一步(不在本阶段执行)
|
||||
|
||||
一旦本地验证通过,部署到 103 时需要:
|
||||
|
||||
1. 203 上安装 Docker / Podman
|
||||
2. 配置镜像仓库凭证(ghcr.io pull token)
|
||||
3. 编写 systemd 服务或 compose 文件(103 端)
|
||||
4. Session 存储迁移计划(SQLite → PostgreSQL,参考 `goose-session-postgres-migration.md`)
|
||||
5. 回滚方案(若有问题快速降级)
|
||||
|
||||
**当前阶段:仅本地验证。**
|
||||
@@ -0,0 +1,361 @@
|
||||
# Goosed 本地构建与交付方案
|
||||
|
||||
> **方案特点:** 完全本地化,no CI/CD 服务器,手工构建 + 手工交付。
|
||||
> **适用场景:** 开发验证阶段,103 部署前的完整测试。
|
||||
|
||||
## 📊 整体流程
|
||||
|
||||
```
|
||||
代码变更
|
||||
↓
|
||||
git commit & git push (to git.tkmind.cn)
|
||||
↓
|
||||
本地手工构建
|
||||
├─ bash scripts/verify-goosed-docker.sh local
|
||||
└─ docker image: tkmind/goosed:local
|
||||
↓
|
||||
本地验证通过 ✅(1–2 周)
|
||||
↓
|
||||
镜像交付 → 103(两个选项)
|
||||
├─ 选项 A: docker save + scp
|
||||
└─ 选项 B: docker push (if Registry)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 第一步:环境检查(初次一次性)
|
||||
|
||||
### 本地机器准备
|
||||
|
||||
```bash
|
||||
# 1. 检查 Docker 版本
|
||||
docker --version
|
||||
# 需要: 20.10+
|
||||
|
||||
# 2. 检查 Docker Compose
|
||||
docker-compose --version
|
||||
# 需要: 2.0+
|
||||
|
||||
# 3. 检查磁盘空间
|
||||
df -h | grep "/$"
|
||||
# 需要: 至少 5GB 空闲(Rust 编译会用 2–3GB)
|
||||
|
||||
# 4. 测试 Docker 构建
|
||||
docker build --version
|
||||
```
|
||||
|
||||
### Git 配置确认
|
||||
|
||||
```bash
|
||||
cd /Users/john/PycharmProjects/test/test-memind
|
||||
|
||||
# 确认 origin 指向 git.tkmind.cn
|
||||
git remote -v
|
||||
# origin git@git.tkmind.cn:tkmind/memind.git (fetch)
|
||||
# origin git@git.tkmind.cn:tkmind/memind.git (push)
|
||||
|
||||
# 确认分支
|
||||
git branch -a
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 第二步:代码变更与提交
|
||||
|
||||
### 开发流程
|
||||
|
||||
```bash
|
||||
# 1. 拉取最新代码
|
||||
git pull origin main
|
||||
|
||||
# 2. 本地开发(修改代码、测试等)
|
||||
# ...your changes...
|
||||
|
||||
# 3. 提交到 git.tkmind.cn
|
||||
git add .
|
||||
git commit -m "你的变更说明"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### 验证提交
|
||||
|
||||
```bash
|
||||
# 检查代码是否已推送到 git.tkmind.cn
|
||||
git log -1 --oneline # 查看最新 commit
|
||||
git push -u origin main # 确保推送
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 第三步:本地构建镜像
|
||||
|
||||
### 方式 A:使用验证脚本(推荐)
|
||||
|
||||
```bash
|
||||
cd /Users/john/PycharmProjects/test/test-memind
|
||||
|
||||
# 一键构建 + 启动 + 验证
|
||||
bash scripts/verify-goosed-docker.sh local
|
||||
|
||||
# 脚本会:
|
||||
# 1. 构建镜像 (8–12 分钟)
|
||||
# 2. 启动容器
|
||||
# 3. 等待容器就绪
|
||||
# 4. 显示测试命令
|
||||
```
|
||||
|
||||
### 方式 B:手工 docker build(更细致控制)
|
||||
|
||||
```bash
|
||||
cd /Users/john/PycharmProjects/test/test-memind
|
||||
|
||||
# 构建镜像
|
||||
docker build -f tkmind_go/Dockerfile.goosed \
|
||||
-t tkmind/goosed:local \
|
||||
tkmind_go/
|
||||
|
||||
# 验证镜像
|
||||
docker images | grep goosed
|
||||
# tkmind/goosed local 50MB
|
||||
|
||||
# 启动容器
|
||||
docker run -d --name goosed-test \
|
||||
-p 18006:18006 \
|
||||
-e GOOSE_HOST=0.0.0.0 \
|
||||
-e GOOSE_PORT=18006 \
|
||||
-e GOOSE_SERVER__SECRET_KEY=test-secret \
|
||||
-v goosed-test-data:/home/goose/.local/share/goose \
|
||||
tkmind/goosed:local
|
||||
|
||||
# 健康检查
|
||||
curl http://127.0.0.1:18006/status
|
||||
|
||||
# 查看日志
|
||||
docker logs goosed-test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 第四步:本地验证
|
||||
|
||||
### 快速检查
|
||||
|
||||
```bash
|
||||
# 1. 端点是否响应
|
||||
curl -s http://127.0.0.1:18006/status | jq .
|
||||
|
||||
# 2. 容器进程是否运行
|
||||
docker ps | grep goosed
|
||||
|
||||
# 3. 日志是否正常
|
||||
docker logs goosed-test | tail -20
|
||||
|
||||
# 4. 资源使用(应该正常)
|
||||
docker stats goosed-test
|
||||
```
|
||||
|
||||
### 完整验证(可选但推荐)
|
||||
|
||||
```bash
|
||||
# 1. 启动两个实例(模拟 103 场景)
|
||||
docker-compose -f docker-compose.local.yml up -d
|
||||
|
||||
# 2. 监控资源
|
||||
docker stats goosed-1 goosed-2
|
||||
|
||||
# 3. 测试持久化
|
||||
docker-compose -f docker-compose.local.yml down -v
|
||||
docker-compose -f docker-compose.local.yml up -d
|
||||
# 验证 Session 数据是否保留
|
||||
|
||||
# 4. 清理
|
||||
docker-compose -f docker-compose.local.yml down -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 第五步:镜像交付(供 103 使用)
|
||||
|
||||
### 选项 A:保存为文件(适合离线传输)
|
||||
|
||||
```bash
|
||||
# 1. 保存镜像到 tar 文件
|
||||
docker save tkmind/goosed:local -o goosed.tar
|
||||
|
||||
# 2. 检查文件大小
|
||||
ls -lh goosed.tar
|
||||
# 大约 50–80MB
|
||||
|
||||
# 3. 传输到 103
|
||||
# 方式 1: 通过 scp
|
||||
scp goosed.tar john@103:~/incoming/
|
||||
|
||||
# 方式 2: 通过 rsync
|
||||
rsync -av goosed.tar john@103:~/incoming/
|
||||
|
||||
# 4. 在 103 上导入(后续操作)
|
||||
# docker load -i goosed.tar
|
||||
```
|
||||
|
||||
### 选项 B:直接推送(需要 Docker Registry)
|
||||
|
||||
如果 103 上有 Docker Registry(Harbor / Local Registry):
|
||||
|
||||
```bash
|
||||
# 1. 标记镜像
|
||||
docker tag tkmind/goosed:local registry.tkmind.cn/goosed:v1
|
||||
|
||||
# 2. 推送
|
||||
docker push registry.tkmind.cn/goosed:v1
|
||||
|
||||
# 3. 在 103 上拉取
|
||||
# docker pull registry.tkmind.cn/goosed:v1
|
||||
```
|
||||
|
||||
### 选项 C:使用 Gitea Container Registry(如已启用)
|
||||
|
||||
```bash
|
||||
# 1. 登录 Gitea Registry
|
||||
# 需要先生成 Gitea token: https://git.tkmind.cn/user/settings/applications
|
||||
|
||||
docker login git.tkmind.cn -u your-username -p your-token
|
||||
|
||||
# 2. 标记镜像
|
||||
docker tag tkmind/goosed:local git.tkmind.cn/tkmind/goosed:latest
|
||||
|
||||
# 3. 推送
|
||||
docker push git.tkmind.cn/tkmind/goosed:latest
|
||||
|
||||
# 4. 在 103 上拉取
|
||||
# docker pull git.tkmind.cn/tkmind/goosed:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 验证检查清单
|
||||
|
||||
在认为"本地验证完成"前,确保以下都通过:
|
||||
|
||||
- [ ] ✅ Docker 镜像成功构建,无编译错误
|
||||
- [ ] ✅ 容器启动无异常,`/status` 端点返回 200
|
||||
- [ ] ✅ Session SQLite 数据库正常创建
|
||||
- [ ] ✅ 容器日志无 panic / segfault / 错误
|
||||
- [ ] ✅ 两实例同时运行(18006 + 18007)无冲突
|
||||
- [ ] ✅ 容器重启后数据持久化(卷挂载正常)
|
||||
- [ ] ✅ 性能稳定(至少 1 小时无异常)
|
||||
- [ ] ✅ 镜像文件成功保存或推送
|
||||
|
||||
**以上全部通过 = 本地验证完成,可进行 103 部署。**
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1:构建失败 - Rust 下载超时
|
||||
|
||||
**A:** Rust 镜像下载可能受网络影响。重试或配置代理:
|
||||
|
||||
```bash
|
||||
# 清空缓存重试
|
||||
docker buildx prune -a
|
||||
docker build --no-cache -f tkmind_go/Dockerfile.goosed -t tkmind/goosed:local tkmind_go/
|
||||
|
||||
# 或使用代理(如有)
|
||||
docker build --build-arg HTTP_PROXY=http://proxy:8080 \
|
||||
-f tkmind_go/Dockerfile.goosed -t tkmind/goosed:local tkmind_go/
|
||||
```
|
||||
|
||||
### Q2:容器启动后立即退出
|
||||
|
||||
**A:** 查看日志找原因:
|
||||
|
||||
```bash
|
||||
docker logs <container-id>
|
||||
|
||||
# 常见原因:
|
||||
# 1. GOOSE_SERVER__SECRET_KEY 环境变量缺失
|
||||
# 2. SQLite 权限问题(goose 用户无写权限)
|
||||
# 3. 数据卷挂载错误
|
||||
```
|
||||
|
||||
### Q3:镜像太大,无法传输
|
||||
|
||||
**A:** 可以先在 103 上 pull,或使用增量传输:
|
||||
|
||||
```bash
|
||||
# 压缩传输
|
||||
docker save tkmind/goosed:local | gzip > goosed.tar.gz
|
||||
|
||||
# 传输
|
||||
scp goosed.tar.gz john@103:~/
|
||||
|
||||
# 在 103 上解压导入
|
||||
gunzip < goosed.tar.gz | docker load
|
||||
```
|
||||
|
||||
### Q4:Session 数据在哪
|
||||
|
||||
**A:** 数据存储在 Docker 卷中:
|
||||
|
||||
```bash
|
||||
# 查看卷位置
|
||||
docker volume inspect goosed-test-data
|
||||
|
||||
# 在宿主机上访问
|
||||
cd /var/lib/docker/volumes/goosed-test-data/_data
|
||||
ls -la
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 清理与重置
|
||||
|
||||
### 停止容器和卷
|
||||
|
||||
```bash
|
||||
# 停止单个容器
|
||||
docker stop goosed-test
|
||||
docker rm goosed-test
|
||||
docker volume rm goosed-test-data
|
||||
|
||||
# 或使用 Compose
|
||||
docker-compose -f docker-compose.local.yml down -v
|
||||
|
||||
# 删除镜像(如需要)
|
||||
docker rmi tkmind/goosed:local
|
||||
```
|
||||
|
||||
### 完全清理
|
||||
|
||||
```bash
|
||||
# 清理所有 Docker 资源(谨慎)
|
||||
docker system prune -a --volumes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 交付前检查清单
|
||||
|
||||
镜像交付给 103 前:
|
||||
|
||||
- [ ] ✅ 代码已提交到 git.tkmind.cn
|
||||
- [ ] ✅ 本地验证通过至少 1 周无异常
|
||||
- [ ] ✅ 镜像文件已保存或推送
|
||||
- [ ] ✅ 团队确认 Docker 方案可行
|
||||
- [ ] ✅ 103 环境已准备(Docker daemon)
|
||||
|
||||
**完成上述检查 = 可以考虑 103 部署**
|
||||
|
||||
---
|
||||
|
||||
## 下一步(103 部署)
|
||||
|
||||
当本地验证通过后,计划 103 部署:
|
||||
|
||||
1. 在 103 上导入镜像:`docker load -i goosed.tar`
|
||||
2. 配置运行时环境(端口、卷、Secret)
|
||||
3. 启动一个容器实例进行灰度测试
|
||||
4. 监控 24–48 小时,确认稳定
|
||||
5. 若稳定,逐步增加副本数
|
||||
|
||||
**当前阶段:本地验证。** 103 部署是后续的独立议题。
|
||||
@@ -0,0 +1,240 @@
|
||||
# Goosed 本地构建方案 — 第一阶段实施计划
|
||||
|
||||
> **阶段目标:** 本地完整验证 Docker 构建方案,无生产影响。
|
||||
> **时间预期:** 1–2 周。
|
||||
> **关键特点:** 完全本地化,手工构建 + 交付,git.tkmind.cn 代码管理。
|
||||
|
||||
---
|
||||
|
||||
## 🎯 核心流程
|
||||
|
||||
```
|
||||
Step 1: 代码提交
|
||||
└─ git push origin main (to git.tkmind.cn)
|
||||
|
||||
Step 2: 本地构建
|
||||
└─ bash scripts/verify-goosed-docker.sh local
|
||||
└─ 输出: tkmind/goosed:local 镜像
|
||||
|
||||
Step 3: 本地验证 (1–2 周)
|
||||
├─ docker-compose up -d
|
||||
├─ 运行测试、监控、性能测试
|
||||
└─ 确认稳定
|
||||
|
||||
Step 4: 镜像交付
|
||||
├─ docker save goosed.tar
|
||||
└─ scp 到 103 (后续部署)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 你需要的文件(最终清单)
|
||||
|
||||
| 文件 | 用途 | 状态 |
|
||||
|------|-----|------|
|
||||
| `scripts/verify-goosed-docker.sh` | 本地一键构建 | ✅ 已完成 |
|
||||
| `docker-compose.local.yml` | 本地开发环境 | ✅ 已完成 |
|
||||
| `docs/goosed-docker-local-verification.md` | 测试指南 | ✅ 已完成 |
|
||||
| `docs/goosed-local-build-delivery.md` | 构建 + 交付说明 | ✅ 已完成 |
|
||||
| `docs/goosed-phase1-local-plan.md` | 本计划 | ✅ 已完成 |
|
||||
|
||||
**删除的文件:**
|
||||
- ❌ `.github/workflows/build-goosed.yml`(GitHub Actions,不需要)
|
||||
- ❌ `docs/ghcr-setup.md`(ghcr.io,不需要)
|
||||
- ❌ `docs/goosed-ci-implementation-plan.md`(CI/CD,不需要)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 立即开始(今天)
|
||||
|
||||
### Step 1:提交文件到 git.tkmind.cn
|
||||
|
||||
```bash
|
||||
cd /Users/john/PycharmProjects/test/test-memind
|
||||
|
||||
# 查看修改
|
||||
git status
|
||||
|
||||
# 添加文件
|
||||
git add scripts/verify-goosed-docker.sh \
|
||||
docker-compose.local.yml \
|
||||
docs/goosed-docker-local-verification.md \
|
||||
docs/goosed-local-build-delivery.md \
|
||||
docs/goosed-phase1-local-plan.md
|
||||
|
||||
# 提交
|
||||
git commit -m "feat: goosed 本地 Docker 构建方案 (第一阶段)
|
||||
|
||||
- scripts/verify-goosed-docker.sh: 一键本地构建脚本
|
||||
- docker-compose.local.yml: 本地开发环境
|
||||
- docs/goosed-docker-local-verification.md: 本地测试指南
|
||||
- docs/goosed-local-build-delivery.md: 构建交付方案
|
||||
- docs/goosed-phase1-local-plan.md: 实施计划
|
||||
|
||||
特点:完全本地化,无 CI 依赖,手工构建 + 交付。
|
||||
时间预期:1-2 周本地验证。"
|
||||
|
||||
# 推送到 git.tkmind.cn
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### Step 2:本地验证(立即运行)
|
||||
|
||||
```bash
|
||||
# 进入项目目录
|
||||
cd /Users/john/PycharmProjects/test/test-memind
|
||||
|
||||
# 一键构建 + 验证
|
||||
bash scripts/verify-goosed-docker.sh local
|
||||
|
||||
# 预期输出(8–12 分钟)
|
||||
# ✅ 镜像构建完成
|
||||
# ✅ 容器已启动
|
||||
# ✅ 容器已就绪
|
||||
```
|
||||
|
||||
### Step 3:容器测试
|
||||
|
||||
```bash
|
||||
# 脚本会显示测试命令,按提示执行即可
|
||||
# 例如:
|
||||
|
||||
# 查看容器状态
|
||||
docker ps | grep goosed
|
||||
|
||||
# 检查健康状态
|
||||
curl http://127.0.0.1:18006/status
|
||||
|
||||
# 查看日志
|
||||
docker logs -f <container-id>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 一周的验证计划
|
||||
|
||||
| 天 | 任务 | 预期 |
|
||||
|---|-----|-----|
|
||||
| **Day 1** | 代码提交 + 首次本地构建 | ✅ 镜像构建成功 |
|
||||
| **Day 2–3** | 单实例运行测试 (18006) | ✅ 容器稳定运行 |
|
||||
| **Day 4–5** | Docker Compose 双实例测试 | ✅ 两实例无冲突 |
|
||||
| **Day 6–7** | 长时间运行测试(持续监控) | ✅ 7 天无异常 |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 本地验证完成标准
|
||||
|
||||
以下全部 ✅ 后,认为第一阶段完成:
|
||||
|
||||
- [ ] ✅ 代码已提交到 git.tkmind.cn
|
||||
- [ ] ✅ 本地 Docker 构建成功(无错误)
|
||||
- [ ] ✅ 镜像大小合理(~50–80MB)
|
||||
- [ ] ✅ 容器启动正常,`/status` 返回 200
|
||||
- [ ] ✅ Session 数据库(SQLite)正常创建
|
||||
- [ ] ✅ 容器日志无 panic / 错误
|
||||
- [ ] ✅ 两实例并行运行无冲突
|
||||
- [ ] ✅ 容器重启后数据持久化
|
||||
- [ ] ✅ 运行至少 7 天无异常
|
||||
- [ ] ✅ 镜像文件已保存(goosed.tar)
|
||||
|
||||
---
|
||||
|
||||
## 🔄 持续开发流程
|
||||
|
||||
第一阶段期间,如需修改代码:
|
||||
|
||||
```bash
|
||||
# 1. 本地修改代码
|
||||
# ...your changes...
|
||||
|
||||
# 2. 本地测试(如需要重新构建)
|
||||
bash scripts/verify-goosed-docker.sh local
|
||||
|
||||
# 3. 提交代码
|
||||
git add .
|
||||
git commit -m "fix: ..."
|
||||
git push origin main
|
||||
|
||||
# 4. 继续本地验证
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 镜像交付(第一阶段末)
|
||||
|
||||
当本地验证通过 1 周后:
|
||||
|
||||
### 方式 1:保存为文件(最简单)
|
||||
|
||||
```bash
|
||||
# 保存最新验证通过的镜像
|
||||
docker save tkmind/goosed:local -o goosed-verified.tar
|
||||
|
||||
# 准备交付给 103(后续操作)
|
||||
ls -lh goosed-verified.tar
|
||||
# 约 50–80MB
|
||||
```
|
||||
|
||||
### 方式 2:标记版本
|
||||
|
||||
```bash
|
||||
# 给验证通过的镜像打版本标签
|
||||
docker tag tkmind/goosed:local tkmind/goosed:v1.0-local
|
||||
|
||||
# 后续交付时使用 v1.0-local 标记
|
||||
docker save tkmind/goosed:v1.0-local -o goosed-v1.0.tar
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ❓ 常见问题
|
||||
|
||||
### Q:什么时候推送到 git.tkmind.cn?
|
||||
|
||||
**A:** 立即推送。这是代码版本管理,与镜像构建独立。镜像是本地产物,不需要推送到 Git。
|
||||
|
||||
### Q:镜像要保存到哪里?
|
||||
|
||||
**A:** 本地 Docker 中即可。当需要部署到 103 时,再用 `docker save` 导出为文件。
|
||||
|
||||
### Q:如果代码有变更怎么办?
|
||||
|
||||
**A:**
|
||||
1. 修改代码 → `git push`
|
||||
2. 重新 `bash scripts/verify-goosed-docker.sh local`
|
||||
3. 继续测试
|
||||
|
||||
### Q:第一阶段需要与 103 通信吗?
|
||||
|
||||
**A:** 不需要。完全本地独立。103 部署是后续的第二阶段。
|
||||
|
||||
### Q:验证需要多久?
|
||||
|
||||
**A:** 建议至少 1 周。如果发现问题,修复后重新计时。
|
||||
|
||||
---
|
||||
|
||||
## 🛑 何时停止本地验证,考虑 103?
|
||||
|
||||
当满足以下条件时:
|
||||
|
||||
- ✅ 本地验证稳定运行 7+ 天
|
||||
- ✅ 所有检查清单项都通过
|
||||
- ✅ 团队确认 Docker 方案可行
|
||||
- ✅ 103 环境已准备就绪(Docker daemon)
|
||||
|
||||
**不满足上述条件,继续本地验证,不要急着上 103。**
|
||||
|
||||
---
|
||||
|
||||
## 📞 遇到问题?
|
||||
|
||||
参考这些文档:
|
||||
|
||||
1. **构建失败?** → `docs/goosed-docker-local-verification.md` 的"常见问题"
|
||||
2. **交付方式?** → `docs/goosed-local-build-delivery.md` 的"镜像交付"
|
||||
3. **测试步骤?** → `docs/goosed-docker-local-verification.md` 的"测试与验证"
|
||||
|
||||
---
|
||||
|
||||
**现在:立即推送代码并运行本地构建!**
|
||||
Executable
+108
@@ -0,0 +1,108 @@
|
||||
#!/bin/bash
|
||||
# 本地验证 goosed Docker 镜像构建 & 运行
|
||||
# 用法: bash scripts/verify-goosed-docker.sh [tag]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TAG="${1:-local}"
|
||||
IMAGE_NAME="tkmind/goosed:${TAG}"
|
||||
CONTAINER_NAME="goosed-test-$$"
|
||||
PORT=${GOOSE_PORT:-18006}
|
||||
SECRET_KEY="${GOOSE_SERVER__SECRET_KEY:-test-secret-key-$(date +%s)}"
|
||||
|
||||
echo "=== Goosed Docker 镜像验证 ==="
|
||||
echo "Image: $IMAGE_NAME"
|
||||
echo "Port: $PORT"
|
||||
echo ""
|
||||
|
||||
cleanup() {
|
||||
echo "🧹 清理测试容器..."
|
||||
docker rm -f "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker volume rm goosed-test-$$-data 2>/dev/null || true
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
# 1. 构建镜像(如果是 local 标签)
|
||||
if [[ "$TAG" == "local" ]]; then
|
||||
echo "📦 Step 1: 构建 Docker 镜像..."
|
||||
docker build \
|
||||
-f tkmind_go/Dockerfile.goosed \
|
||||
-t "$IMAGE_NAME" \
|
||||
tkmind_go/
|
||||
echo "✅ 镜像构建完成"
|
||||
else
|
||||
echo "📥 Step 1: 拉取远程镜像..."
|
||||
docker pull "$IMAGE_NAME"
|
||||
echo "✅ 镜像拉取完成"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🚀 Step 2: 启动容器..."
|
||||
|
||||
# 2. 创建数据卷
|
||||
docker volume create "goosed-test-$$-data" || true
|
||||
|
||||
# 3. 启动容器
|
||||
docker run -d \
|
||||
--name "$CONTAINER_NAME" \
|
||||
-p "${PORT}:18006" \
|
||||
-e GOOSE_HOST=0.0.0.0 \
|
||||
-e GOOSE_PORT=18006 \
|
||||
-e "GOOSE_SERVER__SECRET_KEY=${SECRET_KEY}" \
|
||||
-v "goosed-test-$$-data:/home/goose/.local/share/goose" \
|
||||
"$IMAGE_NAME" \
|
||||
agent
|
||||
|
||||
echo "✅ 容器已启动: $CONTAINER_NAME (PID: $(docker inspect -f '{{.State.Pid}}' "$CONTAINER_NAME"))"
|
||||
|
||||
# 4. 等待容器就绪
|
||||
echo ""
|
||||
echo "⏳ Step 3: 等待容器就绪(最多 30 秒)..."
|
||||
for i in {1..30}; do
|
||||
if docker exec "$CONTAINER_NAME" curl -sf "http://127.0.0.1:18006/status" >/dev/null 2>&1; then
|
||||
echo "✅ 容器已就绪"
|
||||
break
|
||||
fi
|
||||
if [[ $i -eq 30 ]]; then
|
||||
echo "❌ 容器启动超时"
|
||||
docker logs "$CONTAINER_NAME"
|
||||
exit 1
|
||||
fi
|
||||
echo " ⏳ 等待中... ($i/30)"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# 5. 健康检查
|
||||
echo ""
|
||||
echo "🏥 Step 4: 健康检查..."
|
||||
STATUS=$(docker exec "$CONTAINER_NAME" curl -s "http://127.0.0.1:18006/status" || echo '{}')
|
||||
echo "Status: $STATUS"
|
||||
|
||||
# 6. 容器日志
|
||||
echo ""
|
||||
echo "📋 Step 5: 容器日志(最后 10 行)..."
|
||||
docker logs "$CONTAINER_NAME" 2>&1 | tail -10
|
||||
|
||||
echo ""
|
||||
echo "✅ 验证完成!"
|
||||
echo ""
|
||||
echo "容器信息:"
|
||||
docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Ports}}\t{{.Status}}"
|
||||
|
||||
echo ""
|
||||
echo "🧪 测试命令示例:"
|
||||
echo " # 查看状态"
|
||||
echo " curl http://127.0.0.1:${PORT}/status"
|
||||
echo ""
|
||||
echo " # 查看日志"
|
||||
echo " docker logs -f $CONTAINER_NAME"
|
||||
echo ""
|
||||
echo " # 进入容器"
|
||||
echo " docker exec -it $CONTAINER_NAME /bin/bash"
|
||||
echo ""
|
||||
echo "✋ 容器将在脚本退出时自动清理。按 Ctrl+C 停止。"
|
||||
echo ""
|
||||
|
||||
# 保持容器运行直到用户中断
|
||||
wait
|
||||
Reference in New Issue
Block a user