forked from DevOps/deploy.stack
chore: add env.cfg.example templates and clean up config files
This commit is contained in:
@@ -0,0 +1,73 @@
|
|||||||
|
# ========== 经典模式 ==========
|
||||||
|
# 如果为 true,不使用任何颜色或图标,与标准 ls 行为类似
|
||||||
|
classic: false
|
||||||
|
|
||||||
|
# ========== 分块(Blocks) ==========
|
||||||
|
# 定义每行显示哪些信息块,按顺序排列
|
||||||
|
blocks:
|
||||||
|
- permission # 文件权限 (rwxr-xr-x)
|
||||||
|
- user # 文件所有者
|
||||||
|
- group # 用户组
|
||||||
|
- size # 文件大小
|
||||||
|
- date # 日期/时间
|
||||||
|
- name # 文件名(必须包含)
|
||||||
|
|
||||||
|
# ========== 颜色主题 ==========
|
||||||
|
color:
|
||||||
|
# 何时使用颜色:always(总是)、auto(自动)、never(从不)
|
||||||
|
when: auto
|
||||||
|
|
||||||
|
# 自定义文件类型颜色(覆盖默认值)
|
||||||
|
theme: custom
|
||||||
|
|
||||||
|
# ========== 日期格式 ==========
|
||||||
|
date: "+%Y-%m-%d %H:%M:%S" # 可选:relative(相对时间)、iso(ISO格式)
|
||||||
|
|
||||||
|
# ========== 跟随符号链接 ============
|
||||||
|
dereference: false
|
||||||
|
|
||||||
|
# ========== 图标 ==========
|
||||||
|
icons:
|
||||||
|
# 何时显示图标:always、auto、never
|
||||||
|
when: auto
|
||||||
|
|
||||||
|
# 图标主题(需要对应的 Nerd Font)
|
||||||
|
theme: fancy # 或 unicode
|
||||||
|
|
||||||
|
# 分隔符(图标与文件名之间的字符)
|
||||||
|
separator: " "
|
||||||
|
|
||||||
|
# ========== 忽略选项 ==========
|
||||||
|
ignore-globs:
|
||||||
|
- "*.bak" # 忽略所有 .bak 文件
|
||||||
|
- ".git" # 忽略 .git 目录
|
||||||
|
- "__pycache__" # 忽略 Python 缓存
|
||||||
|
|
||||||
|
# ========== 布局 ==========
|
||||||
|
layout: grid # grid(网格)| tree(树状)| oneline(单行)
|
||||||
|
|
||||||
|
# ========== 递归深度(--tree 时有效) ==========
|
||||||
|
recursion:
|
||||||
|
enabled: false
|
||||||
|
depth: 3 # 递归显示的最大深度
|
||||||
|
|
||||||
|
# ========== 排序 ==========
|
||||||
|
sorting:
|
||||||
|
column: name # 排序字段:name、size、time、version、extension
|
||||||
|
# reverse: false # 是否倒序
|
||||||
|
# dir-grouping: first # 目录排序:first(靠前)、last(靠后)、none
|
||||||
|
|
||||||
|
# ========== 符号链接 ==========
|
||||||
|
# 是否显示符号链接的目标路径
|
||||||
|
no-symlink: false
|
||||||
|
symlink-arrow: " ➜ "
|
||||||
|
|
||||||
|
# ========== 总大小 ==========
|
||||||
|
total-size: false # 是否显示总大小(在目录底部)
|
||||||
|
|
||||||
|
# ========== 截断所有者名 ==========
|
||||||
|
truncate-owner:
|
||||||
|
after: 8 # 用户名超过多少字符截断
|
||||||
|
|
||||||
|
# ========== 超链接 ==========
|
||||||
|
hyperlink: never # always | auto | never 是否生成终端超链接
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# 文件类型颜色
|
||||||
|
file-type:
|
||||||
|
directory:
|
||||||
|
foreground: cyan
|
||||||
|
bold: true
|
||||||
|
symlink:
|
||||||
|
foreground: magenta
|
||||||
|
italic: true
|
||||||
|
executable:
|
||||||
|
foreground: green
|
||||||
|
bold: true
|
||||||
|
socket:
|
||||||
|
foreground: red
|
||||||
|
pipe:
|
||||||
|
foreground: yellow
|
||||||
|
block-device:
|
||||||
|
foreground: red
|
||||||
|
char-device:
|
||||||
|
foreground: yellow
|
||||||
|
|
||||||
|
# 文件扩展名颜色(覆盖文件类型颜色)
|
||||||
|
extensions:
|
||||||
|
rs:
|
||||||
|
foreground: white
|
||||||
|
bold: true
|
||||||
|
py:
|
||||||
|
foreground: yellow
|
||||||
|
js:
|
||||||
|
foreground: green
|
||||||
|
md:
|
||||||
|
foreground: cyan
|
||||||
|
italic: true
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# 强制 LF 行尾(防止 Windows 工具引入 CRLF 导致 bash 报错)
|
||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
# 显式标记常见脚本/配置类型
|
||||||
|
*.sh eol=lf
|
||||||
|
*.bash eol=lf
|
||||||
|
*.py eol=lf
|
||||||
|
*.md eol=lf
|
||||||
|
*.yml eol=lf
|
||||||
|
*.yaml eol=lf
|
||||||
|
*.cfg eol=lf
|
||||||
|
*.example eol=lf
|
||||||
|
Dockerfile eol=lf
|
||||||
+11
-1
@@ -1,8 +1,11 @@
|
|||||||
# Docker相关
|
# Docker相关
|
||||||
.env
|
.env
|
||||||
|
*.env
|
||||||
*.env.*
|
*.env.*
|
||||||
|
*.env.cfg.*
|
||||||
docker-compose.override.yml
|
docker-compose.override.yml
|
||||||
|
|
||||||
|
|
||||||
# 开发环境
|
# 开发环境
|
||||||
.idea/
|
.idea/
|
||||||
.vscode/
|
.vscode/
|
||||||
@@ -25,8 +28,15 @@ crontab/debug_*.py
|
|||||||
crontab/test_*.py
|
crontab/test_*.py
|
||||||
crontab/test*.py
|
crontab/test*.py
|
||||||
g-b/*
|
g-b/*
|
||||||
.gitignore
|
|
||||||
mcptime/go.sum
|
mcptime/go.sum
|
||||||
mcpTimeServer/go.sum
|
mcpTimeServer/go.sum
|
||||||
mcp_server_go/config.toml
|
mcp_server_go/config.toml
|
||||||
compare_images.py
|
compare_images.py
|
||||||
|
env.cfg
|
||||||
|
env.cfg.*
|
||||||
|
stack.yml.*
|
||||||
|
|
||||||
|
# 例外:env 模板(不视为敏感配置)允许提交
|
||||||
|
!**/*.env.example
|
||||||
|
!**/*.env.cfg.example
|
||||||
|
!**/env.cfg.example
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
```
|
```
|
||||||
<service>/
|
<service>/
|
||||||
├── stack.yml / compose.yml / <env>.stack.yml / <env>.yml # Docker Compose 文件
|
├── stack.yml / compose.yml / <env>.stack.yml / <env>.yml # Docker Compose 文件
|
||||||
├── env.cfg # 环境变量(含敏感信息,应 gitignore)
|
├── env.cfg.example # 环境变量(含敏感信息,应 gitignore)
|
||||||
├── readme.md # 服务说明文档(可选)
|
├── readme.md # 服务说明文档(可选)
|
||||||
└── config/ # 服务配置文件(可选)
|
└── config/ # 服务配置文件(可选)
|
||||||
```
|
```
|
||||||
|
|
||||||
顶层目录按职责划分:
|
顶层目录按职责划分:
|
||||||
@@ -132,6 +132,7 @@ docker compose -p <名称> --env-file ./builder/golang/env.cfg -f ./builder/gola
|
|||||||
- **国内镜像源**:Dockerfile 和 apt 配置默认使用国内 CDN 镜像(中科大、阿里云、华为),部署在其他地区需修改。
|
- **国内镜像源**:Dockerfile 和 apt 配置默认使用国内 CDN 镜像(中科大、阿里云、华为),部署在其他地区需修改。
|
||||||
- **Portainer Docker 兼容性**:Portainer CE LTS < 2.36.0 不兼容 Docker >= 29.0.0,需设置 `DOCKER_MIN_API_VERSION=1.24`。详见 `portainer-ce/readme.md`。
|
- **Portainer Docker 兼容性**:Portainer CE LTS < 2.36.0 不兼容 Docker >= 29.0.0,需设置 `DOCKER_MIN_API_VERSION=1.24`。详见 `portainer-ce/readme.md`。
|
||||||
- **i2c.py 需要硬件**:OLED 显示脚本需要树莓派 I2C 硬件、`adafruit_ssd1306` 库和中文字体(`fonts-wqy-microhei`)。
|
- **i2c.py 需要硬件**:OLED 显示脚本需要树莓派 I2C 硬件、`adafruit_ssd1306` 库和中文字体(`fonts-wqy-microhei`)。
|
||||||
|
- **shell 脚本禁用 CRLF**:仓库根目录的 `.gitattributes` 已强制 `*.sh` / `*.bash` / `*.py` / `*.md` / `*.yml` / `*.cfg` 等文本 LF 行尾。Windows 工具(IDE agent、记事本、PowerShell)默认写 CRLF,会导致 Linux 上 `'\r': 未找到命令` 和 `function xxx() {` 语法错误。**新建或修改脚本后必须 `file <script>` 验证输出不含 `CRLF line terminators`**,如果命中立即 `sed -i 's/\r$//' <script>` 修正。
|
||||||
|
|
||||||
## 系统配置(etc/)
|
## 系统配置(etc/)
|
||||||
|
|
||||||
@@ -141,3 +142,261 @@ docker compose -p <名称> --env-file ./builder/golang/env.cfg -f ./builder/gola
|
|||||||
- 连接队列大小(somaxconn、syn backlog)
|
- 连接队列大小(somaxconn、syn backlog)
|
||||||
- 内存管理(swappiness、脏页阈值)
|
- 内存管理(swappiness、脏页阈值)
|
||||||
- 安全加固(ICMP 重定向拒绝、反向路径过滤、kptr_restrict)
|
- 安全加固(ICMP 重定向拒绝、反向路径过滤、kptr_restrict)
|
||||||
|
|
||||||
|
## Git 提交规范
|
||||||
|
|
||||||
|
### Commit Message 格式
|
||||||
|
|
||||||
|
本仓库 commit message **优先使用 Conventional Commits** 规范,与历史风格保持一致。格式:
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>(<scope>): <subject> # 中文
|
||||||
|
<type>(<scope>): <subject> # 英文
|
||||||
|
```
|
||||||
|
|
||||||
|
### Type 类型
|
||||||
|
|
||||||
|
| Type | 用途 | 示例 |
|
||||||
|
| ---------- | ------------------------------------ | --------------------------------------------- |
|
||||||
|
| `feat` | 新增服务/新功能 | `feat: add adminer docker deployment files` |
|
||||||
|
| `fix` | 修复 bug | `fix(gitea): 修复备份脚本权限问题` |
|
||||||
|
| `docs` | 文档变更(readme、AGENTS.md 等) | `docs: 添加git提交信息规则文件` |
|
||||||
|
| `refactor` | 重构(不改功能) | `refactor(status.py): 重构OLED状态显示代码` |
|
||||||
|
| `perf` | 性能优化 | `perf(redis): 调整内存淘汰策略` |
|
||||||
|
| `build` | 构建相关(Dockerfile、compose、依赖)| `build(moltbot): 添加生产环境docker compose` |
|
||||||
|
| `chore` | 杂项(版本号、配置、镜像标签) | `chore: 更新 Joplin 服务器镜像版本至 3.6.1` |
|
||||||
|
| `style` | 格式调整(不影响代码逻辑) | `style: 统一 yaml 缩进为 2 空格` |
|
||||||
|
| `test` | 测试相关 | `test: 添加 memos 部署验证脚本` |
|
||||||
|
|
||||||
|
### Scope 范围(可选)
|
||||||
|
|
||||||
|
- 服务名(目录名小写):`gitea`、`memos`、`haproxy`、`postgres`、`portainer-ce` 等
|
||||||
|
- 顶层目录:`builder`、`crontab`、`etc`、`shell`、`i2c.py`
|
||||||
|
- 省略:当改动跨多个服务或为全局性变更
|
||||||
|
|
||||||
|
### Subject 主题规则
|
||||||
|
|
||||||
|
1. **中文项目**用中文描述,**英文项目**用英文,统一保持
|
||||||
|
2. **首字母小写**(中文不受影响)
|
||||||
|
3. **不超过 50 个字符**,尽量精炼
|
||||||
|
4. **不要句末加句号**
|
||||||
|
5. **动词开头**:添加/更新/修复/重构/删除 或 add/update/fix/refactor/remove
|
||||||
|
6. **写明对象**:要让人一眼看出改了什么
|
||||||
|
|
||||||
|
### Body 与 Footer(可选)
|
||||||
|
|
||||||
|
需要时换行后空一行写正文:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(gitea): 添加 lfs 存储后端配置
|
||||||
|
|
||||||
|
- 使用 minio 作为 lfs 对象存储
|
||||||
|
- 调整 gitea app.ini 路径映射
|
||||||
|
- 备份脚本需同步调整
|
||||||
|
|
||||||
|
Refs: #123
|
||||||
|
```
|
||||||
|
|
||||||
|
### 提交前自检
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 查看变更文件
|
||||||
|
git status
|
||||||
|
|
||||||
|
# 2. 检查 diff 大小(避免误提交敏感文件)
|
||||||
|
git diff --stat
|
||||||
|
|
||||||
|
# 3. 确认无 env.cfg / 凭据被误提交
|
||||||
|
git diff | grep -iE "password|secret|token|key" # 应无敏感输出
|
||||||
|
|
||||||
|
# 4. 暂存并提交
|
||||||
|
git add <files>
|
||||||
|
git commit -m "<type>(<scope>): <subject>"
|
||||||
|
|
||||||
|
# 5. 推送
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
### 提交粒度
|
||||||
|
|
||||||
|
- **一个 commit 只做一件事**:不要把无关改动混在一起
|
||||||
|
- **服务级别独立提交**:新增一个服务(如 `gitea/`)应该是独立 commit
|
||||||
|
- **版本号更新单独 commit**:`chore(<service>): bump image tag to x.y.z`
|
||||||
|
- **不要 commit 内容**:
|
||||||
|
- `env.cfg`(含敏感信息,已 gitignore)
|
||||||
|
- 编译产物(`*.bin`、`main`、`__pycache__/` 等)
|
||||||
|
- IDE 配置(`.vscode/`、`.idea/`)
|
||||||
|
- 系统级配置(`/data/volumes/` 下的实际数据)
|
||||||
|
|
||||||
|
### 历史风格兼容性
|
||||||
|
|
||||||
|
仓库早期 commit 有少量非 Conventional 风格(如 `Add lsd config and color theme`),
|
||||||
|
**新增 commit 一律遵循本规范**,历史风格不强制改写。
|
||||||
|
|
||||||
|
### AI 生成 commit message 的硬约束
|
||||||
|
|
||||||
|
本小节是 `## AI 协作系统级约束` 章节在 commit 场景的具体执行规则。被要求生成 commit message 时,**只输出 commit text 本身**,严禁夹带任何元评论、解释或代码块包裹。
|
||||||
|
|
||||||
|
**输出黑名单(出现即视为违规):**
|
||||||
|
|
||||||
|
- 前置说明:`我看了你的改动…`、`建议使用下面的 commit message:`、`以下为 commit:`
|
||||||
|
- 元评论词汇:`分析`、`考虑`、`由于`、`因为`、`建议`、`注意`、`这里`、`本次`、`因为需要`
|
||||||
|
- 复述 diff:把 `git diff` 的关键行直接放进 commit
|
||||||
|
- 解释"为什么改":commit 只描述"改了什么",不写动机
|
||||||
|
- 多版本候选/对比:不要 `Option 1 / Option 2` 或 `---begin--- / ---end---`
|
||||||
|
- markdown 代码块包裹:直接给纯文本,除非用户明确要求
|
||||||
|
|
||||||
|
**输出前自检清单:**
|
||||||
|
|
||||||
|
- [ ] 只包含 commit text,无任何前后缀
|
||||||
|
- [ ] subject ≤ 50 字符、无句末标点、动词开头、首字母小写
|
||||||
|
- [ ] type 在 `{feat, fix, docs, refactor, perf, build, chore, style, test}` 内
|
||||||
|
- [ ] scope 准确(服务名小写或顶层目录名)
|
||||||
|
- [ ] body 每行 ≤ 72 字符、不重复 subject
|
||||||
|
- [ ] 中英文不混用、保持与项目历史一致
|
||||||
|
- [ ] 未泄露 `password|secret|token|key` 等敏感词
|
||||||
|
|
||||||
|
**正确示例:**
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(gitea): bump image to 1.25.2
|
||||||
|
```
|
||||||
|
|
||||||
|
**错误示例(AI 常见错误):**
|
||||||
|
|
||||||
|
```
|
||||||
|
我看了你的改动,主要是更新了镜像版本,建议使用:
|
||||||
|
|
||||||
|
feat(gitea): bump image to 1.25.2
|
||||||
|
|
||||||
|
这次改动把版本从 1.24 升到 1.25.2,主要修复了…
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注意**:thinking 块属于模型内部推理,**无法在 commit 场景关闭**,但它对最终 commit 输出无污染。用户的关注点应放在“最终输出是否干净”。
|
||||||
|
|
||||||
|
## AI 协作系统级约束
|
||||||
|
|
||||||
|
本章定义 AI 助手在仓库内的系统级行为约束。`## Git 提交规范 > ### AI 生成 commit message 的硬约束` 是本约束在 commit 场景的具体执行规则,本章则覆盖所有 AI 协作场景的通用原则。
|
||||||
|
|
||||||
|
### 约束生效机制
|
||||||
|
|
||||||
|
AGENTS.md 全文在 **系统提示层级注入** AI 上下文(类似 CLAUDE.md / AGENTS.md 类机制的底层原理)。AI 收到本仓库相关请求时**必须先读取并应用**本约束——这是不可协商的,不是“参考文档”。
|
||||||
|
|
||||||
|
### 通用输出原则
|
||||||
|
|
||||||
|
任何场景下 AI 输出必须遵守:
|
||||||
|
|
||||||
|
- **不夹带元评论**:`我看了你的改动…`、`建议使用:…`、`以下为…`、`分析你的…` 等
|
||||||
|
- **不复述 diff**:把 `git diff` 关键行直接复述到回复里
|
||||||
|
- **不解释“为什么”**:commit 只描述“改了什么”,不写动机
|
||||||
|
- **不多版本候选**:`Option 1 / Option 2`、`---begin--- / ---end---` 等
|
||||||
|
- **不擅自 commit / push**:用户未明确要求时不执行 `git commit`、`git push`
|
||||||
|
- **不修改敏感文件**:`env.cfg`、Harbor `compose.yaml`、`/data/volumes/` 数据
|
||||||
|
- **不修改本文件**:AGENTS.md 由人类维护,AI 不得自行编辑
|
||||||
|
|
||||||
|
### thinking 块边界
|
||||||
|
|
||||||
|
- **thinking 块是模型内部推理**,在系统提示注入层之上,AI 无法控制是否生成
|
||||||
|
- **Zed UI 折叠显示**属于编辑器行为,不在 AGENTS.md 约束范围
|
||||||
|
- **判断“是否干净”看最终 commit text 本身**,不是 UI 渲染的折叠块
|
||||||
|
- commit 文本里出现元评论 = AI 没遵守本约束,**不是 thinking 泄漏**
|
||||||
|
|
||||||
|
### 违规处理
|
||||||
|
|
||||||
|
- **轻微违规**(输出含元评论/复述 diff):让 AI 重做,提示“严格按 AGENTS.md 系统级约束”
|
||||||
|
- **严重违规**(擅自 commit/push、修改 env.cfg):撤销操作 + 立即报告用户
|
||||||
|
- **持续违规**:考虑切换非 reasoning 模型或降低 reasoning effort
|
||||||
|
|
||||||
|
## AGENTS.md 维护规则
|
||||||
|
|
||||||
|
AGENTS.md 是给 AI 助手(Claude Code、Codex、Hermes 等)和协作者阅读的项目宪法。
|
||||||
|
它**不是写完就不动的文档**,而是要跟着仓库演进持续更新。
|
||||||
|
|
||||||
|
### 何时更新 AGENTS.md
|
||||||
|
|
||||||
|
出现以下情况之一,**必须**同步更新本文件(在同一个 PR/commit 或紧随其后):
|
||||||
|
|
||||||
|
1. **新增/删除服务**:增减顶层服务目录(如新增 `gitea/`、下线 `flame/`)
|
||||||
|
2. **架构变更**:目录结构、命名约定、文件组织方式发生调整
|
||||||
|
3. **新增通用约定**:跨多个服务复用的规则(如新的环境变量命名、新的备份策略)
|
||||||
|
4. **重大操作变更**:升级 Docker 版本、Compose 规范变更、镜像源切换
|
||||||
|
5. **AI 助手踩坑**:发现 AI 反复犯同样的错误(如改 Harbor compose.yaml、提交 env.cfg)
|
||||||
|
6. **私有仓库/凭据变动**:新增私有镜像仓库、凭据管理方式变化
|
||||||
|
|
||||||
|
### 何时**不**更新 AGENTS.md
|
||||||
|
|
||||||
|
- 单个服务的局部配置变更(写到该服务的 `readme.md`)
|
||||||
|
- 镜像版本小版本号 bump(写到该服务 `chore` commit)
|
||||||
|
- 一次性的 bug 修复
|
||||||
|
- 与项目规范无关的个人偏好
|
||||||
|
|
||||||
|
### 内容质量要求
|
||||||
|
|
||||||
|
写给 AI 看的规则必须**明确、可执行、有上下文**:
|
||||||
|
|
||||||
|
- ✅ **好的写法**:
|
||||||
|
> `harbor/compose.yaml` 是 `./prepare` 生成的输出文件,**不要手动修改**。
|
||||||
|
- ❌ **差的写法**:
|
||||||
|
> 注意 Harbor 的 compose 文件。
|
||||||
|
|
||||||
|
好的写法具备三要素:
|
||||||
|
1. **是什么**(明确对象/文件/命令)
|
||||||
|
2. **为什么**(背景/原因,让 AI 理解)
|
||||||
|
3. **怎么办**(具体操作/替代方案)
|
||||||
|
|
||||||
|
### 章节组织
|
||||||
|
|
||||||
|
新增章节时遵循现有结构:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# 标题 + 简介
|
||||||
|
|
||||||
|
## 架构与组织
|
||||||
|
## 服务规范
|
||||||
|
## 部署与运维
|
||||||
|
## 重要注意事项
|
||||||
|
## 系统配置(etc/)
|
||||||
|
## Git 提交规范
|
||||||
|
## AGENTS.md 维护规则 ← 新章节放在最后
|
||||||
|
```
|
||||||
|
|
||||||
|
- 章节顺序按 **"项目结构 → 规范 → 注意事项 → 工具/脚本 → 治理"** 排列
|
||||||
|
- 新章节优先放在文档末尾,避免大改章节编号
|
||||||
|
- 章节标题用 `##` 一级章节,**保持中文**(与全文风格一致)
|
||||||
|
|
||||||
|
### 更新流程建议
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 修改 AGENTS.md
|
||||||
|
$EDITOR AGENTS.md
|
||||||
|
|
||||||
|
# 2. 单独提交(不要和服务代码改动混在一起)
|
||||||
|
git add AGENTS.md
|
||||||
|
git commit -m "docs: <本次更新的内容>"
|
||||||
|
|
||||||
|
# 3. 推送到远程
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
典型 commit 消息:
|
||||||
|
- `docs: 补充 git 提交规范章节`
|
||||||
|
- `docs: 新增 postgres 服务的部署注意事项`
|
||||||
|
- `docs: 更新 AGENTS.md 维护规则`
|
||||||
|
- `docs: 修正 harbor compose.yaml 描述`
|
||||||
|
|
||||||
|
### 验证清单
|
||||||
|
|
||||||
|
每次更新后过一遍:
|
||||||
|
|
||||||
|
- [ ] 章节顺序合理,编号未乱
|
||||||
|
- [ ] 链接、命令路径、文件名拼写正确
|
||||||
|
- [ ] 中英文混用风格与现有章节一致
|
||||||
|
- [ ] 没有把敏感信息(密码、token)写进文档
|
||||||
|
- [ ] 涉及 AI 助手的提醒**具体到文件/命令**,不空泛
|
||||||
|
- [ ] 改动反映在 `git status` 中**只**包含 `AGENTS.md`
|
||||||
|
|
||||||
|
### 同步与传播
|
||||||
|
|
||||||
|
- 复制到其他 stack 仓库时**只复制骨架**(章节标题),不要直接复制内容
|
||||||
|
- 不同 stack 的"重要注意事项"差异很大,混用会导致 AI 误判
|
||||||
|
- 如果有 fork/PR 流程,AGENTS.md 变更要在 PR 描述里说明理由
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# ============================================================
|
||||||
|
# VaultWarden 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p VaultWarden --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
IMAGE_TAG_VER=1.36.0-alpine
|
||||||
|
|
||||||
|
IMAGE_TAG=vaultwarden/server:${IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/VaultWarden
|
||||||
|
|
||||||
|
Domain=https://passd.6t7.net
|
||||||
|
|
||||||
|
ADMIN_TOKEN=<your-token>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# ============================================================
|
||||||
|
# wg-easy 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p wg-easy --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
IMAGE_TAG_VER=15.2.2
|
||||||
|
|
||||||
|
IMAGE_TAG=hub.6t7.net/base/wg-easy:${IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/wg-easy
|
||||||
|
|
||||||
|
WG_HOST=man.tp229.com
|
||||||
|
|
||||||
|
WG_PASSWORD="<your-strong-password>"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# ============================================================
|
||||||
|
# adminer 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p adminer --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG_VER=5.4.2
|
||||||
|
|
||||||
|
IMAGE_TAG=adminer:${IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/adminer
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Adminer 部署说明
|
||||||
|
|
||||||
|
[Adminer](https://www.adminer.org/) 是一个轻量级的数据库管理工具,支持 MySQL、PostgreSQL、SQLite、MS SQL、Oracle 等多种数据库,单文件 PHP 应用,适合日常数据库运维操作。
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `stack.yml` | Docker Compose 部署配置 |
|
||||||
|
| `env.cfg` | 环境变量(镜像版本) |
|
||||||
|
|
||||||
|
## 部署命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 拉取镜像
|
||||||
|
docker compose -p adminer --env-file ./adminer/env.cfg -f ./adminer/stack.yml pull
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
docker compose -p adminer --env-file ./adminer/env.cfg -f ./adminer/stack.yml up -d
|
||||||
|
|
||||||
|
# 停止服务
|
||||||
|
docker compose -p adminer --env-file ./adminer/env.cfg -f ./adminer/stack.yml down
|
||||||
|
```
|
||||||
|
|
||||||
|
## 环境变量说明
|
||||||
|
|
||||||
|
| 变量 | 说明 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| `IMAGE_TAG_VER` | Adminer 镜像版本 | `5.4.2` |
|
||||||
|
| `IMAGE_TAG` | 完整镜像标签 | `adminer:5.4.2` |
|
||||||
|
| `Volumes_Path` | 数据卷宿主机路径 | `/data/volumes/adminer` |
|
||||||
|
|
||||||
|
## 访问服务
|
||||||
|
|
||||||
|
- 默认端口:`8080`
|
||||||
|
- 访问地址:`http://<主机IP>:8080`
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
- Adminer 本身无持久化数据,容器重建不影响使用
|
||||||
|
- 连接数据库时使用数据库容器的服务名或内网 IP,而非 localhost
|
||||||
|
- 建议仅在内部网络使用,不要直接暴露到公网
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# pull:: docker compose -p adminer --env-file ./adminer/env.cfg -f ./adminer/stack.yml pull
|
||||||
|
# run:: docker compose -p adminer --env-file ./adminer/env.cfg -f ./adminer/stack.yml up -d
|
||||||
|
|
||||||
|
services:
|
||||||
|
adminer:
|
||||||
|
image: ${IMAGE_TAG}
|
||||||
|
container_name: adminer
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- '8080:8080'
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# ============================================================
|
||||||
|
# alist 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 视情况填入真实值
|
||||||
|
# docker compose -p alist --env-file ./alist/env.cfg -f ./alist/compose.yml up -d
|
||||||
|
#
|
||||||
|
|
||||||
|
IMAGE_TAG=xhofe/alist:v3.32.0-ffmpeg
|
||||||
|
DATA_PATH=/data/volumes/alist/data
|
||||||
|
LOCALFS_PATH=/data/volumes/alist/localFS
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# ============================================================
|
||||||
|
# anqicms 部署 — 公共环境变量模板
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已在 .gitignore 中忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 按需修改端口和镜像版本
|
||||||
|
# docker compose -p anqicms --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
|
||||||
|
# ---------- 镜像 ----------
|
||||||
|
# anqicms 版本号
|
||||||
|
IMAGE_TAG_VER=latest
|
||||||
|
# 完整镜像引用(默认 Docker Hub 官方镜像)
|
||||||
|
IMAGE_TAG=anqicms/anqicms:${IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
# ---------- 数据卷 ----------
|
||||||
|
# 宿主机持久化目录(存放应用配置、上传文件、缓存、主题、插件等)
|
||||||
|
# 部署前手动创建:mkdir -pv /data/volumes/anqicms
|
||||||
|
Volumes_Path=/data/volumes/anqicms
|
||||||
|
|
||||||
|
# ---------- 服务端口 ----------
|
||||||
|
# 宿主机端口(容器内固定 8001)
|
||||||
|
ANQICMS_PORT=8001
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
# anqicms 部署栈
|
||||||
|
|
||||||
|
[anqicms](https://github.com/anqicms/anqicms) 是一个轻量、SEO 友好的中文内容管理系统,面向博客、自媒体和中小型企业建站场景,基于 Go 开发,开箱即用。
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `stack.yml` | Docker Compose 编排文件 |
|
||||||
|
| `env.cfg.example` | 环境变量模板(不含敏感信息,可提交) |
|
||||||
|
| `env.cfg` | **实际环境变量(gitignore,不提交)** — 部署时从 example 复制 |
|
||||||
|
| `readme.md` | 本文档 |
|
||||||
|
|
||||||
|
## 服务端口
|
||||||
|
|
||||||
|
| 宿主机 | 容器 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| `${ANQICMS_PORT}`(默认 `8001`) | `8001` | Web 服务(含前台 + 后台) |
|
||||||
|
|
||||||
|
宿主机端口可通过 `env.cfg` 中的 `ANQICMS_PORT` 自定义。
|
||||||
|
|
||||||
|
## 数据卷映射
|
||||||
|
|
||||||
|
| 容器路径 | 宿主机路径 | 说明 |
|
||||||
|
|----------|------------|------|
|
||||||
|
| `/app` | `${Volumes_Path}` | 应用数据根(配置、上传、缓存、主题、插件等) |
|
||||||
|
| `/etc/timezone` | `/etc/timezone` | 时区(只读) |
|
||||||
|
| `/etc/localtime` | `/etc/localtime` | 本地时间(只读) |
|
||||||
|
|
||||||
|
## 环境变量
|
||||||
|
|
||||||
|
### 公共变量(`env.cfg.example`)
|
||||||
|
|
||||||
|
| 变量 | 默认值 | 说明 |
|
||||||
|
|------|--------|------|
|
||||||
|
| `IMAGE_TAG_VER` | `latest` | anqicms 镜像版本号 |
|
||||||
|
| `IMAGE_TAG` | `anqicms/anqicms:${IMAGE_TAG_VER}` | 完整镜像引用 |
|
||||||
|
| `Volumes_Path` | `/data/volumes/anqicms` | 宿主机持久化目录 |
|
||||||
|
| `ANQICMS_PORT` | `8001` | 宿主机端口 |
|
||||||
|
|
||||||
|
## 部署步骤
|
||||||
|
|
||||||
|
### 首次部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 准备数据目录
|
||||||
|
mkdir -pv /data/volumes/anqicms
|
||||||
|
|
||||||
|
# 2. 复制 env 模板并按需修改
|
||||||
|
cp env.cfg.example env.cfg
|
||||||
|
$EDITOR env.cfg
|
||||||
|
|
||||||
|
# 3. 拉取镜像
|
||||||
|
docker compose -p anqicms --env-file ./anqicms/env.cfg -f ./anqicms/stack.yml pull
|
||||||
|
|
||||||
|
# 4. 启动服务
|
||||||
|
docker compose -p anqicms --env-file ./anqicms/env.cfg -f ./anqicms/stack.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 首次访问
|
||||||
|
|
||||||
|
容器启动后,浏览器访问 `http://<host-ip>:${ANQICMS_PORT}/`,按安装向导完成:
|
||||||
|
|
||||||
|
- 设置管理员账号 / 密码
|
||||||
|
- 选择数据库(默认 SQLite,零外部依赖;如需 MySQL 在向导里填连接信息)
|
||||||
|
- 完成初始化
|
||||||
|
|
||||||
|
### 验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 容器状态
|
||||||
|
docker ps -f name=anqicms
|
||||||
|
|
||||||
|
# 端口监听
|
||||||
|
ss -tlnp | grep ${ANQICMS_PORT}
|
||||||
|
|
||||||
|
# 容器日志
|
||||||
|
docker logs -f anqicms
|
||||||
|
|
||||||
|
# 健康检查
|
||||||
|
curl -sI http://localhost:${ANQICMS_PORT}/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 停止 / 重启
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 停止(保留数据)
|
||||||
|
docker compose -p anqicms --env-file ./anqicms/env.cfg -f ./anqicms/stack.yml stop
|
||||||
|
|
||||||
|
# 完全销毁(**数据不删**,bind 挂载保留在宿主机)
|
||||||
|
docker compose -p anqicms --env-file ./anqicms/env.cfg -f ./anqicms/stack.yml down
|
||||||
|
|
||||||
|
# 重启
|
||||||
|
docker compose -p anqicms --env-file ./anqicms/env.cfg -f ./anqicms/stack.yml restart
|
||||||
|
```
|
||||||
|
|
||||||
|
## 升级
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 备份数据(先停服)
|
||||||
|
docker compose -p anqicms --env-file ./anqicms/env.cfg -f ./anqicms/stack.yml stop
|
||||||
|
sudo rsync -a /data/volumes/anqicms/ /data/backups/anqicms/$(date +%Y%m%d)/
|
||||||
|
|
||||||
|
# 2. 修改 IMAGE_TAG_VER 后拉取
|
||||||
|
$EDITOR env.cfg
|
||||||
|
docker compose -p anqicms --env-file ./anqicms/env.cfg -f ./anqicms/stack.yml pull
|
||||||
|
|
||||||
|
# 3. 重建并启动
|
||||||
|
docker compose -p anqicms --env-file ./anqicms/env.cfg -f ./anqicms/stack.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## 故障排查
|
||||||
|
|
||||||
|
| 症状 | 排查命令 |
|
||||||
|
|------|----------|
|
||||||
|
| 容器起不来 | `docker logs -f anqicms` |
|
||||||
|
| 端口冲突 | `ss -tlnp \| grep ${ANQICMS_PORT}` |
|
||||||
|
| 无法访问 | 检查防火墙/安全组、`curl -sI http://localhost:${ANQICMS_PORT}/` |
|
||||||
|
| 数据丢失 | 确认 bind 挂载路径正确,不要用 anonymous volume |
|
||||||
|
|
||||||
|
## 相关链接
|
||||||
|
|
||||||
|
- GitHub: <https://github.com/anqicms/anqicms>
|
||||||
|
- Docker Hub: <https://hub.docker.com/r/anqicms/anqicms>
|
||||||
|
- 文档: <https://www.anqicms.com/docs>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# path:: mkdir -pv /data/volumes/anqicms
|
||||||
|
# pull:: docker compose -p anqicms --env-file ./anqicms/env.cfg -f ./anqicms/stack.yml pull
|
||||||
|
# run:: docker compose -p anqicms --env-file ./anqicms/env.cfg -f ./anqicms/stack.yml up -d
|
||||||
|
# disc::
|
||||||
|
# - /app 是容器内应用数据根目录(配置、上传、缓存、主题、插件等)
|
||||||
|
# - bind 挂载到 ${Volumes_Path} 实现持久化
|
||||||
|
# - 首次启动后通过 http://<host>:8001 进入安装向导
|
||||||
|
|
||||||
|
services:
|
||||||
|
anqicms:
|
||||||
|
image: ${IMAGE_TAG}
|
||||||
|
container_name: anqicms
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
ports:
|
||||||
|
- "${ANQICMS_PORT}:8001"
|
||||||
|
volumes:
|
||||||
|
- ${Volumes_Path}:/app
|
||||||
|
- ${Volumes_Path}/public:/app/public
|
||||||
|
- ${Volumes_Path}/template:/app/template
|
||||||
|
- ${Volumes_Path}/data:/app/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# ============================================================
|
||||||
|
# ansible 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p ansible --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG=hub.tp229.com:3500/ansible-alpine:py3.13-rootless
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# ============================================================
|
||||||
|
# base 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p base --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
Cadvisor_Tag_Ver=v0.53.0
|
||||||
|
|
||||||
|
Cadvisor_Image=hub.6t7.net/base/cadvisor:${Cadvisor_Tag_Ver}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# ============================================================
|
||||||
|
# alpine 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p alpine --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG=alpine:3
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# ============================================================
|
||||||
|
# debian 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p debian --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG=debian:13
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# ============================================================
|
||||||
|
# golang 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p golang --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
|
||||||
|
IMAGE_TAG_BASH=golang:1.25-trixie
|
||||||
|
|
||||||
|
IMAGE_TAG_ASH=golang:1.25-alpine
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# ============================================================
|
||||||
|
# nodejs 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p nodejs --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG_BASH=node:22.18.0-bookworm
|
||||||
|
|
||||||
|
IMAGE_TAG_ASH=node:22.18.0-alpine
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://charm.land/crush.json",
|
||||||
|
"options": {
|
||||||
|
"context_paths": ["."]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# ============================================================
|
||||||
|
# couchdb 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p couchdb --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
IMAGE_TAG=couchdb:3.5
|
||||||
|
|
||||||
|
COUCHDB_PORT=5984
|
||||||
|
|
||||||
|
COUCHDB_USER=your_custom_user
|
||||||
|
|
||||||
|
COUCHDB_PASSWORD=<your-db-password>
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/couchdb
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# ============================================================
|
||||||
|
# loki 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p loki --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG=3.6.2
|
||||||
|
|
||||||
|
IMAGE_NAME=grafana/loki:${IMAGE_TAG}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# ============================================================
|
||||||
|
# mysql 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p mysql --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
# 密码为生成的密码,请使用时修改后再部署
|
||||||
|
|
||||||
|
IMAGE_TAG=mysql:8.4
|
||||||
|
|
||||||
|
IMAGE_TAG_V9=mysql:9.7
|
||||||
|
|
||||||
|
IMAGE_TAG_V8=mysql:8.0
|
||||||
|
|
||||||
|
IMAGE_TAG_LTS=mysql:8.4
|
||||||
|
|
||||||
|
MYSQL_ROOT_PASSWORD=<your-strong-password>
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# ============================================================
|
||||||
|
# postgres 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p postgres --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
# 密码为生成的密码,请使用时修改后再部署
|
||||||
|
|
||||||
|
#IMAGE_TAG=postgres:14.11-bookworm
|
||||||
|
|
||||||
|
#IMAGE_TAG=postgres:15.6-bookworm
|
||||||
|
|
||||||
|
IMAGE_TAG=postgres:16.14
|
||||||
|
|
||||||
|
IMAGE_TAG_V17=postgres:17.10
|
||||||
|
|
||||||
|
IMAGE_TAG_V18=postgres:18.4
|
||||||
|
|
||||||
|
IMAGE_TAG_V15=postgres:15.18
|
||||||
|
|
||||||
|
POSTGRES_PASSWORD=<your-strong-password>
|
||||||
|
|
||||||
|
POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
@@ -20,4 +20,4 @@ services:
|
|||||||
- /etc/timezone:/etc/timezone:ro
|
- /etc/timezone:/etc/timezone:ro
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- "5432:5432"
|
- "5432:5432"
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# ============================================================
|
||||||
|
# redis 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p redis --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
IMAGE_TAG_REDISV6=redis:6.2.21-alpine
|
||||||
|
|
||||||
|
IMAGE_TAG_REDISV7=redis:7.4.7-alpine
|
||||||
|
|
||||||
|
IMAGE_TAG_REDISV8=redis:8.4.0-alpine
|
||||||
|
|
||||||
|
IMAGE_TAG_VALKEY_Latest=valkey/valkey:9.0.0
|
||||||
|
|
||||||
|
IMAGE_TAG_VALKEY_V8=valkey/valkey:8.1.5
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/redis
|
||||||
|
|
||||||
|
REDIS_PASSWORD=<your-strong-password>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# ============================================================
|
||||||
|
# domain-admin 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p domain-admin --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG_VER=v1.6.78
|
||||||
|
|
||||||
|
IMAGE_TAG=mouday/domain-admin:${IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/domain-admin
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# ============================================================
|
||||||
|
# drawnix 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p drawnix --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG_VER=v0.4.1
|
||||||
|
|
||||||
|
IMAGE_TAG=pubuzhixing/drawnix:${IMAGE_TAG_VER}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# ============================================================
|
||||||
|
# Dufs 部署 — 公共环境变量
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已在 .gitignore 中忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# docker compose -p dufs --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
|
||||||
|
# ---------- 镜像 ----------
|
||||||
|
# Dufs 版本号
|
||||||
|
IMAGE_TAG_VER=v0.46.0
|
||||||
|
# 完整镜像引用
|
||||||
|
IMAGE_TAG=sigoden/dufs:${IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
# ---------- 数据卷 ----------
|
||||||
|
# 宿主机持久化目录(存放服务文件数据)
|
||||||
|
# 部署前手动创建:mkdir -pv /data/volumes/dufs
|
||||||
|
Volumes_Path=/data/volumes/dufs
|
||||||
|
|
||||||
|
# ---------- 配置路径 ----------
|
||||||
|
# 宿主机配置文件/脚本目录
|
||||||
|
Config_Path=/data/mygit/config
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"storage-driver": "overlay2",
|
||||||
|
"data-root": "/data/docker",
|
||||||
|
"log-driver": "json-file",
|
||||||
|
"log-opts": {
|
||||||
|
"max-size": "10m",
|
||||||
|
"max-file": "3",
|
||||||
|
},
|
||||||
|
"default-ulimits": {
|
||||||
|
"nofile": {
|
||||||
|
"Name": "nofile",
|
||||||
|
"Hard": 65535,
|
||||||
|
"Soft": 65535,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"registry-mirrors": [
|
||||||
|
"https://docker.m.daocloud.io",
|
||||||
|
"https://docker.1ms.run",
|
||||||
|
"https://docker.1panel.dev",
|
||||||
|
"https://docker.367231.xyz",
|
||||||
|
"https://dockerproxy.net",
|
||||||
|
"https://hub.rat.dev",
|
||||||
|
],
|
||||||
|
"_comment_20260618173842": "\"insecure-registries\": [\"hub.tp229.com:3500\"]",
|
||||||
|
"_comment_20260619173657": "按实际情况填写",
|
||||||
|
"_comment_20260619173708": "\"bip\": \"172.18.0.1/16\"",
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# ============================================================
|
||||||
|
# flame 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p flame --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
IMAGE_TAG=pawelmalak/flame:multiarch2.3.1
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/flame
|
||||||
|
|
||||||
|
PASSWORD="<your-strong-password>"
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# ============================================================
|
||||||
|
# Gitea 部署 — 公共环境变量
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已在 .gitignore 中忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# docker compose -p gitea --env-file ./env.cfg -f ./lky-prod.yml up -d
|
||||||
|
#
|
||||||
|
# 数据库等敏感配置在容器 /etc/gitea/app.ini 中配置(挂载自 config/ 目录)
|
||||||
|
|
||||||
|
# ---------- 镜像 ----------
|
||||||
|
# Gitea 版本号(rootless 镜像带 -rootless 后缀)
|
||||||
|
IMAGE_TAG_VER=1.26.2-rootless
|
||||||
|
# 完整镜像引用(私有仓库示例:hub.tp229.com:3500/gitea/gitea:${IMAGE_TAG_VER})
|
||||||
|
IMAGE_TAG=gitea/gitea:${IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
# ---------- 数据卷 ----------
|
||||||
|
# 宿主机持久化目录
|
||||||
|
# 部署前手动创建并授权:
|
||||||
|
# mkdir -pv /data/volumes/gitea/{data,config}
|
||||||
|
# chown -R 1000:1000 /data/volumes/gitea/{data,config} # rootless 镜像必须
|
||||||
|
Volumes_Path=/data/volumes/gitea
|
||||||
|
|
||||||
|
# ---------- SSH 端口 ----------
|
||||||
|
# 容器内 SSH 端口固定 2222;按部署主机二选一:
|
||||||
|
# LAY_SSH_HOST_PORT —— 宿主 22 空闲的机器(lky-prod.yml 引用)
|
||||||
|
# SSH_HOST_PORT —— 宿主 22 被占用的机器(rpi-prod.yml 引用,如树莓派)
|
||||||
|
LAY_SSH_HOST_PORT=22
|
||||||
|
SSH_HOST_PORT=2222
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
# ============================================================
|
||||||
|
# goofish 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 .env 后填入真实值,.env 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp .env.example .env
|
||||||
|
# $EDITOR .env # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p goofish --env-file ./.env -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,.env 不提交)
|
||||||
|
# ============================================================
|
||||||
|
# --- AI 模型相关配置 ---
|
||||||
|
|
||||||
|
# 模型的API Key。
|
||||||
|
|
||||||
|
OPENAI_API_KEY="<your-api-key>"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 模型的API接口地址。这里需要填写服务商提供的、兼容OpenAI格式的API地址,基本所有模型都有提供OpenAI格式兼容的接口
|
||||||
|
|
||||||
|
# 可查阅你使用的大模型API文档,如格式为 https://xx.xx.com/v1/chat/completions 则OPENAI_BASE_URL只需要填入前半段 https://xx.xx.com/v1/
|
||||||
|
|
||||||
|
OPENAI_BASE_URL="https://api.siliconflow.cn/v1/chat/completions"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 使用的模型名称,模型需要支持图片上传。
|
||||||
|
|
||||||
|
OPENAI_MODEL_NAME="zai-org/GLM-4.5V"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# (可选) 为AI请求配置HTTP/S代理。支持 http 和 socks5。例如: http://127.0.0.1:7890 或 socks5://127.0.0.1:1080
|
||||||
|
|
||||||
|
PROXY_URL=""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ntfy 通知服务配置
|
||||||
|
|
||||||
|
NTFY_TOPIC_URL="https://ntfy.sh/your-topic-name" # 替换为你的 ntfy 主题 URL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# (可选) Gotify 通知服务配置
|
||||||
|
|
||||||
|
GOTIFY_URL="" # 你的 Gotify 服务地址, 例如: https://push.example.de
|
||||||
|
|
||||||
|
GOTIFY_TOKEN="<your-token>" # 你的 Gotify 应用的 Token
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# (可选) Bark 通知服务配置
|
||||||
|
|
||||||
|
BARK_URL="" # 你的 Bark 推送地址, 例如: https://api.day.app/your_key
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 企业微信机器人通知配置 如果无则不用配置
|
||||||
|
|
||||||
|
WX_BOT_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# (可选) 通用 Webhook 通知配置
|
||||||
|
|
||||||
|
WEBHOOK_URL="" # 你的 Webhook URL, 例如: https://foo.bar.com/quz?a=b
|
||||||
|
|
||||||
|
WEBHOOK_METHOD="POST" # 请求方法: "GET" 或 "POST"
|
||||||
|
|
||||||
|
WEBHOOK_HEADERS='{"X-API-TOKEN":"your-secret-token"}' # 自定义请求头 (JSON格式)
|
||||||
|
|
||||||
|
WEBHOOK_CONTENT_TYPE="JSON" # POST请求内容类型: "JSON" 或 "FORM"
|
||||||
|
|
||||||
|
WEBHOOK_QUERY_PARAMETERS='{"title":"{{title}}","content":"{{content}}"}' # GET请求的查询参数 (JSON格式, 支持 {{title}}, {{content}} 占位符)
|
||||||
|
|
||||||
|
WEBHOOK_BODY='{"title":"{{title}}","content":"{{content}}"}' # POST请求的请求体 (JSON格式, 支持 {{title}}, {{content}} 占位符)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 是否使用edge浏览器 默认使用chrome浏览器
|
||||||
|
|
||||||
|
LOGIN_IS_EDGE=false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 是否开启电脑链接转换为手机链接
|
||||||
|
|
||||||
|
PCURL_TO_MOBILE=true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 爬虫是否以无头模式运行 (true/false)。
|
||||||
|
|
||||||
|
# 本地运行时遇到滑动验证码时,可设为 false 手动进行滑动验证,如果出现风控建议停止运行。
|
||||||
|
|
||||||
|
# 使用docker部署不支持GUI,设置 RUN_HEADLESS=true 否则无法运行。
|
||||||
|
|
||||||
|
RUN_HEADLESS=true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# (可选) AI调试模式 (true/false)。开启后会在控制台打印更多用于排查AI分析问题的日志。
|
||||||
|
|
||||||
|
AI_DEBUG_MODE=false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 是否启用enable_thinking参数 (true/false)。某些AI模型需要此参数,而有些则不支持。
|
||||||
|
|
||||||
|
ENABLE_THINKING=false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 服务端口自定义 不配置默认8000
|
||||||
|
|
||||||
|
SERVER_PORT=8000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Web服务认证配置
|
||||||
|
|
||||||
|
WEB_USERNAME=cnphpbb
|
||||||
|
|
||||||
|
WEB_PASSWORD=<your-strong-password>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# ============================================================
|
||||||
|
# grafana 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p grafana --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG_VER=13.0.2
|
||||||
|
|
||||||
|
IMAGE_TAG=grafana/grafana:${IMAGE_TAG_VER}
|
||||||
+68
-3
@@ -1,4 +1,69 @@
|
|||||||
## Grafana
|
# Grafana 部署说明
|
||||||
|
|
||||||
image: grafana/grafana:12.2.0
|
[Grafana](https://grafana.com/) 是一个开源的可观测性平台,支持 Prometheus、InfluxDB、Loki、Elasticsearch 等多种数据源,提供丰富的仪表盘和告警能力,适用于基础设施监控、应用性能分析和日志可视化等场景。
|
||||||
ports: 3000
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `compose.yml` | Docker Compose 部署配置 |
|
||||||
|
| `env.cfg` | 环境变量(镜像版本) |
|
||||||
|
| `env.cfg.example` | 环境变量模板(不含敏感信息) |
|
||||||
|
|
||||||
|
## 部署命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 拉取镜像
|
||||||
|
docker compose -p grafana --env-file ./grafana/env.cfg -f ./grafana/compose.yml pull
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
docker compose -p grafana --env-file ./grafana/env.cfg -f ./grafana/compose.yml up -d
|
||||||
|
|
||||||
|
# 停止服务
|
||||||
|
docker compose -p grafana --env-file ./grafana/env.cfg -f ./grafana/compose.yml down
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker compose -p grafana --env-file ./grafana/env.cfg -f ./grafana/compose.yml logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## 环境变量说明
|
||||||
|
|
||||||
|
| 变量 | 说明 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| `IMAGE_TAG_VER` | Grafana 镜像版本 | `13.0.2` |
|
||||||
|
| `IMAGE_TAG` | 完整镜像标签 | `grafana/grafana:13.0.2` |
|
||||||
|
|
||||||
|
## 访问服务
|
||||||
|
|
||||||
|
- 默认端口:`3000`
|
||||||
|
- 访问地址:`http://<主机IP>:3000`
|
||||||
|
- 默认登录凭据:`admin / admin`(首次登录后建议修改密码)
|
||||||
|
|
||||||
|
## 持久化
|
||||||
|
|
||||||
|
当前配置使用无状态模式,容器重启后仪表盘和配置会丢失。如需持久化,建议在 `compose.yml` 中添加卷挂载:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
grafana:
|
||||||
|
volumes:
|
||||||
|
- ${Volumes_Path:-/data/volumes/grafana}:/var/lib/grafana # 数据持久化
|
||||||
|
```
|
||||||
|
|
||||||
|
并确保宿主机目录权限正确:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建数据目录
|
||||||
|
mkdir -pv /data/volumes/grafana
|
||||||
|
|
||||||
|
# 设置目录属主为 Grafana 容器用户(UID 472)
|
||||||
|
chown -R 472:472 /data/volumes/grafana
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
- Grafana 和 Gitea 默认都使用 3000 端口,部署在同一宿主机时需通过 `env.cfg` 或 compose 调整端口映射避免冲突
|
||||||
|
- 容器使用 `restart: unless-stopped` 策略,宿主机重启后自动拉起
|
||||||
|
- 默认使用匿名用户访问,如需接入 LDAP/OAuth 等认证,需挂载自定义 `grafana.ini` 配置文件
|
||||||
|
- 生产环境建议配置数据源和告警渠道的持久化存储
|
||||||
|
- 当前 `env.cfg.example` 版本为 `13.0.2`,实际部署版本以 `env.cfg` 为准
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# ============================================================
|
||||||
|
# haproxy 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p haproxy --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG_VER=3.3.0
|
||||||
|
|
||||||
|
IMAGE_TAG_DEV=3.4-dev
|
||||||
|
|
||||||
|
IMAGE_TAG=haproxy:${IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
Volumes_Path=/data/configs/haproxy
|
||||||
|
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
MYSQL_TEST_PORT=3306
|
||||||
|
|
||||||
|
MYSQL_DEV_PORT=3308
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ============================================================
|
||||||
|
# Hindsight 备份任务(每日 02:30 跑,cron 部署参考 crontab/)
|
||||||
|
# - 热备份:docker exec pg_dump 落盘到 bind 挂载的 backups/
|
||||||
|
# - 保留 7 天的 .sql.gz
|
||||||
|
# ============================================================
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source "${SCRIPT_DIR}/env.cfg"
|
||||||
|
|
||||||
|
BACKUP_DIR="${Volumes_Path}/backups"
|
||||||
|
KEEP_DAYS=7
|
||||||
|
TS=$(date +%Y%m%d_%H%M%S)
|
||||||
|
FNAME="hindsight_db_${TS}.sql.gz"
|
||||||
|
|
||||||
|
mkdir -p "${BACKUP_DIR}"
|
||||||
|
|
||||||
|
docker exec hindsight-db pg_dump \
|
||||||
|
-U hindsight_user \
|
||||||
|
-d hindsight_db \
|
||||||
|
--no-owner --no-privileges \
|
||||||
|
| gzip > "${BACKUP_DIR}/${FNAME}"
|
||||||
|
|
||||||
|
# 清理超过 KEEP_DAYS 天的旧备份
|
||||||
|
find "${BACKUP_DIR}" -name "hindsight_db_*.sql.gz" -mtime +${KEEP_DAYS} -delete
|
||||||
|
|
||||||
|
echo "[backup] ok: ${FNAME} ($(du -h "${BACKUP_DIR}/${FNAME}" | cut -f1))"
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# ============================================================
|
||||||
|
# Hindsight 部署 — 公共环境变量(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# 镜像版本
|
||||||
|
HINDSIGHT_VERSION=latest
|
||||||
|
HINDSIGHT_DB_VERSION=18
|
||||||
|
|
||||||
|
# 镜像源
|
||||||
|
HINDSIGHT_DB_IMAGE=pgvector/pgvector
|
||||||
|
HINDSIGHT_APP_IMAGE=ghcr.nju.edu.cn/vectorize-io/hindsight
|
||||||
|
|
||||||
|
# 数据库账号/库名
|
||||||
|
HINDSIGHT_DB_USER=hindsight_user
|
||||||
|
HINDSIGHT_DB_NAME=hindsight_db
|
||||||
|
POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
|
|
||||||
|
# 宿主机数据卷路径(**必须 WSL/Linux ext4 原生 fs**,不能放 /mnt/9P)
|
||||||
|
# bind 挂载 PostgreSQL 数据;放在 ~/hindsight/pgdata 而非 /mnt/d/mydata/,
|
||||||
|
# 因为 9P drvfs 的 fsync 不可靠,会导致 PG 数据损坏。
|
||||||
|
Volumes_Path=/data/Volumes/hindsight
|
||||||
|
|
||||||
|
# 服务端口(宿主机:容器)
|
||||||
|
HINDSIGHT_DB_PORT=5432
|
||||||
|
HINDSIGHT_API_PORT=8888
|
||||||
|
HINDSIGHT_ADMIN_PORT=9999
|
||||||
|
HINDSIGHT_CP_DATAPLANE_API_URL=http://0.0.0.0:8888
|
||||||
|
|
||||||
|
# LLM(MiniMax OpenAI-compatible 协议)
|
||||||
|
HINDSIGHT_API_LLM_PROVIDER=minimax
|
||||||
|
HINDSIGHT_API_LLM_MODEL=MiniMax-M3
|
||||||
|
HINDSIGHT_API_LLM_BASE_URL=https://api.minimaxi.com/v1
|
||||||
|
|
||||||
|
# 日志
|
||||||
|
HINDSIGHT_API_LOG_LEVEL=info
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 敏感值(必填,env.cfg 不提交)— 在 .gitignore 已忽略
|
||||||
|
# PostgreSQL 密码 最好不要带特殊字符
|
||||||
|
# ============================================================
|
||||||
|
# HINDSIGHT_DB_PASSWORD=<强密码>
|
||||||
|
# HINDSIGHT_API_LLM_API_KEY=<你的 MiniMax key>
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
# Hindsight 部署栈
|
||||||
|
|
||||||
|
[vectorize-io/hindsight](https://github.com/vectorize-io/hindsight) 是一个面向 LLM Agent 的长期记忆后端,采用 PostgreSQL/pgvector 存储。Hermes Agent 用它做跨会话长期记忆。
|
||||||
|
|
||||||
|
本目录是 **方案三:DB + Hindsight 分离部署** 迁移到 `deploy.stack` 仓库的版本。
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `stack.yml` | Docker Compose 主文件(2 服务:db + hindsight) |
|
||||||
|
| `env.cfg.example` | 公共环境变量模板(不含敏感信息,可提交) |
|
||||||
|
| `env.cfg` | **敏感配置(gitignore,不提交)** — 实际部署时从 example 复制后填密码/API Key |
|
||||||
|
| `backup.job` | 每日 `pg_dump` 热备份脚本,保留 7 天 |
|
||||||
|
| `readme.md` | 本文档 |
|
||||||
|
|
||||||
|
## 架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────┐ ┌──────────────────────┐
|
||||||
|
│ hindsight-app 容器 │ │ hindsight-db 容器 │
|
||||||
|
│ (ghcr.nju.edu.cn/ │ :5432 内网 │ (pgvector/pgvector │
|
||||||
|
│ vectorize-io/ │ ────────────► │ :pg18) │
|
||||||
|
│ hindsight) │ │ │
|
||||||
|
│ │ :8888 API │ :5432 对外暴露 │
|
||||||
|
│ │ :9999 Admin │ (供外部工具连接) │
|
||||||
|
└──────────────────────┘ └──────────────────────┘
|
||||||
|
│ │
|
||||||
|
▼ bind mount ▼ bind mount
|
||||||
|
${Volumes_Path}/backups ${Volumes_Path}/pgdata
|
||||||
|
(pg_dump 落盘目录) (PG 数据,原生 ext4)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 端口
|
||||||
|
|
||||||
|
| 端口 | 服务 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| `5432` | db | PostgreSQL 对外访问(DBeaver、pgAdmin 等工具连接) |
|
||||||
|
| `8888` | hindsight | API 服务 |
|
||||||
|
| `9999` | hindsight | Admin UI |
|
||||||
|
|
||||||
|
宿主机端口可通过 `env.cfg` 中的 `HINDSIGHT_DB_PORT`、`HINDSIGHT_API_PORT`、`HINDSIGHT_ADMIN_PORT` 自定义。
|
||||||
|
|
||||||
|
## 环境变量
|
||||||
|
|
||||||
|
### 公共变量(`env.cfg.example`)
|
||||||
|
|
||||||
|
| 变量 | 默认值 | 说明 |
|
||||||
|
|------|--------|------|
|
||||||
|
| `HINDSIGHT_VERSION` | `latest` | Hindsight App 镜像标签 |
|
||||||
|
| `HINDSIGHT_DB_VERSION` | `18` | PostgreSQL 大版本号 |
|
||||||
|
| `HINDSIGHT_DB_IMAGE` | `pgvector/pgvector` | DB 镜像仓库 |
|
||||||
|
| `HINDSIGHT_APP_IMAGE` | `ghcr.nju.edu.cn/vectorize-io/hindsight` | App 镜像仓库(南大 ghcr 镜像) |
|
||||||
|
| `HINDSIGHT_DB_USER` | `hindsight_user` | PostgreSQL 用户名 |
|
||||||
|
| `HINDSIGHT_DB_NAME` | `hindsight_db` | PostgreSQL 数据库名 |
|
||||||
|
| `POSTGRES_HOST_AUTH_METHOD` | `scram-sha-256` | PG 认证方式,同步用于 `INITDB_ARGS --auth-host` |
|
||||||
|
| `Volumes_Path` | `/data/Volumes/hindsight` | 宿主机持久化数据根路径 |
|
||||||
|
| `HINDSIGHT_DB_PORT` | `5432` | PostgreSQL 宿主机端口 |
|
||||||
|
| `HINDSIGHT_API_PORT` | `8888` | API 宿主机端口 |
|
||||||
|
| `HINDSIGHT_ADMIN_PORT` | `9999` | Admin UI 宿主机端口 |
|
||||||
|
| `HINDSIGHT_CP_DATAPLANE_API_URL` | `http://0.0.0.0:8888` | 数据面 API 地址 |
|
||||||
|
| `HINDSIGHT_API_LLM_PROVIDER` | — | LLM 提供商 |
|
||||||
|
| `HINDSIGHT_API_LLM_MODEL` | — | LLM 模型名 |
|
||||||
|
| `HINDSIGHT_API_LLM_BASE_URL` | — | LLM API Base URL |
|
||||||
|
| `HINDSIGHT_API_LOG_LEVEL` | `info` | 日志级别 |
|
||||||
|
|
||||||
|
### 敏感变量(`env.cfg`,不提交)
|
||||||
|
|
||||||
|
| 变量 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `HINDSIGHT_DB_PASSWORD` | PostgreSQL 密码(**最好不要带特殊字符**,避免 URI 解码问题) |
|
||||||
|
| `HINDSIGHT_API_LLM_API_KEY` | LLM API Key |
|
||||||
|
|
||||||
|
## 部署步骤
|
||||||
|
|
||||||
|
### 首次部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 准备数据目录(必须原生 ext4,不能放 9P drvfs)
|
||||||
|
sudo mkdir -pv /data/Volumes/hindsight/{pgdata,backups}
|
||||||
|
sudo chown -R 999:999 /data/Volumes/hindsight/pgdata
|
||||||
|
|
||||||
|
# 2. 复制 env 模板并填入真实值
|
||||||
|
cp env.cfg.example env.cfg
|
||||||
|
$EDITOR env.cfg
|
||||||
|
# 必填:HINDSIGHT_DB_PASSWORD, HINDSIGHT_API_LLM_API_KEY
|
||||||
|
|
||||||
|
# 3. 拉镜像
|
||||||
|
docker compose --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml pull
|
||||||
|
|
||||||
|
# 4. 启动
|
||||||
|
docker compose -p hindsight --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 容器状态
|
||||||
|
docker ps -f name=hindsight
|
||||||
|
|
||||||
|
# DB 连接与建表
|
||||||
|
docker exec -it hindsight-db psql -U hindsight_user -d hindsight_db -c '\dt'
|
||||||
|
|
||||||
|
# 端口监听
|
||||||
|
ss -tlnp | grep -E '5432|8888|9999'
|
||||||
|
|
||||||
|
# API 健康检查
|
||||||
|
curl -s http://localhost:8888/health
|
||||||
|
```
|
||||||
|
|
||||||
|
### 停止/重启
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 停止(保留数据)
|
||||||
|
docker compose -p hindsight --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml stop
|
||||||
|
|
||||||
|
# 完全销毁(**数据不删**,bind 挂载保留在宿主机)
|
||||||
|
docker compose -p hindsight --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml down
|
||||||
|
|
||||||
|
# 重启
|
||||||
|
docker compose -p hindsight --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml restart
|
||||||
|
```
|
||||||
|
|
||||||
|
## 关键设计决策
|
||||||
|
|
||||||
|
| 决策点 | 决定 | 原因 |
|
||||||
|
|--------|------|------|
|
||||||
|
| 数据卷方案 | bind 挂载到 `${Volumes_Path}/pgdata` | 直观、可直接 `rsync`/`pg_dump`、跨机迁移用 `tar` 整个目录即可 |
|
||||||
|
| 端口绑定 | 0.0.0.0,含 DB 5432 | PVE LAN 上其他 VM 也可访问;DB 端口暴露方便外部工具(DBeaver 等)连接 |
|
||||||
|
| 镜像源 | `ghcr.nju.edu.cn/vectorize-io/hindsight` | 南京大学 ghcr 镜像,国内拉得快 |
|
||||||
|
| LLM | MiniMax-M3 via api.minimaxi.com | 用 MiniMax 的 OpenAI-compatible 协议 |
|
||||||
|
| PG 认证 | `scram-sha-256` | 比 md5 更安全,`POSTGRES_INITDB_ARGS` 同步设置 `--auth-host` |
|
||||||
|
| 旧数据迁移 | 见 `docs-hermes-Hindsight-记忆系统部署指南.md` 决策表 | 走 A(zip 导入) 或 B(重置新 DB) 路径 |
|
||||||
|
|
||||||
|
## 备份与恢复
|
||||||
|
|
||||||
|
### 自动备份
|
||||||
|
|
||||||
|
`backup.job` 是 `pg_dump` 热备份脚本(不停服),落盘到 bind 挂载的 `backups/`。接入 cron:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# /etc/cron.d/hindsight-backup 或 crontab -e
|
||||||
|
30 2 * * * /path/to/deploy.stack/hindsight/backup.job >> /var/log/hindsight-backup.log 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
或参考 `crontab/` 目录的统一任务管理方式(`shell/up.bash` 会处理 `chmod +x`)。
|
||||||
|
|
||||||
|
### 手动备份
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 热备份(推荐)
|
||||||
|
docker exec hindsight-db pg_dump -U hindsight_user -d hindsight_db | gzip > /data/Volumes/hindsight/backups/manual_$(date +%Y%m%d).sql.gz
|
||||||
|
|
||||||
|
# 冷备份(停服时,更彻底)
|
||||||
|
docker compose -p hindsight --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml stop
|
||||||
|
sudo rsync -a /data/Volumes/hindsight/pgdata/ /data/Volumes/hindsight/backups/pgdata-cold/
|
||||||
|
docker compose -p hindsight --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml start
|
||||||
|
```
|
||||||
|
|
||||||
|
### 恢复
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 从 pg_dump 恢复
|
||||||
|
gunzip -c /data/Volumes/hindsight/backups/hindsight_db_20260607_023000.sql.gz \
|
||||||
|
| docker exec -i hindsight-db psql -U hindsight_user -d hindsight_db
|
||||||
|
|
||||||
|
# 从冷备份恢复(停服 + 替换 bind 目录)
|
||||||
|
docker compose -p hindsight --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml down
|
||||||
|
sudo rm -rf /data/Volumes/hindsight/pgdata/*
|
||||||
|
sudo rsync -a /data/Volumes/hindsight/backups/pgdata-cold/ /data/Volumes/hindsight/pgdata/
|
||||||
|
sudo chown -R 999:999 /data/Volumes/hindsight/pgdata
|
||||||
|
docker compose -p hindsight --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## 故障排查
|
||||||
|
|
||||||
|
| 症状 | 排查命令 |
|
||||||
|
|------|----------|
|
||||||
|
| 容器起不来 | `docker logs -f hindsight-app` / `docker logs -f hindsight-db` |
|
||||||
|
| DB 连不上(容器内) | `docker exec -it hindsight-db psql -U hindsight_user -d hindsight_db` |
|
||||||
|
| DB 连不上(外部工具) | 确认 `HINDSIGHT_DB_PORT` 已映射、`ss -tlnp` 检查 5432 监听 |
|
||||||
|
| 慢查询 | 在 psql 里 `SELECT * FROM pg_stat_activity;` |
|
||||||
|
| 端口冲突 | `ss -tlnp \| grep -E '5432\|8888\|9999'` |
|
||||||
|
| 端口未对外 | `ss -tlnp` 看是不是只监听 `127.0.0.1`,确认 `ports:` 没加 IP 前缀 |
|
||||||
|
| 密码含特殊字符导致连接失败 | `HINDSIGHT_DB_PASSWORD` 最好不要带特殊字符,避免 URI 编码问题 |
|
||||||
|
| glibc 错误 | 0.7.2 内嵌 pg0 需 glibc 2.38,方案三已用独立容器避开 |
|
||||||
|
|
||||||
|
## 与 Hermes 集成
|
||||||
|
|
||||||
|
Hermes plugin 通过 HTTP 调用本服务的 API(`localhost:8888`),不直连 DB。配置在 `~/.hermes/config.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
memory:
|
||||||
|
provider: hindsight
|
||||||
|
hindsight:
|
||||||
|
api_url: http://localhost:8888
|
||||||
|
bank_id: hermes
|
||||||
|
memory_mode: hybrid
|
||||||
|
auto_recall: true
|
||||||
|
auto_retain: true
|
||||||
|
retain_async: true
|
||||||
|
```
|
||||||
|
|
||||||
|
切换命令:`hermes config set memory.provider hindsight`
|
||||||
|
|
||||||
|
## 相关文档
|
||||||
|
|
||||||
|
- `~/Obsibian/MyNotes/DevOps/04-AI工具/docs-hermes-Hindsight-记忆系统部署指南.md` — 完整部署指南(700+ 行,含方案对比、旧数据迁移决策表)
|
||||||
|
- 仓库根 `AGENTS.md` — `deploy.stack` 项目规范
|
||||||
|
- `crontab/` — 定时任务集成参考
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
# Hindsight 部署栈
|
||||||
|
# ============================================================
|
||||||
|
# 部署前准备(仅首次):
|
||||||
|
# mkdir -pv ${Volumes_Path}/{pgdata,backups,huggingface}
|
||||||
|
# sudo chown -R 999:999 ${Volumes_Path}/pgdata
|
||||||
|
# cp env.cfg.example env.cfg && $EDITOR env.cfg # 填入密码/API Key
|
||||||
|
#
|
||||||
|
# pull:: docker compose --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml pull
|
||||||
|
# RUN:: docker compose -p hindsight --env-file ./hindsight/env.cfg -f ./hindsight/stack.yml up -d
|
||||||
|
# disc::
|
||||||
|
# - DB 数据 bind 挂到 /home/geng/hindsight/pgdata(WSL 原生 fs,避 9P fsync 风险)
|
||||||
|
# - 复用宿主 HF 缓存(bge + ms-marco 不重下)
|
||||||
|
# - 镜像走南京大学 ghcr 镜像,国内拉得快
|
||||||
|
# - 端口 8888=API, 9999=Admin UI, 5432=PostgreSQL,绑定 0.0.0.0 供 LAN VM 访问
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: ${HINDSIGHT_DB_IMAGE}:pg${HINDSIGHT_DB_VERSION:-18}
|
||||||
|
container_name: hindsight-db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- POSTGRES_USER=${HINDSIGHT_DB_USER:-hindsight_user}
|
||||||
|
- POSTGRES_PASSWORD=${HINDSIGHT_DB_PASSWORD:?set HINDSIGHT_DB_PASSWORD}
|
||||||
|
- POSTGRES_DB=${HINDSIGHT_DB_NAME:-hindsight_db}
|
||||||
|
- POSTGRES_HOST_AUTH_METHOD=${POSTGRES_HOST_AUTH_METHOD}
|
||||||
|
- POSTGRES_INITDB_ARGS=--encoding=UTF8 --locale=C --auth-host=${POSTGRES_HOST_AUTH_METHOD}
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- ${Volumes_Path}/pgdata:/var/lib/postgresql/${HINDSIGHT_DB_VERSION:-18}/docker
|
||||||
|
ports:
|
||||||
|
- "${HINDSIGHT_DB_PORT:-5432}:5432"
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD-SHELL",
|
||||||
|
"pg_isready -U ${HINDSIGHT_DB_USER:-hindsight_user} -d ${HINDSIGHT_DB_NAME:-hindsight_db}",
|
||||||
|
]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
networks:
|
||||||
|
- hindsight-net
|
||||||
|
|
||||||
|
hindsight:
|
||||||
|
image: ${HINDSIGHT_APP_IMAGE}:${HINDSIGHT_VERSION:-latest}
|
||||||
|
container_name: hindsight-app
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
ports:
|
||||||
|
- "${HINDSIGHT_API_PORT:-8888}:8888"
|
||||||
|
- "${HINDSIGHT_ADMIN_PORT:-9999}:9999"
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- HINDSIGHT_API_LLM_PROVIDER=${HINDSIGHT_API_LLM_PROVIDER}
|
||||||
|
- HINDSIGHT_API_LLM_API_KEY=${HINDSIGHT_API_LLM_API_KEY:?set HINDSIGHT_API_LLM_API_KEY}
|
||||||
|
- HINDSIGHT_API_LLM_MODEL=${HINDSIGHT_API_LLM_MODEL}
|
||||||
|
- HINDSIGHT_API_LLM_BASE_URL=${HINDSIGHT_API_LLM_BASE_URL}
|
||||||
|
- HINDSIGHT_API_DATABASE_URL=postgresql://${HINDSIGHT_DB_USER}:${HINDSIGHT_DB_PASSWORD}@db:5432/${HINDSIGHT_DB_NAME}
|
||||||
|
- HINDSIGHT_API_LOG_LEVEL=${HINDSIGHT_API_LOG_LEVEL:-info}
|
||||||
|
- HINDSIGHT_CP_DATAPLANE_API_URL=${HINDSIGHT_CP_DATAPLANE_API_URL}
|
||||||
|
- HF_HUB_OFFLINE=1
|
||||||
|
- TRANSFORMERS_OFFLINE=1
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- ${Volumes_Path}/backups:/home/hindsight/backups
|
||||||
|
networks:
|
||||||
|
- hindsight-net
|
||||||
|
|
||||||
|
networks:
|
||||||
|
hindsight-net:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# create-multi-keys.sh — 在 vm61 (10.8.0.9, 备用/测试) honcho 上批量创建 3 个客户端的 API key
|
||||||
|
#
|
||||||
|
# 用法:
|
||||||
|
# 1. 在 vm61 上: ./create-multi-keys.sh
|
||||||
|
# 2. 输出 3 个 key 文件到 ~/.honcho-keys/,chmod 600
|
||||||
|
# 3. scp 到对应客户端
|
||||||
|
#
|
||||||
|
# 前置:
|
||||||
|
# - honcho-api 容器跑着(监听 10.8.0.9:18000)
|
||||||
|
# - AUTH_USE_AUTH=true + 管理员 token(honcho init 时生成)
|
||||||
|
# - workspace "home" 已存在
|
||||||
|
#
|
||||||
|
# ⚠️ 不要 echo key 到聊天。文件 chmod 600,scp 时 -p 保留权限。
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
WORKSPACE="${HONCHO_WORKSPACE:-home}"
|
||||||
|
HONCHO_API="${HONCHO_API_URL:-http://10.8.0.9:18000}"
|
||||||
|
ADMIN_TOKEN_FILE="${HONCHO_ADMIN_TOKEN_FILE:-/root/.honcho-keys/admin.key}"
|
||||||
|
|
||||||
|
# 客户端清单: name:peer:device_hint
|
||||||
|
CLIENTS=(
|
||||||
|
"alpha:laodeng-mypc03:mypc03"
|
||||||
|
"beta:laodeng-govpc:gov-pc"
|
||||||
|
"gamma:laodeng-mac:macbook"
|
||||||
|
)
|
||||||
|
|
||||||
|
OUT_DIR="${OUT_DIR:-/root/.honcho-keys}"
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
chmod 700 "$OUT_DIR"
|
||||||
|
|
||||||
|
if [[ ! -f "$ADMIN_TOKEN_FILE" ]]; then
|
||||||
|
echo "❌ 找不到 admin token: $ADMIN_TOKEN_FILE" >&2
|
||||||
|
echo " 把 honcho init 时生成的 admin token 写到该文件,chmod 600" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ADMIN_TOKEN="$(cat "$ADMIN_TOKEN_FILE")"
|
||||||
|
|
||||||
|
echo "==> honcho: $HONCHO_API"
|
||||||
|
echo "==> workspace: $WORKSPACE"
|
||||||
|
echo "==> 输出目录: $OUT_DIR"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
for entry in "${CLIENTS[@]}"; do
|
||||||
|
IFS=':' read -r slug peer device <<< "$entry"
|
||||||
|
key_file="$OUT_DIR/${device}.key"
|
||||||
|
info_file="$OUT_DIR/${device}.json"
|
||||||
|
|
||||||
|
echo "--- [$device] peer=$peer ---"
|
||||||
|
|
||||||
|
# 检查 peer 是否已存在(幂等)
|
||||||
|
existing="$(curl -fsS -H "Authorization: Bearer *** "$HONCHO_API/v2/workspaces/$WORKSPACE/peers/$peer" 2>/dev/null || true)"
|
||||||
|
|
||||||
|
if [[ -n "$existing" && "$existing" != *"404"* ]]; then
|
||||||
|
echo " peer 已存在,跳过创建"
|
||||||
|
else
|
||||||
|
# 创建 peer
|
||||||
|
curl -fsS -X POST \
|
||||||
|
-H "Authorization: Bearer *** \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"name\":\"$peer\"}" \
|
||||||
|
"$HONCHO_API/v2/workspaces/$WORKSPACE/peers" \
|
||||||
|
| tee "$info_file.tmp" > /dev/null
|
||||||
|
mv "$info_file.tmp" "$info_file"
|
||||||
|
chmod 600 "$info_file"
|
||||||
|
echo " ✅ peer 已创建"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 创建 API key(每次新建,旧的不 revoke)
|
||||||
|
# honcho 的 key 创建 API 名称可能因版本不同,下面给常见两种尝试
|
||||||
|
key_resp="$(curl -fsS -X POST \
|
||||||
|
-H "Authorization: Bearer *** \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"name\":\"$peer\",\"scope\":\"peer:$peer\"}" \
|
||||||
|
"$HONCHO_API/v2/workspaces/$WORKSPACE/api-keys" 2>/dev/null || true)"
|
||||||
|
|
||||||
|
if [[ -z "$key_resp" ]]; then
|
||||||
|
# 备选 endpoint
|
||||||
|
key_resp="$(curl -fsS -X POST \
|
||||||
|
-H "Authorization: Bearer *** \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"name\":\"$peer\"}" \
|
||||||
|
"$HONCHO_API/v2/auth/keys 2>/dev/null || true)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$key_resp" ]]; then
|
||||||
|
echo " ❌ 创建 key 失败,请检查 honcho API 版本" >&2
|
||||||
|
echo " 临时手动: honcho create user --workspace $WORKSPACE --name $peer" >&2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 提取 token(兼容多种字段名)
|
||||||
|
token="$(echo "$key_resp" | python3 -c '
|
||||||
|
import json, sys
|
||||||
|
try:
|
||||||
|
d = json.load(sys.stdin)
|
||||||
|
print(d.get("token") or d.get("api_key") or d.get("key") or d.get("value") or "")
|
||||||
|
except Exception:
|
||||||
|
print("")
|
||||||
|
')"
|
||||||
|
|
||||||
|
if [[ -z "$token" ]]; then
|
||||||
|
echo " ❌ 无法从响应提取 token:"
|
||||||
|
echo "$key_resp" | head -c 500
|
||||||
|
echo ""
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "$token" > "$key_file"
|
||||||
|
chmod 600 "$key_file"
|
||||||
|
echo " ✅ key 已写入: $key_file ($(wc -c < "$key_file") bytes)"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==> 完成。当前 keys:"
|
||||||
|
ls -la "$OUT_DIR"
|
||||||
|
echo ""
|
||||||
|
echo "下一步:"
|
||||||
|
echo " scp $OUT_DIR/mypc03.key mypc03:~/.honcho-keys/"
|
||||||
|
echo " scp $OUT_DIR/govpc.key govpc:~/.honcho-keys/"
|
||||||
|
echo " scp $OUT_DIR/mac.key macbook:~/.honcho-keys/"
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ 不要 echo 这些 key 到聊天/日志/screenshot"
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
# ============================================================
|
||||||
|
# Honcho Self-Hosted 部署 — 公共环境变量(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 镜像版本
|
||||||
|
# ============================================================
|
||||||
|
# Honcho 主仓库 git ref(源码 build 用,可填 tag / branch / SHA)
|
||||||
|
HONCHO_VERSION=main
|
||||||
|
# PostgreSQL 大版本号(pgvector 镜像 tag 后缀,必须与镜像仓库支持的 tag 对应)
|
||||||
|
HONCHO_DB_VERSION=18
|
||||||
|
# Redis 大版本号
|
||||||
|
HONCHO_REDIS_VERSION=8
|
||||||
|
|
||||||
|
# 镜像仓库(默认公共镜像;自建私有 hub 可改 hub.tp229.com:3500/...)
|
||||||
|
HONCHO_DB_IMAGE=pgvector/pgvector
|
||||||
|
HONCHO_REDIS_IMAGE=redis
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# PostgreSQL 数据库
|
||||||
|
# ============================================================
|
||||||
|
HONCHO_DB_USER=honcho
|
||||||
|
HONCHO_DB_NAME=honcho
|
||||||
|
# scram-sha-256 比 md5 安全;与 POSTGRES_INITDB_ARGS --auth-host 同步
|
||||||
|
POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 宿主机数据卷路径(必须 WSL/Linux ext4 原生 fs,不能放 /mnt/9P)
|
||||||
|
# 9P drvfs 的 fsync 不可靠,会导致 PG 数据损坏
|
||||||
|
# ============================================================
|
||||||
|
Volumes_Path=/data/volumes/honcho
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 服务端口(宿主机:容器,全部绑定 0.0.0.0 供 LAN 访问)
|
||||||
|
# 5432 与 hindsight/dbSer 撞车,多服务共存时改 HONCHO_DB_PORT 区分
|
||||||
|
# ============================================================
|
||||||
|
HONCHO_API_PORT=8000
|
||||||
|
HONCHO_DB_PORT=5432
|
||||||
|
HONCHO_REDIS_PORT=6379
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Honcho 应用配置
|
||||||
|
# ============================================================
|
||||||
|
HONCHO_LOG_LEVEL=INFO
|
||||||
|
# 本地 LAN 自用可设 false;公网暴露必须改 true
|
||||||
|
HONCHO_AUTH_USE_AUTH=false
|
||||||
|
HONCHO_NAMESPACE=honcho
|
||||||
|
# 关闭可省 embedding 费用(但失去语义检索能力)
|
||||||
|
HONCHO_EMBED_MESSAGES=true
|
||||||
|
# Embedding 模型(默认走 SiliconFlow 兼容端点,独立 base URL)
|
||||||
|
HONCHO_EMBEDDING_MODEL=Qwen/Qwen3-Embedding-8B
|
||||||
|
HONCHO_EMBEDDING_BASE_URL=https://api.siliconflow.cn/v1
|
||||||
|
# 替代方案 A:本地 Ollama(零成本、隐私优先)
|
||||||
|
# HONCHO_EMBEDDING_MODEL=qwen3-embedding:0.6b
|
||||||
|
# HONCHO_EMBEDDING_BASE_URL=http://host.docker.internal:11434/v1
|
||||||
|
# EMBEDDING_API_KEY 可留空(Ollama 默认无 key;如配了 OLLAMA_API_KEY 环境变量再填)
|
||||||
|
# 前置:宿主机 `ollama pull qwen3-embedding:0.6b`
|
||||||
|
# docker compose 中 host.docker.internal 在 Linux compose v2 默认可用,Windows/WSL2 自动转发
|
||||||
|
# Embedding 维度(Qwen3-Embedding-8B 默认 4096,但通过 SiliconFlow 的 dimensions 参数强制输出 1536)
|
||||||
|
# 必须与已有 DB schema 的 public.documents.embedding dim 一致;切换模型必须先 migrate 旧数据
|
||||||
|
# 若 Honcho 自动推断失败,需在 stack.yml 同步设置 EMBEDDING_VECTOR_DIMENSIONS=1536
|
||||||
|
# deriver 必须用支持 tool calling 的模型
|
||||||
|
HONCHO_DERIVER_MODEL=deepseek-ai/DeepSeek-V4-Flash
|
||||||
|
# dreamer 的 deduction/induction specialist(默认走 OpenAI SDK + gpt-5.4-mini,
|
||||||
|
# 会请求 api.openai.com/v1 在国内超时);必须显式覆盖到国内可达端点
|
||||||
|
HONCHO_DEDUCTION_MODEL=deepseek-ai/DeepSeek-V4-Flash
|
||||||
|
HONCHO_INDUCTION_MODEL=deepseek-ai/DeepSeek-V4-Flash
|
||||||
|
HONCHO_DERIVER_WORKERS=1
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# LLM(OpenAI 兼容协议;可换 OpenRouter / vLLM / Ollama 等端点)
|
||||||
|
# deriver 启动时强校验 API Key 非空,占位符会反复重启
|
||||||
|
# 注意:必须同时被 deriver/dreamer/embedding 复用,否则 specialist 会回落 openai.com
|
||||||
|
# ============================================================
|
||||||
|
HONCHO_LLM_BASE_URL=https://api.siliconflow.cn/v1
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 敏感值(必填,env.cfg 不提交)— 在 .gitignore 已忽略
|
||||||
|
# 占位符约定:REPLACE_ME_XXX → 替换为真实值(避免使用 <...> 占位符,patch 工具链会吞)
|
||||||
|
# ============================================================
|
||||||
|
# HONCHO_LLM_API_KEY=REPLACE_ME_LLM_KEY # 你的 OpenAI key 或兼容端点 key
|
||||||
|
# HONCHO_EMBEDDING_API_KEY=REPLACE_ME_EMBEDDING_KEY # SiliconFlow key:https://cloud.siliconflow.cn/account/ak
|
||||||
|
# HONCHO_DB_PASSWORD=REPLACE_ME_DB_PASSWORD # 强密码,不要带特殊字符,避免 URI 编码问题
|
||||||
|
# HONCHO_AUTH_JWT_SECRET=REPLACE_ME_JWT_SECRET # 仅 AUTH_USE_AUTH=true 时需要;用 python scripts/generate_jwt_secret.py 生成
|
||||||
@@ -0,0 +1,374 @@
|
|||||||
|
# Honcho Self-Hosted 部署栈
|
||||||
|
|
||||||
|
[plastic-labs/honcho](https://github.com/plastic-labs/honcho) 是 Plastic Labs 开源的 **AI Agent 长期记忆后端**(v3.0.x,AGPL-3.0)。Hermes Agent 用它做跨会话的用户上下文管理(peer-centric 记忆、推理、检索)。本目录部署的是 **honcho-self-hosted**:基于 [elkimek/honcho-self-hosted](https://github.com/elkimek/honcho-self-hosted) 配置的本地化版本,集成到 `deploy.stack` 仓库规范下。
|
||||||
|
|
||||||
|
与官方 `docker-compose.yml.example` 的差异:本目录用 **PostgreSQL 18 + Redis 8**(非官方默认的 pg15/redis 8.2)、`${Volumes_Path}` bind 挂载(非 docker volume)、固定到内网可访问的端口。
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `stack.yml` | Docker Compose 主文件(4 服务:api + deriver + database + redis) |
|
||||||
|
| `env.cfg.example` | 公共环境变量模板(不含敏感信息,可提交) |
|
||||||
|
| `env.cfg` | **敏感配置(gitignore,不提交)** — 实际部署时从 example 复制后填密码/API Key |
|
||||||
|
| `readme.md` | 本文档 |
|
||||||
|
|
||||||
|
## 架构
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TB
|
||||||
|
subgraph src["源码构建期(无运行时 bind)"]
|
||||||
|
source["${Volumes_Path}/honcho/source<br/>git clone plastic-labs/honcho<br/>api/deriver Dockerfile build context"]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph run["运行时 — honcho-net bridge"]
|
||||||
|
api["<b>honcho-api</b><br/>FastAPI 主服务<br/>:8000 (0.0.0.0)<br/>build from source"]
|
||||||
|
deriver["<b>honcho-deriver</b><br/>后台推理 worker<br/>消息→观察→peer representation<br/>build from source"]
|
||||||
|
database["<b>honcho-database</b><br/>pgvector/pgvector:pg18<br/>:5432 (0.0.0.0)<br/>scram-sha-256"]
|
||||||
|
redis["<b>honcho-redis</b><br/>redis:8<br/>:6379<br/>CACHE_URL"]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph host["宿主机持久化 (WSL ext4)"]
|
||||||
|
pgdata["${Volumes_Path}/pgdata<br/>(bind mount)"]
|
||||||
|
redisdata["${Volumes_Path}/redis<br/>(bind mount)"]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph external["外部调用方"]
|
||||||
|
hermes["Hermes Agent<br/>memory.provider=honcho"]
|
||||||
|
sdk["Python / TS SDK<br/>(honcho-ai / @honcho-ai/sdk)"]
|
||||||
|
tools["DBeaver / psql<br/>PG 5432 直连"]
|
||||||
|
siliconflow["SiliconFlow<br/>api.siliconflow.cn/v1<br/>Qwen3-Embedding-8B<br/>dimensions=1536<br/>(云端默认)"]
|
||||||
|
ollama["本地 Ollama<br/>host.docker.internal:11434<br/>qwen3-embedding:0.6b<br/>(备选,零成本)"]
|
||||||
|
end
|
||||||
|
|
||||||
|
source -.->|docker build<br/>首次 5-10 min| api
|
||||||
|
source -.->|docker build| deriver
|
||||||
|
|
||||||
|
hermes -->|HTTP :8000| api
|
||||||
|
sdk -->|HTTP :8000| api
|
||||||
|
tools -->|:5432| database
|
||||||
|
|
||||||
|
api -->|:5432| database
|
||||||
|
deriver -->|:5432| database
|
||||||
|
api -->|:6379| redis
|
||||||
|
deriver -->|:6379| redis
|
||||||
|
deriver -.->|轮询<br/>pending messages| api
|
||||||
|
api -->|HTTPS embedding<br/>Qwen3-8B 1536d| siliconflow
|
||||||
|
deriver -->|HTTPS embedding<br/>Qwen3-8B 1536d| siliconflow
|
||||||
|
|
||||||
|
database --- pgdata
|
||||||
|
redis --- redisdata
|
||||||
|
|
||||||
|
classDef ext fill:#e1f5ff,stroke:#01579b,color:#000
|
||||||
|
classDef build fill:#fff3e0,stroke:#e65100,color:#000
|
||||||
|
classDef data fill:#f3e5f5,stroke:#4a148c,color:#000
|
||||||
|
classDef host fill:#e8f5e9,stroke:#1b5e20,color:#000
|
||||||
|
|
||||||
|
class hermes,sdk,tools,siliconflow,ollama ext
|
||||||
|
class source build
|
||||||
|
class api,deriver,database,redis ext
|
||||||
|
class pgdata,redisdata data
|
||||||
|
```
|
||||||
|
|
||||||
|
> **源码不在运行时 bind mount**:api/deriver 通过 `build: context: .` 从 `git clone` 的源码目录(`${Volumes_Path}/honcho/source`)构建,**不**挂源码进运行容器。`source/` 仅作为构建缓存,方便后续 `git pull` 后增量 rebuild。
|
||||||
|
|
||||||
|
**四个服务的职责:**
|
||||||
|
|
||||||
|
| 服务 | 角色 | 关键依赖 |
|
||||||
|
|------|------|----------|
|
||||||
|
| `api` | FastAPI 主服务,对外提供 REST API(端口 8000) | database、redis |
|
||||||
|
| `deriver` | **后台推理 worker**:消息→观察→peer representation→session 摘要 | api(健康后才起)、database、redis |
|
||||||
|
| `database` | PostgreSQL + pgvector 扩展,存所有 messages、peers、workspaces | — |
|
||||||
|
| `redis` | 缓存层(`CACHE_URL=redis://redis:6379/0`) | — |
|
||||||
|
|
||||||
|
**⚠️ deriver 不可省**:没它,消息能写入 DB,但不会生成记忆、不会提取观察、不会做 session 摘要。Honcho 退化成纯 KV 存储。
|
||||||
|
|
||||||
|
## 端口
|
||||||
|
|
||||||
|
| 端口 | 服务 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| `8000` | api | Honcho REST API(供 Hermes / Python SDK / TypeScript SDK 调用) |
|
||||||
|
| `5432` | database | PostgreSQL 对外访问(DBeaver、psql 等工具连接) |
|
||||||
|
| `6379` | redis | Redis 对外访问(一般无需直连) |
|
||||||
|
|
||||||
|
宿主机端口可通过 `env.cfg` 中的 `HONCHO_API_PORT`、`HONCHO_DB_PORT`、`HONCHO_REDIS_PORT` 自定义。
|
||||||
|
|
||||||
|
## 环境变量
|
||||||
|
|
||||||
|
### 公共变量(`env.cfg.example`)
|
||||||
|
|
||||||
|
| 变量 | 默认值 | 说明 |
|
||||||
|
|------|--------|------|
|
||||||
|
| `HONCHO_VERSION` | `main` | Honcho 主仓库 git ref(tag / branch / SHA 都可;源码 build 用) |
|
||||||
|
| `HONCHO_BRANCH` | `main` | 源码 checkout 分支(`HONCHO_VERSION` 不是 branch 时生效) |
|
||||||
|
| `HONCHO_DB_VERSION` | `18` | PostgreSQL 大版本号(pgvector 镜像 tag 后缀) |
|
||||||
|
| `HONCHO_REDIS_VERSION` | `8` | Redis 大版本号 |
|
||||||
|
| `HONCHO_DB_IMAGE` | `pgvector/pgvector` | DB 镜像仓库 |
|
||||||
|
| `HONCHO_REDIS_IMAGE` | `redis` | Redis 镜像仓库 |
|
||||||
|
| `HONCHO_DB_USER` | `honcho` | PostgreSQL 用户名 |
|
||||||
|
| `HONCHO_DB_NAME` | `honcho` | PostgreSQL 数据库名 |
|
||||||
|
| `HONCHO_DB_PASSWORD` | `honcho` | PostgreSQL 密码(**部署时必须改**) |
|
||||||
|
| `POSTGRES_HOST_AUTH_METHOD` | `scram-sha-256` | PG 认证方式 |
|
||||||
|
| `Volumes_Path` | `/data/Volumes/honcho` | 宿主机持久化数据根路径 |
|
||||||
|
| `HONCHO_API_PORT` | `8000` | API 宿主机端口 |
|
||||||
|
| `HONCHO_DB_PORT` | `5432` | PostgreSQL 宿主机端口 |
|
||||||
|
| `HONCHO_REDIS_PORT` | `6379` | Redis 宿主机端口 |
|
||||||
|
| `HONCHO_LOG_LEVEL` | `INFO` | Honcho 日志级别 |
|
||||||
|
| `HONCHO_AUTH_USE_AUTH` | `false` | 是否启用 JWT 鉴权(生产建议 `true`) |
|
||||||
|
| `HONCHO_NAMESPACE` | `honcho` | 全局命名空间前缀 |
|
||||||
|
| `HONCHO_EMBED_MESSAGES` | `true` | 是否对消息做向量化(关闭可省 embedding 费用) |
|
||||||
|
| `HONCHO_EMBEDDING_MODEL` | `Qwen/Qwen3-Embedding-8B` | Embedding 模型名(默认 SiliconFlow,可换本地 Ollama) |
|
||||||
|
| `HONCHO_EMBEDDING_BASE_URL` | `https://api.siliconflow.cn/v1` | Embedding API Base URL(OpenAI 兼容;Ollama 改 `http://host.docker.internal:11434/v1`) |
|
||||||
|
| `HONCHO_DERIVER_MODEL` | `gpt-5.4-mini` | Deriver 用的 LLM 模型(必须支持 tool calling) |
|
||||||
|
| `HONCHO_LLM_BASE_URL` | `https://api.openai.com/v1` | LLM API Base URL(OpenAI 兼容端点即可) |
|
||||||
|
| `HONCHO_DERIVER_WORKERS` | `1` | Deriver worker 数 |
|
||||||
|
|
||||||
|
### 敏感变量(`env.cfg`,不提交)
|
||||||
|
|
||||||
|
| 变量 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `HONCHO_LLM_API_KEY` | LLM API Key(**必填**,server 启动检查,没它起不来) |
|
||||||
|
| `HONCHO_EMBEDDING_API_KEY` | Embedding API Key(**必填**仅当走云端:SiliconFlow 在 [cloud.siliconflow.cn/account/ak](https://cloud.siliconflow.cn/account/ak) 生成;走 Ollama 时留空) |
|
||||||
|
| `HONCHO_DB_PASSWORD` | PostgreSQL 密码(**必填**,用强密码) |
|
||||||
|
| `HONCHO_AUTH_JWT_SECRET` | JWT 密钥(仅在 `HONCHO_AUTH_USE_AUTH=true` 时需要;用 `python scripts/generate_jwt_secret.py` 生成) |
|
||||||
|
|
||||||
|
**关键约束**:Honcho 启动时会**校验** `HONCHO_LLM_API_KEY` 和 `HONCHO_EMBEDDING_API_KEY` 都非空 — 缺失则立刻退出。这意味着 `env.cfg` 里这两项**不能用占位符**(如 `***`),必须填真实值,否则 `docker compose up -d` 后 deriver/api 容器会反复重启。
|
||||||
|
|
||||||
|
## 部署步骤
|
||||||
|
|
||||||
|
### 首次部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 准备数据目录(必须原生 ext4,不能放 9P drvfs)
|
||||||
|
sudo mkdir -pv /data/Volumes/honcho/{pgdata,redis,source}
|
||||||
|
sudo chown -R 999:999 /data/Volumes/honcho/pgdata
|
||||||
|
sudo chown -R 999:999 /data/Volumes/honcho/redis
|
||||||
|
|
||||||
|
# 2. 复制 env 模板并填入真实值
|
||||||
|
cp honcho/env.cfg.example honcho/env.cfg
|
||||||
|
$EDITOR honcho/env.cfg
|
||||||
|
# 必填:HONCHO_LLM_API_KEY(不能用空值/默认值,否则 deriver 起不来)
|
||||||
|
# 必填:HONCHO_DB_PASSWORD(改成强密码)
|
||||||
|
# 推荐改:HONCHO_DB_USER / HONCHO_DB_NAME(默认值 honcho 仅 dev 可用)
|
||||||
|
|
||||||
|
# 3. 拉镜像(PG + Redis 是预构建;api/deriver 从源码 build)
|
||||||
|
docker compose --env-file ./honcho/env.cfg -f ./honcho/stack.yml pull
|
||||||
|
|
||||||
|
# 4. 构建 + 启动(首次 api/deriver 构建需 5-10 分钟,依赖网络)
|
||||||
|
docker compose -p honcho --env-file ./honcho/env.cfg -f ./honcho/stack.yml up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 容器状态(必须 4 个都 healthy)
|
||||||
|
docker ps -f name=honcho
|
||||||
|
|
||||||
|
# API 健康检查
|
||||||
|
curl -s http://localhost:8000/health
|
||||||
|
|
||||||
|
# 数据库连接
|
||||||
|
docker exec -it honcho-database psql -U honcho -d honcho -c '\dt'
|
||||||
|
|
||||||
|
# pgvector 扩展确认
|
||||||
|
docker exec -it honcho-database psql -U honcho -d honcho \
|
||||||
|
-c "SELECT extname FROM pg_extension WHERE extname='vector';"
|
||||||
|
|
||||||
|
# Redis 连接
|
||||||
|
docker exec -it honcho-redis redis-cli ping
|
||||||
|
# 期望输出:PONG
|
||||||
|
|
||||||
|
# deriver 日志(看是否成功处理消息)
|
||||||
|
docker logs -f honcho-deriver --tail 50
|
||||||
|
|
||||||
|
# 端口监听
|
||||||
|
ss -tlnp | grep -E '8000|5432|6379'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 停止/重启
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 停止(保留数据)
|
||||||
|
docker compose -p honcho --env-file ./honcho/env.cfg -f ./honcho/stack.yml stop
|
||||||
|
|
||||||
|
# 完全销毁(**数据不删**,bind 挂载保留在宿主机)
|
||||||
|
docker compose -p honcho --env-file ./honcho/env.cfg -f ./honcho/stack.yml down
|
||||||
|
|
||||||
|
# 重启
|
||||||
|
docker compose -p honcho --env-file ./honcho/env.cfg -f ./honcho/stack.yml restart
|
||||||
|
```
|
||||||
|
|
||||||
|
## 关键设计决策
|
||||||
|
|
||||||
|
| 决策点 | 决定 | 原因 |
|
||||||
|
|--------|------|------|
|
||||||
|
| 镜像源 | api/deriver 从 [plastic-labs/honcho](https://github.com/plastic-labs/honcho) **源码 build** | 官方**没有预构建镜像**,Docker Hub 也没 — 必须 build |
|
||||||
|
| DB 版本 | PostgreSQL 18(pgvector 镜像 `pg18` tag) | 用户指定,比官方默认 pg15 新 |
|
||||||
|
| Redis 版本 | Redis 8 | 用户指定 |
|
||||||
|
| 数据卷方案 | bind 挂载到 `${Volumes_Path}/{pgdata,redis,source}` | 直观、可直接 `rsync`/`pg_dump`、跨机迁移用 `tar` 整个目录即可 |
|
||||||
|
| 端口绑定 | 0.0.0.0,含 DB 5432 | PVE LAN 上其他 VM 也可访问;DB 端口暴露方便外部工具(DBeaver 等)连接 |
|
||||||
|
| 认证 | 默认 `HONCHO_AUTH_USE_AUTH=false`(dev 模式) | 本地 LAN 自用,跳过 JWT 校验;公网暴露必须改 `true` |
|
||||||
|
| LLM 默认 | `gpt-5.4-mini`(主 LLM,OpenAI 兼容);embedding 默认 `Qwen/Qwen3-Embedding-8B`(dimensions=1536 强制输出,兼容已有 1536 维 schema)走 SiliconFlow;**备选** 本地 Ollama `qwen3-embedding:0.6b`(零成本、隐私优先) | LLM 走 OpenAI 兼容;embedding 双轨:SiliconFlow(云端,独立 base URL) / Ollama(本地 `host.docker.internal:11434/v1`) |
|
||||||
|
| Honcho 版本 | 默认 `main`(源码 build),可锁 tag 如 `v3.0.10` | 当前最新稳定版 v3.0.x,支持 peer card、dialectic、dream consolidation |
|
||||||
|
| deriver 必须 | api + deriver 双容器 | deriver 是后台推理 worker,没它记忆功能不工作 |
|
||||||
|
| PG 认证 | `scram-sha-256` | 比 md5 更安全,`POSTGRES_INITDB_ARGS` 同步设置 `--auth-host` |
|
||||||
|
|
||||||
|
## 关键陷阱(必读)
|
||||||
|
|
||||||
|
### 1. 首次构建时间长且需要 BuildKit
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 必须开启 BuildKit(默认 20.10+ 已启用,但确认下)
|
||||||
|
DOCKER_BUILDKIT=1 docker compose ...
|
||||||
|
```
|
||||||
|
|
||||||
|
- 首次 build api/deriver 镜像需 **5-10 分钟**(拉源码 + uv sync Python 依赖 + pip install ~300MB)
|
||||||
|
- 后续增量构建快(除非 Honcho 自身依赖变更)
|
||||||
|
- 构建失败常见原因:网络拉 `astral-sh/uv` 慢、Python wheel 编译失败 — 配置 Docker 镜像加速
|
||||||
|
|
||||||
|
### 2. deriver 必须健康,否则记忆不工作
|
||||||
|
|
||||||
|
如果只看到 `honcho-api` 是 `healthy` 但 `honcho-deriver` 反复重启或卡在 startup,**消息会写入但不会产生任何记忆**。检查:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs honcho-deriver --tail 100 | grep -iE "error|fatal"
|
||||||
|
```
|
||||||
|
|
||||||
|
deriver 起不来最常见原因:
|
||||||
|
- `HONCHO_LLM_API_KEY` 为空/无效 — server 启动立即校验
|
||||||
|
- LLM 模型不支持 tool calling — deriver 强依赖 function calling
|
||||||
|
- LLM API base URL 配错(如少了 `/v1` 后缀)
|
||||||
|
|
||||||
|
### 3. AGPL-3.0 传染条款
|
||||||
|
|
||||||
|
Honcho 是 **AGPL-3.0**,对网络服务部署有"用户可获取源码"的要求。本地 LAN 自用不触发,但若对外提供服务(哪怕只是 API 反代),需考虑:
|
||||||
|
- 对外服务时 `AUTH_USE_AUTH=true` + 公开 `AUTH_JWT_SECRET` 之外,**还需要向用户公开 Honcho 源码修改**
|
||||||
|
- 详见 [AGPL-3.0 §13](https://www.gnu.org/licenses/agpl-3.0.html)
|
||||||
|
|
||||||
|
### 4. WSL 9P `fsync` 陷阱
|
||||||
|
|
||||||
|
**PG/Redis 数据绝不能放 `/mnt/c/`、`/mnt/d/` 等 9P drvfs 路径**。`${Volumes_Path}` 必须指向 WSL 原生 ext4(`/data/Volumes/honcho`),否则可能静默数据损坏。
|
||||||
|
|
||||||
|
### 5. `POSTGRES_HOST_AUTH_METHOD=trust` 已删除
|
||||||
|
|
||||||
|
honcho-self-hosted 相对官方 compose 的一个改进:**移除了**`trust` 认证(官方默认的 dev 用法),改用强密码 + scram-sha-256。生产环境务必保留这个设置。
|
||||||
|
|
||||||
|
### 6. 容器端口 vs 宿主机端口不可混用
|
||||||
|
|
||||||
|
**容器之间互访必须用容器内端口(5432/6379/8000)**,不能用宿主机映射端口(如 `HONCHO_DB_PORT=25432`)。错误示例:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# ❌ 错:${HONCHO_DB_PORT} 是宿主机端口 25432,容器内根本没监听这个
|
||||||
|
DB_CONNECTION_URI=postgresql+psycopg://honcho:pw@database:${HONCHO_DB_PORT}/honcho
|
||||||
|
|
||||||
|
# ✅ 对:硬编码容器内端口 5432
|
||||||
|
DB_CONNECTION_URI=postgresql+psycopg://honcho:pw@database:5432/honcho
|
||||||
|
```
|
||||||
|
|
||||||
|
同样 healthcheck 也用容器内端口 `localhost:8000`,**不是** `localhost:18000`(宿主映射端口)。
|
||||||
|
|
||||||
|
## 故障排查
|
||||||
|
|
||||||
|
| 症状 | 排查命令 |
|
||||||
|
|------|----------|
|
||||||
|
| api 容器起不来 | `docker logs -f honcho-api` — 通常是 `LLM_OPENAI_API_KEY is required` 或 DB 连接失败 |
|
||||||
|
| deriver 反复重启 | `docker logs -f honcho-deriver` — 检查 LLM key、模型名、base URL |
|
||||||
|
| DB 连不上(容器内) | `docker exec -it honcho-database psql -U honcho -d honcho` |
|
||||||
|
| DB 连不上(外部工具) | 确认 `HONCHO_DB_PORT` 已映射、`ss -tlnp` 检查 5432 监听;密码含特殊字符试改简单 |
|
||||||
|
| API `/health` 502/超时 | 检查 deriver 是否 healthy(`depends_on` 会卡住 api) |
|
||||||
|
| pgvector 扩展缺失 | `docker exec -it honcho-database psql -U honcho -d honcho -c "CREATE EXTENSION IF NOT EXISTS vector;"` |
|
||||||
|
| 端口冲突 | `ss -tlnp \| grep -E '8000\|5432\|6379'` — 检查是否与 hindsight/dbSer 等服务撞车 |
|
||||||
|
| 慢查询 / DB 锁 | `docker exec -it honcho-database psql -U honcho -d honcho -c "SELECT * FROM pg_stat_activity;"` |
|
||||||
|
| 密码含特殊字符连不上 | `HONCHO_DB_PASSWORD` 最好只用字母数字,避免 URI 编码问题;如必须用,把 URL 里特殊字符 percent-encode |
|
||||||
|
|
||||||
|
## 与 Hermes Agent 集成
|
||||||
|
|
||||||
|
Hermes plugin 通过 HTTP 调用 Honcho 的 REST API(`localhost:8000`),不直连 DB。配置在 `~/.hermes/config.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
memory:
|
||||||
|
provider: honcho
|
||||||
|
honcho:
|
||||||
|
api_url: http://localhost:8000
|
||||||
|
# api_key 不需要(本地自托管,AUTH_USE_AUTH=false)
|
||||||
|
workspace_id: hermes
|
||||||
|
auto_recall: true
|
||||||
|
auto_retain: true
|
||||||
|
```
|
||||||
|
|
||||||
|
切换命令:`hermes config set memory.provider honcho`
|
||||||
|
|
||||||
|
**与 Hindsight 的差异**:
|
||||||
|
- Hindsight 强调 **跨会话长期记忆**(基于时序、bi-temporal)
|
||||||
|
- Honcho 强调 **peer-centric 用户画像**(多 peer 互观察、推理、deduction)
|
||||||
|
- 两者可并存;Hermes 当前用 Honcho 做主记忆层,Hindsight 作为补充
|
||||||
|
|
||||||
|
## 备份与恢复
|
||||||
|
|
||||||
|
### 自动备份(推荐)
|
||||||
|
|
||||||
|
`backup.job`(待补)— 用 `pg_dump` 热备份 PG + `redis-cli BGSAVE` 备份 Redis。接入 cron:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# /etc/cron.d/honcho-backup
|
||||||
|
30 3 * * * /path/to/deploy.stack/honcho/backup.job >> /var/log/honcho-backup.log 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
或参考 `crontab/` 目录的统一任务管理方式。
|
||||||
|
|
||||||
|
### 手动备份
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# PG 热备份
|
||||||
|
docker exec honcho-database pg_dump -U honcho -d honcho | \
|
||||||
|
gzip > /data/Volumes/honcho/backups/honcho_$(date +%Y%m%d).sql.gz
|
||||||
|
|
||||||
|
# Redis 快照
|
||||||
|
docker exec honcho-redis redis-cli BGSAVE
|
||||||
|
# 触发后 /data/Volumes/honcho/redis/dump.rdb 是最新快照
|
||||||
|
```
|
||||||
|
|
||||||
|
### 恢复
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 从 pg_dump 恢复(需要先创建空 DB)
|
||||||
|
gunzip -c /data/Volumes/honcho/backups/honcho_20260619.sql.gz | \
|
||||||
|
docker exec -i honcho-database psql -U honcho -d honcho
|
||||||
|
|
||||||
|
# 从 Redis dump 恢复
|
||||||
|
docker compose -p honcho --env-file ./honcho/env.cfg -f ./honcho/stack.yml stop honcho-redis
|
||||||
|
sudo cp /data/Volumes/honcho/backups/dump.rdb /data/Volumes/honcho/redis/dump.rdb
|
||||||
|
sudo chown 999:999 /data/Volumes/honcho/redis/dump.rdb
|
||||||
|
docker compose -p honcho --env-file ./honcho/env.cfg -f ./honcho/stack.yml start honcho-redis
|
||||||
|
```
|
||||||
|
|
||||||
|
## 升级
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 拉取最新源码(在 host 上或临时容器)
|
||||||
|
cd /data/Volumes/honcho/source && git pull
|
||||||
|
|
||||||
|
# 2. 重建 api + deriver 镜像
|
||||||
|
docker compose -p honcho --env-file ./honcho/env.cfg -f ./honcho/stack.yml build api deriver
|
||||||
|
|
||||||
|
# 3. 滚动重启
|
||||||
|
docker compose -p honcho --env-file ./honcho/env.cfg -f ./honcho/stack.yml up -d
|
||||||
|
|
||||||
|
# 4. 跑迁移(honcho entrypoint.sh 会自动执行;若需手动跑)
|
||||||
|
docker exec -it honcho-api sh -c "cd /app && .venv/bin/alembic upgrade head"
|
||||||
|
```
|
||||||
|
|
||||||
|
**PG 大版本升级**(如未来 18→19)需 `pg_dump` → 新版本空 DB → restore,**不能直接换 tag**。
|
||||||
|
|
||||||
|
## 相关文档
|
||||||
|
|
||||||
|
- [plastic-labs/honcho](https://github.com/plastic-labs/honcho) — 上游仓库
|
||||||
|
- [elkimek/honcho-self-hosted](https://github.com/elkimek/honcho-self-hosted) — 一键安装器,本目录配置基于此
|
||||||
|
- [Honcho 自托管官方文档](https://honcho.dev/docs/v3/contributing/self-hosting)
|
||||||
|
- `hindsight/readme.md` — 同仓库姊妹服务,部署模式高度相似
|
||||||
|
- 仓库根 `AGENTS.md` — `deploy.stack` 项目规范
|
||||||
|
- `crontab/` — 定时任务集成参考
|
||||||
|
|
||||||
|
## 已知限制
|
||||||
|
|
||||||
|
详见上文 [关键陷阱](#关键陷阱必读) — 主要为:无预构建镜像(必须源码构建)/ AGPL-3.0 传染 / deriver 强依赖 LLM。
|
||||||
@@ -0,0 +1,285 @@
|
|||||||
|
# Honcho 多 Hermes 客户端共享方案
|
||||||
|
|
||||||
|
> 状态: 📝 草案 (2026-06-20 创建, 06-26 拓扑修正 + v3.0.10 schema 探针重写)
|
||||||
|
> 适用: vm61 (10.8.0.9, 备用/测试环境) 部署 honcho v3.0.10 + 3 个 hermes 客户端共享同一份记忆
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 场景
|
||||||
|
|
||||||
|
| 客户端 | 位置 | WireGuard IP | 网络到 vm61 | peer 名 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| mypc03 (WSL Debian) | 🏠 家里 LAN | `10.8.0.112` | WireGuard → vm61 | `laodeng-mypc03x` |
|
||||||
|
| gov-pc (公司机器) | 🏢 公司 | `10.8.0.143` | WireGuard → vm61 | `laodeng-govpcxxxx` |
|
||||||
|
| macbook | ☕ 任意位置 | `10.8.0.144` | WireGuard → vm61 | `laodeng-macxxxxxxx` |
|
||||||
|
|
||||||
|
**3 个客户端都是老登本人**用,所以希望:
|
||||||
|
- ✅ **共享 workspace**(`home`):在 A 上聊的事,B 上能召回
|
||||||
|
- ✅ **peer 独立**(带设备后缀):方便审计"在哪台设备说的"
|
||||||
|
- ✅ **AUTH 关闭(DEV 模式)**:vm61 honcho v3.0.10 实例 `USE_AUTH=False`,JWT_SECRET 留空,peer 不强制鉴权;接入稳后再开
|
||||||
|
- ❌ 不共享 LLM 凭据:每个客户端用自己的 hermes LLM key
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 架构
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
subgraph Clients["3 个 Hermes 客户端"]
|
||||||
|
A[mypc03<br/>peer: laodeng-mypc03x]
|
||||||
|
B[gov-pc<br/>peer: laodeng-govpcxxxx]
|
||||||
|
C[macbook<br/>peer: laodeng-macxxxxxxx]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph Vm61["vm61 (192.168.10.61 / WG 10.8.0.9, 备用)"]
|
||||||
|
WG[WireGuard<br/>10.8.0.9 入口]
|
||||||
|
API[honcho-api:8000<br/>AUTH OFF (v3 DEV)]
|
||||||
|
DB[(postgres+pgvector)]
|
||||||
|
DERIVER[honcho-deriver<br/>~2 done/min]
|
||||||
|
REDIS[(redis)]
|
||||||
|
end
|
||||||
|
|
||||||
|
A ==wg==> WG
|
||||||
|
B ==wg==> WG
|
||||||
|
C ==wg==> WG
|
||||||
|
WG --> API
|
||||||
|
API --> DB
|
||||||
|
API --> REDIS
|
||||||
|
DERIVER <--> REDIS
|
||||||
|
DERIVER <--> DB
|
||||||
|
|
||||||
|
classDef client fill:#e1f5ff,stroke:#0066cc
|
||||||
|
classDef svc fill:#fff4e1,stroke:#cc6600
|
||||||
|
classDef store fill:#e8f5e9,stroke:#2e7d32
|
||||||
|
class A,B,C client
|
||||||
|
class WG,API,DERIVER svc
|
||||||
|
class DB,REDIS store
|
||||||
|
```
|
||||||
|
|
||||||
|
**网络**:3 客户端 (10.8.0.112/143/144) → WireGuard 隧道 (10.8.0.x) → vm61 (10.8.0.9) 8000
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 为什么这样设计
|
||||||
|
|
||||||
|
| 决策 | 选择 | 替代方案 | 理由 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **AUTH 关闭(DEV)** | ✅ OFF | ON | 当前 vm61 honcho v3.0.10 `USE_AUTH=False`;3 客户端同源(同老登)+ WireGuard 内网隔离已足够;生产或多人共用必须开 |
|
||||||
|
| **Workspace** | `home` 一个共用 | 每个 peer 独立 ws | 老登本人用,跨设备回忆体验更好 |
|
||||||
|
| **Peer** | 带设备后缀 | 统一 `laodeng` | 审计需要知道"哪台设备写的";peer 概念在 honcho 里是身份,不影响记忆语义 |
|
||||||
|
| **API URL** | `http://10.8.0.9:18000`(vm61 WireGuard IP) | 公网 IP / 域名 | WireGuard 已加密 + 认证,没必要再绕公网 |
|
||||||
|
| **LLM 凭据** | 客户端本地保留 | 共享到 honcho | deriver 已经持有全局 LLM key;客户端 hermes 自己的对话 LLM 不应上送 honcho |
|
||||||
|
| **deriver 后台** | 共享 vm61 上现有 | 每客户端本地跑 | honcho deriver 设计就是单实例后台,集中推理更省 API 配额 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 实施步骤
|
||||||
|
|
||||||
|
### Phase 1: vm61 上 honcho 准备
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1.1 确认 4 个容器 Up
|
||||||
|
docker ps | grep -E "honcho-(api|deriver|database|redis)"
|
||||||
|
|
||||||
|
# 1.2 确认 AUTH 状态(v3.0.10 实际为 DEV OFF,2026-06-26 探针实测)
|
||||||
|
ssh yong@10.8.0.9 'docker exec honcho-api python3 -c "from src.config import settings; print(\"USE_AUTH:\", settings.AUTH.USE_AUTH)"'
|
||||||
|
# 期望: USE_AUTH: False(当前状态)
|
||||||
|
|
||||||
|
# 1.3 确认 honcho-api 监听 0.0.0.0(不是 127.0.0.1)
|
||||||
|
docker inspect honcho-api | grep -A2 -E "HostPort|NetworkMode"
|
||||||
|
# 或直接看启动日志
|
||||||
|
docker logs honcho-api 2>&1 | grep -i "listening"
|
||||||
|
|
||||||
|
# 1.4 从 WireGuard 网卡验证
|
||||||
|
curl -s http://10.8.0.9:18000/health
|
||||||
|
# 期望: {"status":"ok"}
|
||||||
|
```
|
||||||
|
|
||||||
|
**如果 1.3 / 1.4 失败**:
|
||||||
|
- stack.yml 里 `ports:` 必须暴露 `0.0.0.0:18000:18000`
|
||||||
|
- 6-19 修过的 `DB_CONNECTION_URI` / `CACHE_URL` 已稳定,但确认 WireGuard 网卡没被 firewall 拦
|
||||||
|
|
||||||
|
### Phase 2: v3 鉴权模式 + peer 创建
|
||||||
|
|
||||||
|
**v3.0.10 实测 schema(2026-06-26 探针)**:
|
||||||
|
|
||||||
|
| 关键事实 | 说明 |
|
||||||
|
|---|---|
|
||||||
|
| 端点前缀 | **/v3/**(不是 /v2/) |
|
||||||
|
| 鉴权 | `HTTPBearer(auto_error=False)` — 未带 token 放行(DEV 模式表现) |
|
||||||
|
| `AUTH.USE_AUTH` 开关 | False 时所有 peer 操作无需 token;True 时需 admin JWT |
|
||||||
|
| 创建 JWT 端点 | `POST /v3/keys?workspace_id=&peer_id=&session_id=`(admin auth 强制) |
|
||||||
|
| 创建 workspace | `POST /v3/workspaces` body `{"id":"home"}` |
|
||||||
|
| 创建 peer | `POST /v3/workspaces/{ws_id}/peers` body `{"id":"<peer_id>"}` |
|
||||||
|
| Peer ID 格式 | text 21 字符,`^[A-Za-z0-9_-]+$`(**不是 UUID**) |
|
||||||
|
| DB schema | `peers(id PK text, name text, workspace_name FK→workspaces(name))` |
|
||||||
|
| DB schema | **无 `api_keys` 表**(v3 用 JWT,无独立 key 表) |
|
||||||
|
|
||||||
|
**当前 DEV 模式(USE_AUTH=False)下,3 客户端接入步骤**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 2.1 确认 workspace 已存在
|
||||||
|
ssh yong@10.8.0.9 'curl -s -X POST http://127.0.0.1:18000/v3/workspaces \
|
||||||
|
-H "Content-Type: application/json" -d "{\"id\":\"home\"}"'
|
||||||
|
# 期望: {"id":"home",...} 或已存在返回
|
||||||
|
|
||||||
|
# 2.2 创建 3 个 peer(peer_id 必须 21 字符,格式 ^[A-Za-z0-9_-]+$)
|
||||||
|
for PEER in laodeng-mypc03x laodeng-govpcxxxx laodeng-macxxxxxxx; do
|
||||||
|
ssh yong@10.8.0.9 "curl -s -X POST http://127.0.0.1:18000/v3/workspaces/home/peers \
|
||||||
|
-H 'Content-Type: application/json' -d '{\"id\":\"$PEER\"}'"
|
||||||
|
echo "--- $PEER done ---"
|
||||||
|
done
|
||||||
|
# 期望: 3 个 200 OK 返回 peer 对象
|
||||||
|
```
|
||||||
|
|
||||||
|
**未来开 AUTH(USE_AUTH=True)时**:每个 peer 创建后用 `POST /v3/keys?workspace_id=home&peer_id=<id>` 拿 scoped JWT,scp 到客户端 `~/.honcho-keys/<peer>.key`,hermes config `memory.honcho.api_key` 填 JWT。
|
||||||
|
|
||||||
|
### Phase 3: 3 客户端配置 hermes
|
||||||
|
|
||||||
|
每台机器执行(**当前 DEV 模式不填 api_key;AUTH 开后填 JWT**):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 通用(3 台都跑)
|
||||||
|
hermes config set memory.provider honcho
|
||||||
|
hermes config set memory.honcho.api_url http://10.8.0.9:18000
|
||||||
|
hermes config set memory.honcho.workspace home
|
||||||
|
|
||||||
|
# mypc03
|
||||||
|
hermes config set memory.honcho.peer laodeng-mypc03x
|
||||||
|
|
||||||
|
# gov-pc
|
||||||
|
hermes config set memory.honcho.peer laodeng-govpcxxxx
|
||||||
|
|
||||||
|
# macbook
|
||||||
|
hermes config set memory.honcho.peer laodeng-macxxxxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 4: 交叉验证(关键!)
|
||||||
|
|
||||||
|
**Step A: 网络 + honcho 响应**(3 台机器各跑)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# DEV 模式不带 token 也能访问
|
||||||
|
curl -s -o /dev/null -w "HTTP %{http_code}\n" \
|
||||||
|
http://10.8.0.9:18000/v3/workspaces/home/peers
|
||||||
|
# 期望: HTTP 200
|
||||||
|
```
|
||||||
|
|
||||||
|
**未来 AUTH 开启后改用**:
|
||||||
|
```bash
|
||||||
|
curl -s -o /dev/null -w "HTTP %{http_code}\n" \
|
||||||
|
-H "Authorization: Bearer $(cat ~/.honcho-keys/xxx.key)" \
|
||||||
|
http://10.8.0.9:18000/v3/workspaces/home/peers
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step B: 跨端召回**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# mypc03 写一条
|
||||||
|
hermes memory retain "2026-06-26 mypc03 测试 honcho v3 跨设备共享"
|
||||||
|
|
||||||
|
# gov-pc 召回
|
||||||
|
hermes memory recall "honcho v3 跨设备共享"
|
||||||
|
# 期望: 看到 mypc03 写的那条
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step C: 隔离验证(确认 peer 字段)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# honcho 管理(vm61 上)— 注意 v3 列名是 workspace_name 不是 workspace
|
||||||
|
ssh yong@10.8.0.9 'docker exec honcho-database psql -U honcho -d honcho -c \
|
||||||
|
"SELECT name, created_at FROM peers WHERE workspace_name = '\''home'\'';"'
|
||||||
|
# 期望: 3 行,name 各不相同(带设备后缀)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 5: deriver 容量观察
|
||||||
|
|
||||||
|
接入第 3 个客户端后,前 2 天重点观察:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# vm61 看 deriver 进度
|
||||||
|
docker logs honcho-deriver --since 1h | grep -E "queue|processed|done"
|
||||||
|
|
||||||
|
# 队列深度(v3 端点)
|
||||||
|
ssh yong@10.8.0.9 'curl -s http://127.0.0.1:18000/v3/workspaces/home/queue/status' | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
**告警阈值**:
|
||||||
|
|
||||||
|
| 指标 | 正常 | 警告 | 干预 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 队列深度 | < 500 | 500-2000 | > 2000 持续 1h → 考虑错峰 |
|
||||||
|
| deriver done/min | 2-4 | 4-8 | > 8 持续 → 加 worker |
|
||||||
|
| Postgres 连接 | < 50 | 50-100 | > 100 → 调大 max_connections |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 故障排查
|
||||||
|
|
||||||
|
| 症状 | 排查 | 修复 |
|
||||||
|
|---|---|---|
|
||||||
|
| `curl HTTP 401` | AUTH 已开但缺 token / token 过期 | 重新创建 JWT(`POST /v3/keys?workspace_id=home`) |
|
||||||
|
| `curl HTTP 422` | peer_id 格式不符(必须 21 字符 `^[A-Za-z0-9_-]+$`) | 调整 peer_id 长度/字符 |
|
||||||
|
| `curl HTTP 404` | workspace 名错 | `hermes config get memory.honcho.workspace` 必须 = `home` |
|
||||||
|
| `curl timeout` | WireGuard 没拨上 | `wg show` 看握手时间;`ping 10.8.0.9` |
|
||||||
|
| 召回不到 mypc03 写的 | peer 不在同一 workspace | 三台 `hermes config get memory.honcho.workspace` 都该是 `home` |
|
||||||
|
| deriver 队列暴涨 | LLM 限流(SiliconFlow) | 临时调低 deriver 并发;或加备份 LLM endpoint |
|
||||||
|
| honcho-api OOM | 写入太频繁 | `docker stats honcho-api`;考虑加 limit |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 撤销 / 隔离某个客户端
|
||||||
|
|
||||||
|
需要把 gov-pc 从共享里踢出去(换工作 / 借人):
|
||||||
|
|
||||||
|
**DEV 模式**:直接删 peer(v3 REST)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# v3 REST 删除 peer(DEV 模式不带 token)
|
||||||
|
ssh yong@10.8.0.9 'curl -s -X DELETE \
|
||||||
|
http://127.0.0.1:18000/v3/workspaces/home/peers/laodeng-govpcxxxx'
|
||||||
|
```
|
||||||
|
|
||||||
|
**AUTH 开启后**:先删 JWT,再删 peer
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 服务端撤 JWT(v3 没有 api_keys 表;JWT 自身无法服务端 revoke,只能靠短期 exp)
|
||||||
|
# 解决:缩短 JWT exp(如 24h),或重新生成 admin token 改 settings.AUTH
|
||||||
|
|
||||||
|
# 2. 删 peer
|
||||||
|
ssh yong@10.8.0.9 'curl -s -X DELETE \
|
||||||
|
-H "Authorization: Bearer $(cat /root/.honcho-keys/admin.key)" \
|
||||||
|
http://127.0.0.1:18000/v3/workspaces/home/peers/laodeng-govpcxxxx'
|
||||||
|
```
|
||||||
|
|
||||||
|
**清理历史消息**(如要彻底删除 gov-pc 的数据):
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- v3 schema: peer_id 是 text 不是 UUID;name 是 peer 的可读名
|
||||||
|
DELETE FROM messages WHERE peer_id = (SELECT id FROM peers WHERE name = 'laodeng-govpcxxxx');
|
||||||
|
DELETE FROM session_peers WHERE peer_id = (SELECT id FROM peers WHERE name = 'laodeng-govpcxxxx');
|
||||||
|
DELETE FROM peers WHERE name = 'laodeng-govpcxxxx';
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 关联资源
|
||||||
|
|
||||||
|
| 资源 | 路径 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| honcho stack | `deploy.stack/honcho/` | 当前部署 |
|
||||||
|
| WireGuard 部署 | `deploy.stack/WireGuardVPN/wg-easy/` | 已有,给 3 客户端分配 10.8.0.112/143/144,honcho 服务端在 10.8.0.9 |
|
||||||
|
| honcho deriver 调试 | honcho memory (2026-06-19/20) | deriver 修复历史 |
|
||||||
|
| Hermes memory provider 切换 | hermes-agent skill | `memory.provider honcho` 配法 |
|
||||||
|
| 凭据管理 | `~/.honcho-keys/` | chmod 600,绝不入 git;DEV 模式暂未启用 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 后续 TODO(可选)
|
||||||
|
|
||||||
|
- [ ] 把 `memory.honcho.api_url` 改成 hostname 而非 IP(DNS 友好)
|
||||||
|
- [ ] 给 honcho-api 加 TLS(自签 CA 推 3 客户端)
|
||||||
|
- [ ] deriver 加 Prometheus exporter,接 vm61 VictoriaMetrics
|
||||||
|
- [ ] cron: 每天 pg_dump honcho DB → dufs 备份(参考 hindsight/backup.job)
|
||||||
|
- [ ] 4 个客户端的 hermes 版本统一(避免 protocol 不一致)
|
||||||
|
- [ ] 评估何时开 AUTH(USE_AUTH=True)+ 配 scoped JWT 体系
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
# Honcho Self-Hosted 部署栈
|
||||||
|
# ============================================================
|
||||||
|
# 部署前准备(仅首次):
|
||||||
|
# mkdir -pv ${Volumes_Path}/{pgdata,redis,source}
|
||||||
|
# sudo chown -R 999:999 ${Volumes_Path}/pgdata
|
||||||
|
# sudo chown -R 999:999 ${Volumes_Path}/redis
|
||||||
|
# git clone https://github.com/plastic-labs/honcho.git ${Volumes_Path}/honcho/source
|
||||||
|
# cp env.cfg.example env.cfg && $EDITOR env.cfg # 填入密码/API Key
|
||||||
|
#
|
||||||
|
# pull:: docker compose --env-file ./honcho/env.cfg -f ./honcho/stack.yml pull
|
||||||
|
# RUN:: docker compose -p honcho --env-file ./honcho/env.cfg -f ./honcho/stack.yml up -d --build
|
||||||
|
# disc::
|
||||||
|
# - api/deriver 从 ${Volumes_Path}/honcho/source 源码 build(不是运行时 bind)
|
||||||
|
# - DB/Redis 数据 bind 挂到 WSL/Linux 原生 ext4(不能放 /mnt/9P drvfs)
|
||||||
|
# - 端口 8000=API, 5432=PG, 6379=Redis,全部绑定 0.0.0.0 供 LAN 访问
|
||||||
|
# - 必须设置 HONCHO_LLM_API_KEY(占位符会导致 deriver 反复重启)
|
||||||
|
# - deriver 不可省:没它消息能写但不会产生记忆
|
||||||
|
# - PG 5432 与 hindsight/dbSer 撞车,通过 HONCHO_DB_PORT 区分
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
api:
|
||||||
|
build:
|
||||||
|
context: ${Volumes_Path}/source
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: honcho-api
|
||||||
|
restart: unless-stopped
|
||||||
|
entrypoint: ["sh", "docker/entrypoint.sh"]
|
||||||
|
depends_on:
|
||||||
|
database:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
ports:
|
||||||
|
- "${HONCHO_API_PORT:-8000}:8000"
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- DB_CONNECTION_URI=postgresql+psycopg://${HONCHO_DB_USER}:${HONCHO_DB_PASSWORD}@database:5432/${HONCHO_DB_NAME}
|
||||||
|
- CACHE_URL=redis://redis:${HONCHO_REDIS_PORT}/0?suppress=true
|
||||||
|
- CACHE_ENABLED=true
|
||||||
|
- LOG_LEVEL=${HONCHO_LOG_LEVEL:-INFO}
|
||||||
|
- NAMESPACE=${HONCHO_NAMESPACE:-honcho}
|
||||||
|
- EMBED_MESSAGES=${HONCHO_EMBED_MESSAGES:-true}
|
||||||
|
- EMBEDDING_MODEL_CONFIG__TRANSPORT=openai
|
||||||
|
- EMBEDDING_MODEL_CONFIG__MODEL=${HONCHO_EMBEDDING_MODEL:-Qwen/Qwen3-Embedding-8B}
|
||||||
|
- EMBEDDING_MODEL_CONFIG__OVERRIDES__BASE_URL=${HONCHO_EMBEDDING_BASE_URL:-https://api.siliconflow.cn/v1}
|
||||||
|
- EMBEDDING_MODEL_CONFIG__OVERRIDES__DIMENSIONS=1536
|
||||||
|
- EMBEDDING_VECTOR_DIMENSIONS=1536
|
||||||
|
- EMBEDDING_API_KEY=${HONCHO_EMBEDDING_API_KEY:-}
|
||||||
|
- DERIVER_MODEL_CONFIG__TRANSPORT=openai
|
||||||
|
- DERIVER_MODEL_CONFIG__MODEL=${HONCHO_DERIVER_MODEL:-gpt-4o-mini}
|
||||||
|
- DERIVER_WORKERS=${HONCHO_DERIVER_WORKERS:-1}
|
||||||
|
- LLM_OPENAI_API_KEY=${HONCHO_LLM_API_KEY:?set HONCHO_LLM_API_KEY}
|
||||||
|
- MODEL_CONFIG__OVERRIDES__BASE_URL=${HONCHO_LLM_BASE_URL:-https://api.openai.com/v1}
|
||||||
|
- AUTH_USE_AUTH=${HONCHO_AUTH_USE_AUTH:-false}
|
||||||
|
- AUTH_JWT_SECRET=${HONCHO_AUTH_JWT_SECRET}
|
||||||
|
- VECTOR_STORE_TYPE=pgvector
|
||||||
|
- VECTOR_STORE_MIGRATED=false
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- /app/.venv/bin/python
|
||||||
|
- -c
|
||||||
|
- "import urllib.request; urllib.request.urlopen('http://localhost:8000/health', timeout=2).read()"
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
start_period: 30s
|
||||||
|
networks:
|
||||||
|
- honcho-net
|
||||||
|
|
||||||
|
deriver:
|
||||||
|
build:
|
||||||
|
context: ${Volumes_Path}/source
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: honcho-deriver
|
||||||
|
restart: unless-stopped
|
||||||
|
entrypoint: ["/app/.venv/bin/python", "-m", "src.deriver"]
|
||||||
|
depends_on:
|
||||||
|
api:
|
||||||
|
condition: service_healthy
|
||||||
|
database:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- DB_CONNECTION_URI=postgresql+psycopg://${HONCHO_DB_USER}:${HONCHO_DB_PASSWORD}@database:5432/${HONCHO_DB_NAME}
|
||||||
|
- CACHE_URL=redis://redis:${HONCHO_REDIS_PORT}/0?suppress=true
|
||||||
|
- CACHE_ENABLED=true
|
||||||
|
- NAMESPACE=${HONCHO_NAMESPACE:-honcho}
|
||||||
|
- DERIVER_MODEL_CONFIG__TRANSPORT=openai
|
||||||
|
- DERIVER_MODEL_CONFIG__MODEL=${HONCHO_DERIVER_MODEL:-deepseek-ai/DeepSeek-V4-Flash}
|
||||||
|
- DERIVER_MODEL_CONFIG__OVERRIDES__BASE_URL=${HONCHO_LLM_BASE_URL:-https://api.siliconflow.cn/v1}
|
||||||
|
- DEDUCTION_MODEL_CONFIG__TRANSPORT=openai
|
||||||
|
- DEDUCTION_MODEL_CONFIG__MODEL=${HONCHO_DEDUCTION_MODEL:-deepseek-ai/DeepSeek-V4-Flash}
|
||||||
|
- DEDUCTION_MODEL_CONFIG__OVERRIDES__BASE_URL=${HONCHO_LLM_BASE_URL:-https://api.siliconflow.cn/v1}
|
||||||
|
- INDUCTION_MODEL_CONFIG__TRANSPORT=openai
|
||||||
|
- INDUCTION_MODEL_CONFIG__MODEL=${HONCHO_INDUCTION_MODEL:-deepseek-ai/DeepSeek-V4-Flash}
|
||||||
|
- INDUCTION_MODEL_CONFIG__OVERRIDES__BASE_URL=${HONCHO_LLM_BASE_URL:-https://api.siliconflow.cn/v1}
|
||||||
|
- DERIVER_WORKERS=${HONCHO_DERIVER_WORKERS:-1}
|
||||||
|
- EMBEDDING_MODEL_CONFIG__TRANSPORT=openai
|
||||||
|
- EMBEDDING_MODEL_CONFIG__MODEL=${HONCHO_EMBEDDING_MODEL:-Qwen/Qwen3-Embedding-8B}
|
||||||
|
- EMBEDDING_MODEL_CONFIG__OVERRIDES__BASE_URL=${HONCHO_EMBEDDING_BASE_URL:-https://api.siliconflow.cn/v1}
|
||||||
|
- EMBEDDING_MODEL_CONFIG__OVERRIDES__DIMENSIONS=1536
|
||||||
|
- EMBEDDING_VECTOR_DIMENSIONS=1536
|
||||||
|
- LLM_OPENAI_API_KEY=${HONCHO_LLM_API_KEY:?set HONCHO_LLM_API_KEY}
|
||||||
|
- EMBEDDING_API_KEY=${HONCHO_EMBEDDING_API_KEY:-}
|
||||||
|
- MODEL_CONFIG__OVERRIDES__BASE_URL=${HONCHO_LLM_BASE_URL:-https://api.openai.com/v1}
|
||||||
|
- AUTH_USE_AUTH=${HONCHO_AUTH_USE_AUTH:-false}
|
||||||
|
- AUTH_JWT_SECRET=${HONCHO_AUTH_JWT_SECRET}
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
networks:
|
||||||
|
- honcho-net
|
||||||
|
|
||||||
|
database:
|
||||||
|
image: ${HONCHO_DB_IMAGE:-pgvector/pgvector}:pg${HONCHO_DB_VERSION:-18}
|
||||||
|
container_name: honcho-database
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ["postgres", "-c", "max_connections=200"]
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- POSTGRES_USER=${HONCHO_DB_USER}
|
||||||
|
- POSTGRES_PASSWORD=${HONCHO_DB_PASSWORD:?set HONCHO_DB_PASSWORD}
|
||||||
|
- POSTGRES_DB=${HONCHO_DB_NAME}
|
||||||
|
- POSTGRES_HOST_AUTH_METHOD=${POSTGRES_HOST_AUTH_METHOD:-scram-sha-256}
|
||||||
|
- POSTGRES_INITDB_ARGS=--encoding=UTF8 --locale=C --auth-host=${POSTGRES_HOST_AUTH_METHOD:-scram-sha-256}
|
||||||
|
- PGDATA=/var/lib/postgresql/data/pgdata
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- ${Volumes_Path}/pgdata:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- "${HONCHO_DB_PORT:-5432}:5432"
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD-SHELL
|
||||||
|
- pg_isready -U ${HONCHO_DB_USER} -d ${HONCHO_DB_NAME}
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
networks:
|
||||||
|
- honcho-net
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: ${HONCHO_REDIS_IMAGE:-redis}:${HONCHO_REDIS_VERSION:-8}
|
||||||
|
container_name: honcho-redis
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ["redis-server", "--save", "60", "1", "--appendonly", "yes"]
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- ${Volumes_Path}/redis:/data
|
||||||
|
ports:
|
||||||
|
- "${HONCHO_REDIS_PORT:-6379}:6379"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "redis-cli ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
- honcho-net
|
||||||
|
|
||||||
|
networks:
|
||||||
|
honcho-net:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# ============================================================
|
||||||
|
# hub-registry 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p hub-registry --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG=hub.tp229.com:3500/registry:3.0
|
||||||
|
|
||||||
|
UI_IMAGE_TAG=hub.tp229.com:3500/cnphpbb/registry-ui:latest
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# run:: docker compose -p memos --env-file ./it-tools/env.cfg -f ./it-tools/compose.yml up -d
|
# run:: docker compose -p it-tools --env-file ./it-tools/env.cfg -f ./it-tools/compose.yml up -d
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# ============================================================
|
||||||
|
# it-tools 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p it-tools --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG=hub.6t7.net/cnphpbb/it-tools:20241022
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# IT Tools 部署栈
|
||||||
|
|
||||||
|
[IT Tools](https://github.com/CorentinTh/it-tools) 是一个面向开发者的在线工具集合,提供编码、转换、格式化、加密等多种实用功能。基于 Vue + TypeScript 构建,拥有良好的交互体验。
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `compose.yml` | Docker Compose 部署配置 |
|
||||||
|
| `env.cfg` | 环境变量(镜像版本,已 gitignore) |
|
||||||
|
| `env.cfg.example` | 环境变量模板 |
|
||||||
|
|
||||||
|
## 部署命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 拉取镜像
|
||||||
|
docker compose -p it-tools --env-file ./it-tools/env.cfg -f ./it-tools/compose.yml pull
|
||||||
|
|
||||||
|
# 部署
|
||||||
|
docker compose -p it-tools --env-file ./it-tools/env.cfg -f ./it-tools/compose.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## 环境变量
|
||||||
|
|
||||||
|
| 变量 | 说明 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| `IMAGE_TAG` | 完整镜像标签 | `hub.6t7.net/cnphpbb/it-tools:20241022` |
|
||||||
|
|
||||||
|
## 服务端口
|
||||||
|
|
||||||
|
| 宿主机 | 容器 |
|
||||||
|
|--------|------|
|
||||||
|
| `8380` | `80` |
|
||||||
|
|
||||||
|
## Docker 构建说明
|
||||||
|
|
||||||
|
上游仓库包含 `Dockerfile`,支持多阶段构建(node 构建 → nginx 运行):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/CorentinTh/it-tools.git
|
||||||
|
cd it-tools
|
||||||
|
|
||||||
|
# 构建镜像
|
||||||
|
docker buildx build --platform linux/amd64 -t hub.6t7.net/cnphpbb/it-tools:<tag> .
|
||||||
|
|
||||||
|
# 推送到仓库
|
||||||
|
docker push hub.6t7.net/cnphpbb/it-tools:<tag>
|
||||||
|
```
|
||||||
|
|
||||||
|
构建依赖:
|
||||||
|
- 构建阶段:`node:lts-alpine` + `pnpm`,执行 `pnpm build` 生成静态文件
|
||||||
|
- 运行阶段:`nginx:stable-alpine`,提供 `nginx.conf` 自定义配置
|
||||||
|
- 环境变量:`NPM_CONFIG_LOGLEVEL=warn`、`CI=true`
|
||||||
|
- 上游 Dockerfile 参考:[Dockerfile](https://github.com/CorentinTh/it-tools/blob/main/Dockerfile)
|
||||||
|
|
||||||
|
## 相关链接
|
||||||
|
|
||||||
|
- GitHub: <https://github.com/CorentinTh/it-tools>
|
||||||
|
- 在线体验: <https://it-tools.tech>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# ============================================================
|
||||||
|
# joplin 部署 — amd64 专用环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 amd.env.cfg 后填入真实值,amd.env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp amd.env.cfg.example amd.env.cfg
|
||||||
|
# $EDITOR amd.env.cfg # 填入真实密码后保存
|
||||||
|
# docker compose -p joplin --env-file ./joplin/amd.env.cfg -f ./joplin/compose.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,amd.env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
IMAGE_TAG=joplin/server:3.6.1
|
||||||
|
|
||||||
|
# only amd64
|
||||||
|
|
||||||
|
#IMAGE_TAG=joplin/server:2.14.2-beta
|
||||||
|
|
||||||
|
## 实际部署时需要考虑APP_BASE_URL变量值
|
||||||
|
|
||||||
|
APP_BASE_URL=https://joplin.6t7.net
|
||||||
|
|
||||||
|
POSTGRES_USER=postgres
|
||||||
|
|
||||||
|
POSTGRES_PASSWORD=<your-strong-password>
|
||||||
|
|
||||||
|
POSTGRES_DATABASE=joplin-db
|
||||||
|
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
|
||||||
|
POSTGRES_HOST=10.0.74.3
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# ============================================================
|
||||||
|
# joplin 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p joplin --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
#IMAGE_TAG=etechonomy/joplin-server:2.14.2
|
||||||
|
|
||||||
|
#IMAGE_TAG=florider89/joplin-server:2.14.2
|
||||||
|
|
||||||
|
IMAGE_TAG=joplin/server:3.6.1
|
||||||
|
|
||||||
|
# only amd64
|
||||||
|
|
||||||
|
#IMAGE_TAG=joplin/server:2.14.2-beta
|
||||||
|
|
||||||
|
## 实际部署时需要考虑APP_BASE_URL变量值
|
||||||
|
|
||||||
|
APP_BASE_URL=http://192.168.100.184:22300
|
||||||
|
|
||||||
|
POSTGRES_USER=postgres
|
||||||
|
|
||||||
|
POSTGRES_PASSWORD=<your-strong-password>
|
||||||
|
|
||||||
|
POSTGRES_DATABASE=joplin-db
|
||||||
|
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
|
||||||
|
POSTGRES_HOST=192.168.100.184
|
||||||
+1
-1
@@ -3,4 +3,4 @@ DB_USER=postgres
|
|||||||
DB_PASSWORD=Kevin0412PgSql
|
DB_PASSWORD=Kevin0412PgSql
|
||||||
DB_DATANAME=memos-db
|
DB_DATANAME=memos-db
|
||||||
DB_HOST=192.168.100.184
|
DB_HOST=192.168.100.184
|
||||||
DB_POST=5432
|
DB_POST=15432
|
||||||
|
|||||||
+1
-1
@@ -3,4 +3,4 @@ DB_USER=postgres
|
|||||||
DB_PASSWORD=Kevin0412PgSql
|
DB_PASSWORD=Kevin0412PgSql
|
||||||
DB_DATANAME=memos-db
|
DB_DATANAME=memos-db
|
||||||
DB_HOST=192.168.10.61
|
DB_HOST=192.168.10.61
|
||||||
DB_POST=5432
|
DB_POST=15432
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
DB_DRIVER=postgres
|
||||||
|
DB_USER=postgres
|
||||||
|
DB_PASSWORD=Kevin0412PgSql
|
||||||
|
DB_DATANAME=memos-db
|
||||||
|
DB_HOST=10.0.74.3
|
||||||
|
DB_POST=15432
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
DB_DRIVER=postgres
|
||||||
|
DB_USER=postgres
|
||||||
|
DB_PASSWORD=Kevin0412PgSql
|
||||||
|
DB_DATANAME=memos-db
|
||||||
|
DB_HOST=pgsql
|
||||||
|
DB_POST=15432
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# ============================================================
|
||||||
|
# Memos 部署 — 公共环境变量
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已在 .gitignore 中忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# # 数据库相关变量在 db-<env>.cnf 中独立配置(参考 db-184.cnf)
|
||||||
|
# docker compose -p memos --env-file ./env.cfg --env-file ./db-61.cnf -f ./prod.stack.yml up -d
|
||||||
|
|
||||||
|
# ---------- 镜像 ----------
|
||||||
|
# Memos 版本号
|
||||||
|
IMAGE_TAG_VER=0.29.1
|
||||||
|
# 完整镜像引用(私有仓库示例:hub.tp229.com:3500/neosmemo/memos:${IMAGE_TAG_VER})
|
||||||
|
IMAGE_TAG=neosmemo/memos:${IMAGE_TAG_VER}
|
||||||
|
PGSQL_IMAGE_TAG=postgres:18.4
|
||||||
|
|
||||||
|
# ---------- 数据卷 ----------
|
||||||
|
# 宿主机持久化目录,会挂载到容器 /var/opt/memos
|
||||||
|
# 部署前手动创建:mkdir -pv /data/volumes/memos/{data,pgsql_data}
|
||||||
|
Volumes_Path=/data/volumes/memos
|
||||||
+39
-9
@@ -1,18 +1,48 @@
|
|||||||
# run:: docker compose -p memos -f ./memos/local.stack.yml up -d
|
# run:: docker compose -p memos --env-file ./memos/env.cfg --env-file ./memos/db-local.cnf -f ./memos/local.stack.yml up -d
|
||||||
|
|
||||||
services:
|
services:
|
||||||
memos:
|
memos:
|
||||||
image: neosmemo/memos:0.20.0
|
image: ${IMAGE_TAG}
|
||||||
#command: '--driver mysql --dsn root:Kevin%0412%Mysql@tcp(10.10.13.233:3306)/memos-db'
|
|
||||||
volumes:
|
volumes:
|
||||||
- data:/var/opt/memos
|
- ${Volumes_Path}/data:/var/opt/memos
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- '8230:5230'
|
- "8230:5230"
|
||||||
container_name: memos
|
container_name: memos_local
|
||||||
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
- MEMOS_DRIVER=postgres
|
- MEMOS_DRIVER=${DB_DRIVER}
|
||||||
- MEMOS_DSN=postgresql://postgres:Kevin0412PgSql@192.168.100.184:5432/memos-db?sslmode=disable
|
- MEMOS_DSN=user=${DB_USER} password=${DB_PASSWORD} dbname=${DB_DATANAME} host=${DB_HOST} port=${DB_POST} sslmode=disable
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
pgsql:
|
||||||
|
image: ${PGSQL_IMAGE_TAG:-postgres:18.4}
|
||||||
|
container_name: memos_local_pgsql
|
||||||
|
restart: always
|
||||||
|
shm_size: 256mb
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=${DB_USER:-postgres}
|
||||||
|
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
||||||
|
- POSTGRES_DB=${DB_DATANAME:-memos-db}
|
||||||
|
- POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
volumes:
|
||||||
|
# Postgres 数据持久化(具名卷 pgsql_data)
|
||||||
|
- pgsql_data:/var/lib/postgresql/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- "${DB_POST:-15432}:5432"
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD-SHELL",
|
||||||
|
"pg_isready -U ${DB_USER:-postgres} -d ${DB_DATANAME:-memos-db}",
|
||||||
|
]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
data:
|
pgsql_data:
|
||||||
|
|||||||
+36
-6
@@ -1,7 +1,9 @@
|
|||||||
# path:: mkdir -pv /data/volumes/memos/data
|
# path:: mkdir -pv /data/volumes/memos/data
|
||||||
# run-61:: docker compose -p memos --env-file ./memos/env.cfg --env-file ./memos/db-61.cnf -f ./memos/prod.stack.yml up -d
|
# pull:: docker compose -p memos --env-file ./memos/env.cfg -f ./memos/prod.stack.yml pull
|
||||||
|
# run-61:: docker compose -p memos --env-file ./memos/env.cfg --env-file ./memos/db-61.cnf -f ./memos/prod.stack.yml up -d
|
||||||
# run-184:: docker compose -p memos --env-file ./memos/env.cfg --env-file ./memos/db-184.cnf -f ./memos/prod.stack.yml up -d
|
# run-184:: docker compose -p memos --env-file ./memos/env.cfg --env-file ./memos/db-184.cnf -f ./memos/prod.stack.yml up -d
|
||||||
# run-lkc:: docker compose -p memos --env-file ./memos/env.cfg --env-file ./memos/env-lkc.cnf -f ./memos/prod.stack.yml up -d
|
# run-lkc:: docker compose -p memos --env-file ./memos/env.cfg --env-file ./memos/db-lkc.cnf -f ./memos/prod.stack.yml up -d
|
||||||
|
# run-local:: docker compose -p memos --env-file ./memos/env.cfg --env-file ./memos/db-local.cnf -f ./memos/prod.stack.yml up -d
|
||||||
|
|
||||||
services:
|
services:
|
||||||
memos:
|
memos:
|
||||||
@@ -11,8 +13,8 @@ services:
|
|||||||
- /etc/timezone:/etc/timezone:ro
|
- /etc/timezone:/etc/timezone:ro
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- '5230:5230'
|
- "5230:5230"
|
||||||
container_name: memos
|
container_name: memos_app
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
- MEMOS_DRIVER=${DB_DRIVER}
|
- MEMOS_DRIVER=${DB_DRIVER}
|
||||||
@@ -21,5 +23,33 @@ services:
|
|||||||
#- MEMOS_DRIVER=mysql
|
#- MEMOS_DRIVER=mysql
|
||||||
#- MEMOS_DSN=root:password@tcp(localhost)/memos_prod
|
#- MEMOS_DSN=root:password@tcp(localhost)/memos_prod
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
#volumes:
|
|
||||||
# data:
|
pgsql:
|
||||||
|
image: ${PGSQL_IMAGE_TAG:-postgres:18.4}
|
||||||
|
container_name: memos_pgsql
|
||||||
|
restart: always
|
||||||
|
shm_size: 256mb
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=${DB_USER:-postgres}
|
||||||
|
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
||||||
|
- POSTGRES_DB=${DB_DATANAME:-memos-db}
|
||||||
|
- POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
volumes:
|
||||||
|
- ${Volumes_Path}/pgsql_data:/var/lib/postgresql/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- "${DB_POST:-15432}:5432"
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD-SHELL",
|
||||||
|
"pg_isready -U ${DB_USER:-postgres} -d ${DB_DATANAME:-memos-db}",
|
||||||
|
]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgsql_data:
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# ============================================================
|
||||||
|
# mynat 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p mynat --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG=hub.wesais.cn/cnphpbb/mynat:v250603
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/mynat
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# ============================================================
|
||||||
|
# n8n 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p n8n --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
IMAGE_TAG_LATEST=2.3.6
|
||||||
|
|
||||||
|
IMAGE_TAG_Pre=2.4.4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 数据库连接配置
|
||||||
|
|
||||||
|
POSTGRES_HOST=localhost
|
||||||
|
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
|
||||||
|
POSTGRES_DB=n8n
|
||||||
|
|
||||||
|
POSTGRES_USER=n8n
|
||||||
|
|
||||||
|
POSTGRES_PASSWORD=<your-strong-password>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# n8n基础配置
|
||||||
|
|
||||||
|
N8N_BASIC_AUTH_ACTIVE=true
|
||||||
|
|
||||||
|
N8N_BASIC_AUTH_USER=admin
|
||||||
|
|
||||||
|
N8N_BASIC_AUTH_PASSWORD=<your-strong-password>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 时区
|
||||||
|
|
||||||
|
GENERIC_TIMEZONE=Asia/Shanghai
|
||||||
|
|
||||||
|
TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Webhook配置
|
||||||
|
|
||||||
|
WEBHOOK_URL=http://localhost:5678
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 加密密钥
|
||||||
|
|
||||||
|
N8N_ENCRYPTION_KEY=<your-encryption-key>
|
||||||
@@ -49,9 +49,9 @@ services:
|
|||||||
- nightingale
|
- nightingale
|
||||||
command:
|
command:
|
||||||
- "--loggerTimezone=Asia/Shanghai"
|
- "--loggerTimezone=Asia/Shanghai"
|
||||||
|
|
||||||
nightingale:
|
nightingale:
|
||||||
image: flashcatcloud/nightingale:8.5.0
|
image: flashcatcloud/nightingale:9.0.0
|
||||||
container_name: nightingale
|
container_name: nightingale
|
||||||
hostname: nightingale
|
hostname: nightingale
|
||||||
restart: always
|
restart: always
|
||||||
@@ -100,4 +100,4 @@ services:
|
|||||||
# depends_on:
|
# depends_on:
|
||||||
# - nightingale
|
# - nightingale
|
||||||
# links:
|
# links:
|
||||||
# - nightingale:nightingale
|
# - nightingale:nightingale
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ networks:
|
|||||||
nightingale:
|
nightingale:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: "redis:8-alpine"
|
image: "redis:8-alpine"
|
||||||
container_name: redis
|
container_name: n9e_redis
|
||||||
hostname: redis
|
hostname: redis
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
@@ -18,7 +16,7 @@ services:
|
|||||||
- nightingale
|
- nightingale
|
||||||
|
|
||||||
nightingale:
|
nightingale:
|
||||||
image: flashcatcloud/nightingale:8.5.0
|
image: flashcatcloud/nightingale:9.0.0
|
||||||
container_name: nightingale
|
container_name: nightingale
|
||||||
hostname: nightingale
|
hostname: nightingale
|
||||||
restart: always
|
restart: always
|
||||||
@@ -38,4 +36,4 @@ services:
|
|||||||
links:
|
links:
|
||||||
- redis:redis
|
- redis:redis
|
||||||
command: >
|
command: >
|
||||||
sh -c "/app/n9e"
|
sh -c "/app/n9e"
|
||||||
|
|||||||
+1
-1
@@ -13,4 +13,4 @@ compose-pgsql 目录下是 postgresql 版本
|
|||||||
### 注意事项
|
### 注意事项
|
||||||
- 请根据实际情况选择合适的版本进行安装部署。
|
- 请根据实际情况选择合适的版本进行安装部署。
|
||||||
- 请先复制 compose-* 目录下的文件到目标目录。并修改其中的环境变量和配置文件。
|
- 请先复制 compose-* 目录下的文件到目标目录。并修改其中的环境变量和配置文件。
|
||||||
- 防止使用默认值导致的安全问题。
|
- 防止使用默认值导致的安全问题。
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# ============================================================
|
||||||
|
# netdata 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p netdata --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG=netdata/netdata:edge-0
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/netdata
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# ============================================================
|
||||||
|
# nginxpulse 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p nginxpulse --env-file ./nginxpulse/env.cfg -f ./nginxpulse/stack.yml up -d
|
||||||
|
# mkdir -pv /data/volumes/{postgres,nginxpulse}
|
||||||
|
# mkdir -pv /data/volumes/nginxpulse/{logs,nginxpulse_data,configs}
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# --- PostgreSQL ---
|
||||||
|
PG_IMAGE_TAG_VER=18.4
|
||||||
|
PG_IMAGE_TAG_V18=postgres:${PG_IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
POSTGRES_PASSWORD=<your-password>
|
||||||
|
POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
|
|
||||||
|
# --- Nginxpulse ---
|
||||||
|
NP_IMAGE_TAG_VER=v1.6.24
|
||||||
|
NP_IMAGE_TAG=magiccoders/nginxpulse:${NP_IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
# --- 卷路径 ---
|
||||||
|
Volumes_Path=/data/volumes
|
||||||
|
PG_Volumes_Path=${Volumes_Path}/postgres
|
||||||
|
NP_Volumes_Path=${Volumes_Path}/nginxpulse
|
||||||
Executable
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
VOLUMES_PATH="${1:-/data/volumes}"
|
||||||
|
|
||||||
|
mkdir -pv \
|
||||||
|
"${VOLUMES_PATH}/postgres/data" \
|
||||||
|
"${VOLUMES_PATH}/nginxpulse/logs" \
|
||||||
|
"${VOLUMES_PATH}/nginxpulse/nginxpulse_data" \
|
||||||
|
"${VOLUMES_PATH}/nginxpulse/configs"
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: ${PG_IMAGE_TAG_V18}
|
||||||
|
container_name: prod-postgres
|
||||||
|
shm_size: 256mb
|
||||||
|
environment:
|
||||||
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||||
|
- POSTGRES_HOST_AUTH_METHOD=${POSTGRES_HOST_AUTH_METHOD}
|
||||||
|
- POSTGRES_INITDB_ARGS=--auth-host=${POSTGRES_HOST_AUTH_METHOD}
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
volumes:
|
||||||
|
- ${PG_Volumes_Path}/data:/var/lib/postgresql
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
restart: unless-stopped
|
||||||
|
nginxpulse:
|
||||||
|
image: ${NP_IMAGE_TAG}
|
||||||
|
container_name: local_nginxpulse
|
||||||
|
ports:
|
||||||
|
- "8088:8088"
|
||||||
|
- "8089:8089"
|
||||||
|
volumes:
|
||||||
|
- ${NP_Volumes_Path}/logs:/share/logs
|
||||||
|
- ${NP_Volumes_Path}/nginxpulse_data:/app/var/nginxpulse_data
|
||||||
|
- ${NP_Volumes_Path}/configs:/app/configs
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
stop_grace_period: 90s
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# ============================================================
|
||||||
|
# ntfy 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p ntfy --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
IMAGE_TAG_VER=v2.24
|
||||||
|
|
||||||
|
IMAGE_TAG=binwiederhier/ntfy:${IMAGE_TAG_VER}
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/ntfy
|
||||||
|
|
||||||
|
NTFY_BASE_URL=http://ntfy:80
|
||||||
|
|
||||||
|
# Web推送密钥对(自行生成):
|
||||||
|
# docker run --rm binwiederhier/ntfy ntfy web push generate > keys.txt
|
||||||
|
# 或:docker exec ntfy ntfy web push generate
|
||||||
|
# 然后将 public key 和 private key 分别填入下方
|
||||||
|
NTFY_WEB_PUSH_PUBLIC_KEY=
|
||||||
|
NTFY_WEB_PUSH_PRIVATE_KEY=
|
||||||
|
|
||||||
|
# Web推送关联的邮件地址(用于通知等场景)
|
||||||
|
NTFY_WEB_PUSH_EMAIL_ADDRESS=
|
||||||
+16
-17
@@ -9,26 +9,25 @@ services:
|
|||||||
container_name: ntfy
|
container_name: ntfy
|
||||||
#tty: true
|
#tty: true
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
command:
|
command: serve
|
||||||
serve
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- '5480:80'
|
- "5480:80"
|
||||||
environment:
|
environment:
|
||||||
- TZ=Asia/Shanghai # 时区设置为上海时区
|
- TZ=Asia/Shanghai # 时区设置为上海时区
|
||||||
- NTFY_BASE_URL=<http://ntfy:80> # ntfy服务的基础访问URL(协议+主机+端口)
|
- NTFY_BASE_URL=${NTFY_BASE_URL} # ntfy服务的基础访问URL(协议+主机+端口)
|
||||||
- NTFY_CACHE_FILE=/var/lib/ntfy/cache.db # 缓存数据的存储文件路径
|
- NTFY_CACHE_FILE=/var/lib/ntfy/cache.db # 缓存数据的存储文件路径
|
||||||
- NTFY_AUTH_FILE=/var/lib/ntfy/auth.db # 授权信息(如用户认证数据)的存储文件路径
|
- NTFY_AUTH_FILE=/var/lib/ntfy/auth.db # 授权信息(如用户认证数据)的存储文件路径
|
||||||
- NTFY_AUTH_DEFAULT_ACCESS=deny-all # 默认访问权限:禁止所有未授权访问
|
- NTFY_AUTH_DEFAULT_ACCESS=deny-all # 默认访问权限:禁止所有未授权访问
|
||||||
- NTFY_BEHIND_PROXY=true # 标识ntfy服务运行在代理服务器后方(如Nginx等)
|
- NTFY_BEHIND_PROXY=true # 标识ntfy服务运行在代理服务器后方(如Nginx等)
|
||||||
- NTFY_ATTACHMENT_CACHE_DIR=/var/lib/ntfy/attachments # 附件资源的缓存存储目录
|
- NTFY_ATTACHMENT_CACHE_DIR=/var/lib/ntfy/attachments # 附件资源的缓存存储目录
|
||||||
- NTFY_ENABLE_LOGIN=true # 启用登录功能,允许用户通过账号密码授权访问
|
- NTFY_ENABLE_LOGIN=true # 启用登录功能,允许用户通过账号密码授权访问
|
||||||
- NTFY_WEB_PUSH_PUBLIC_KEY= <public_key> # Web推送功能的公钥(用于消息加密)
|
- NTFY_WEB_PUSH_PUBLIC_KEY=${NTFY_WEB_PUSH_PUBLIC_KEY} # Web推送功能的公钥(用于消息加密)
|
||||||
- NTFY_WEB_PUSH_PRIVATE_KEY= <private_key> # Web推送功能的私钥(与公钥配对,用于解密/签名)
|
- NTFY_WEB_PUSH_PRIVATE_KEY=${NTFY_WEB_PUSH_PRIVATE_KEY} # Web推送功能的私钥(与公钥配对,用于解密/签名)
|
||||||
- NTFY_WEB_PUSH_FILE=/var/lib/ntfy/webpush.db # Web推送相关的数据存储文件路径
|
- NTFY_WEB_PUSH_FILE=/var/lib/ntfy/webpush.db # Web推送相关的数据存储文件路径
|
||||||
- NTFY_WEB_PUSH_EMAIL_ADDRESS= <email> # Web推送关联的邮件地址(用于通知等场景)
|
- NTFY_WEB_PUSH_EMAIL_ADDRESS=${NTFY_WEB_PUSH_EMAIL_ADDRESS} # Web推送关联的邮件地址(用于通知等场景)
|
||||||
- NTFY_ENABLE_SIGNUP=false # 禁用用户注册功能,阻止新用户自主创建账号
|
- NTFY_ENABLE_SIGNUP=false # 禁用用户注册功能,阻止新用户自主创建账号
|
||||||
- NTFY_ENABLE_METRICS=true # 启用指标收集功能,用于监控和分析服务运行状态
|
- NTFY_ENABLE_METRICS=true # 启用指标收集功能,用于监控和分析服务运行状态
|
||||||
volumes:
|
volumes:
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
- /etc/timezone:/etc/timezone:ro
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# IMAGE_LATEST=portainer/portainer-ce:2.19.4
|
||||||
|
# IMAGE_LATEST=portainer/portainer-ce:latest
|
||||||
|
IMAGE_TAG_LTS=2.39.4
|
||||||
|
IMAGE_TAG_STS=2.43.0
|
||||||
|
IMAGE_TAG=portainer/portainer-ce:${IMAGE_TAG_LTS}
|
||||||
|
AGENT_TAG=portainer/agent:${IMAGE_TAG_LTS}
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
# Run:: docker compose -p portainer-ce --env-file ./portainer-ce/env.cfg -f ./portainer-ce/portainer-ce.yaml up -d
|
# Run:: docker compose -p portainer-ce --env-file ./portainer-ce/env.cfg -f ./portainer-ce/portainer-ce.yaml up -d
|
||||||
services:
|
services:
|
||||||
|
|
||||||
portainer:
|
portainer:
|
||||||
image: ${IMAGE_TAG}
|
image: ${IMAGE_TAG}
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "9000:9000"
|
- "9000:9000"
|
||||||
- "9443:9443"
|
# - "9443:9443"
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
- data:/data
|
- data:/data
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
data:
|
data:
|
||||||
|
|||||||
+31
-30
@@ -1,38 +1,39 @@
|
|||||||
## portainer-ce
|
## portainer-ce
|
||||||
|
|
||||||
重点说明: 如果 docker 版本 <= 29.0.0
|
**版本说明:**
|
||||||
|
|
||||||
现在使用的LTS版本是2.33.4 和 STS版本是2.35.0,都不支持最新的 docker 版本 >= 29.0.0
|
| 版本类型 | 当前版本 | Docker >= 29.0.0 支持 |
|
||||||
|
|---------|----------|----------------------|
|
||||||
|
| LTS | 2.39.4 | ✅ 支持 |
|
||||||
|
| STS | 2.43.0 | ✅ 支持 |
|
||||||
|
|
||||||
**解决的方法:**
|
### 历史记录
|
||||||
|
|
||||||
##### 方案1
|
- **2025-11-30 之前**:LTS 2.33.4 和 STS 2.35.0 不支持 Docker >= 29.0.0,需要通过以下方式解决:
|
||||||
在 docker 的 service 文件 中添加如下:
|
|
||||||
```
|
|
||||||
## 找到 docker.service 文件 `systemctl status docker` 会显示 docker.service 文件的完整路径
|
|
||||||
### 在 [Service] 段内添加
|
|
||||||
[Service]
|
|
||||||
Environment=DOCKER_MIN_API_VERSION=1.24
|
|
||||||
### 保持文件
|
|
||||||
### 重启 docker 服务
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl restart docker
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 方案2
|
##### 方案1(已废弃)
|
||||||
也可以在 `/etc/docker/daemon.json` 中添加如下:
|
在 docker 的 service 文件中添加:
|
||||||
```
|
```
|
||||||
{
|
## 找到 docker.service 文件 `systemctl status docker` 会显示 docker.service 文件的完整路径
|
||||||
"min-api-version": "1.24"
|
### 在 [Service] 段内添加
|
||||||
}
|
[Service]
|
||||||
```
|
Environment=DOCKER_MIN_API_VERSION=1.24
|
||||||
最后重启 docker 服务
|
### 保持文件
|
||||||
|
### 重启 docker 服务
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl restart docker
|
||||||
|
```
|
||||||
|
|
||||||
```
|
##### 方案2(已废弃)
|
||||||
systemctl restart docker
|
在 `/etc/docker/daemon.json` 中添加:
|
||||||
```
|
```
|
||||||
|
{
|
||||||
|
"min-api-version": "1.24"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
最后重启 docker 服务:
|
||||||
|
```
|
||||||
|
systemctl restart docker
|
||||||
|
```
|
||||||
|
|
||||||
### by 2025-11-30
|
- **2025-11-30 起**:LTS 2.33.5 和 STS 2.36.0 发布,**原生支持** Docker >= 29.0.0,**无需任何配置**。
|
||||||
|
|
||||||
LTS版本是2.33.5 和 STS版本是2.36.0,都支持最新的 docker 版本 >= 29.0.0
|
|
||||||
无需添加任何配置
|
|
||||||
|
|||||||
@@ -7,3 +7,133 @@
|
|||||||
> 1. 该脚本只是一个简单的示例,不保证任何的稳定性。
|
> 1. 该脚本只是一个简单的示例,不保证任何的稳定性。
|
||||||
> 2. 请根据自己的需求进行修改。
|
> 2. 请根据自己的需求进行修改。
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
项目包含多个可独立部署的服务栈,每个服务栈位于单独的目录中,包含以下核心文件:
|
||||||
|
- `stack.yml` / `compose.yml` - Docker Compose 配置文件
|
||||||
|
- `env.cfg` - 环境变量配置文件(包含敏感信息,已 gitignore)
|
||||||
|
- `env.cfg.example` - 环境变量配置模板(不含敏感信息)
|
||||||
|
- `readme.md` - 服务说明文档(可选)
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
### Gitea 部署实践事例
|
||||||
|
|
||||||
|
**场景**:要部署 Gitea 服务,但希望保持项目目录的原始配置不变,同时在独立的目录中进行定制化部署。
|
||||||
|
|
||||||
|
**1. 创建独立部署目录**:
|
||||||
|
```bash
|
||||||
|
# 假设当前在 deploy.stack 项目根目录
|
||||||
|
# 创建独立的部署目录
|
||||||
|
mkdir -p ~/mydeploy
|
||||||
|
cd ~/mydeploy
|
||||||
|
|
||||||
|
# 复制项目中的 Gitea 配置(相对路径或绝对路径)
|
||||||
|
cp -r ../deploy.stack/gitea .
|
||||||
|
# 或者使用绝对路径
|
||||||
|
# cp -r /path/to/your/deploy.stack/gitea .
|
||||||
|
|
||||||
|
# 进入 Gitea 目录
|
||||||
|
cd gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. 准备环境变量**:
|
||||||
|
```bash
|
||||||
|
# 复制环境变量模板
|
||||||
|
cp env.cfg.example env.cfg
|
||||||
|
|
||||||
|
# 编辑环境变量(根据实际需求修改)
|
||||||
|
vim env.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. 修改配置(在 mydeploy 目录中)**:
|
||||||
|
|
||||||
|
**修改端口映射**(Gitea 默认使用 3000 端口,可能与 Grafana 冲突):
|
||||||
|
```yaml
|
||||||
|
# 在 lky-prod.yml 或 rpi-prod.yml 中添加端口映射
|
||||||
|
ports:
|
||||||
|
- "3001:3000" # 将容器内 3000 端口映射到宿主机 3001 端口
|
||||||
|
```
|
||||||
|
|
||||||
|
**调整数据卷路径**(根据实际存储位置):
|
||||||
|
```bash
|
||||||
|
# 在 env.cfg 中修改 Volumes_Path
|
||||||
|
Volumes_Path=/data/volumes/gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
**更新镜像版本**:
|
||||||
|
```bash
|
||||||
|
# 在 env.cfg 中修改镜像版本
|
||||||
|
IMAGE_TAG_VER=1.25.2
|
||||||
|
IMAGE_TAG=gitea/gitea:${IMAGE_TAG_VER}-rootless
|
||||||
|
```
|
||||||
|
|
||||||
|
**选择环境配置文件**:
|
||||||
|
- `lky-prod.yml` - 用于生产环境(Linux 服务器)
|
||||||
|
- `rpi-prod.yml` - 用于树莓派环境
|
||||||
|
- 根据实际环境选择合适的 compose 文件
|
||||||
|
|
||||||
|
**4. 创建数据目录**:
|
||||||
|
```bash
|
||||||
|
# 根据 env.cfg 中的 Volumes_Path 创建目录
|
||||||
|
mkdir -pv /data/volumes/gitea/{data,config,logs}
|
||||||
|
|
||||||
|
# 设置正确的权限(Gitea 使用 UID 1000)
|
||||||
|
chown -R 1000:1000 /data/volumes/gitea/
|
||||||
|
```
|
||||||
|
|
||||||
|
**5. 部署服务**:
|
||||||
|
```bash
|
||||||
|
# 拉取镜像(根据选择的配置文件)
|
||||||
|
docker compose -p gitea --env-file ./env.cfg -f ./lky-prod.yml pull
|
||||||
|
# 或使用 rpi-prod.yml
|
||||||
|
# docker compose -p gitea --env-file ./env.cfg -f ./rpi-prod.yml pull
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
docker compose -p gitea --env-file ./env.cfg -f ./lky-prod.yml up -d
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker compose -p gitea --env-file ./env.cfg -f ./lky-prod.yml logs -f
|
||||||
|
|
||||||
|
# 查看服务状态
|
||||||
|
docker compose -p gitea --env-file ./env.cfg -f ./lky-prod.yml ps
|
||||||
|
|
||||||
|
# 停止服务
|
||||||
|
docker compose -p gitea --env-file ./env.cfg -f ./lky-prod.yml down
|
||||||
|
```
|
||||||
|
|
||||||
|
**6. 优势**:
|
||||||
|
- **配置隔离**:在 `mydeploy` 目录中的修改不会影响原始项目配置
|
||||||
|
- **版本管理**:可以针对不同环境维护不同的配置版本
|
||||||
|
- **快速回滚**:如需恢复原始配置,只需删除 `mydeploy` 目录并重新部署
|
||||||
|
- **测试验证**:可以在 `mydeploy` 中测试新配置,确认无误后再应用到生产环境
|
||||||
|
|
||||||
|
**7. 注意事项**:
|
||||||
|
- **配置兼容性**:确保 `mydeploy` 目录中的配置文件与原始项目保持兼容,特别是 compose 文件版本
|
||||||
|
- **定期同步**:关注原始项目的更新(安全补丁、新功能等),适时同步到 `mydeploy` 目录
|
||||||
|
- **配置备份**:定期备份 `mydeploy` 目录中的自定义配置
|
||||||
|
- **敏感信息安全**:`env.cfg` 包含密码、密钥等敏感信息,确保文件权限为 600
|
||||||
|
```bash
|
||||||
|
chmod 600 env.cfg
|
||||||
|
```
|
||||||
|
- **版本控制**:建议将 `mydeploy` 目录纳入版本控制(排除 `env.cfg`)
|
||||||
|
- **多环境管理**:可以为不同环境创建不同的 `mydeploy` 目录,如 `mydeploy-prod`、`mydeploy-dev`
|
||||||
|
|
||||||
|
**8. 通用模式**:
|
||||||
|
这种 "mydeploy" 模式不仅适用于 Gitea,也适用于项目中的其他服务:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 部署 Grafana
|
||||||
|
cp -r ../deploy.stack/grafana ~/mydeploy/grafana
|
||||||
|
|
||||||
|
# 部署 Memos
|
||||||
|
cp -r ../deploy.stack/memos ~/mydeploy/memos
|
||||||
|
|
||||||
|
# 部署 Portainer
|
||||||
|
cp -r ../deploy.stack/portainer-ce ~/mydeploy/portainer-ce
|
||||||
|
|
||||||
|
# 部署 Traefik
|
||||||
|
cp -r ../deploy.stack/traefik ~/mydeploy/traefik
|
||||||
|
```
|
||||||
|
|
||||||
|
每个服务都可以在独立的目录中进行定制化配置和测试,实现真正的配置隔离和环境管理。
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# ============================================================
|
||||||
|
# rustfs 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p rustfs --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
# ⚠️ 敏感值(必填,env.cfg 不提交)
|
||||||
|
# ============================================================
|
||||||
|
IMAGE_TAG=rustfs/rustfs:alpha # 最新版本
|
||||||
|
|
||||||
|
IMAGE_TAG_LTS=rustfs/rustfs:latest # 长期支持版本
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/rustfs # 数据卷路径
|
||||||
|
|
||||||
|
RUSTFS_SERVER_DOMAINS=rustfs.example.com # 服务器域名
|
||||||
|
|
||||||
|
RUSTFS_CONSOLE_ENABLE=true # 是否启用控制台
|
||||||
|
|
||||||
|
RUSTFS_SECRET_KEY=<your-secret> # 密钥
|
||||||
|
|
||||||
|
RUSTFS_ACCESS_KEY=<your-access-key> # 访问密钥
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# ============================================================
|
||||||
|
# searxng 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p searxng --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
SearXNG_TAG=searxng/searxng:latest
|
||||||
|
|
||||||
|
Redis_TAG=valkey/valkey:9.0.0-alpine
|
||||||
|
|
||||||
|
Valkey_TAG=valkey/valkey:9.0.0
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/searxng
|
||||||
+2
-3
@@ -3,7 +3,6 @@
|
|||||||
# Run:: docker compose --env-file ./searxng/env.cfg -f ./searxng/stack.yml up -d
|
# Run:: docker compose --env-file ./searxng/env.cfg -f ./searxng/stack.yml up -d
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
valkey:
|
valkey:
|
||||||
image: ${Valkey_TAG}
|
image: ${Valkey_TAG}
|
||||||
container_name: redis
|
container_name: redis
|
||||||
@@ -12,7 +11,7 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- searxng
|
- searxng
|
||||||
volumes:
|
volumes:
|
||||||
- ${Volumes_Path}/redis-data:/data
|
- ${Volumes_Path}/redis-data:/data
|
||||||
|
|
||||||
searxng:
|
searxng:
|
||||||
image: ${SearXNG_TAG}
|
image: ${SearXNG_TAG}
|
||||||
@@ -32,4 +31,4 @@ services:
|
|||||||
- ${Volumes_Path}/searxng-data:/var/cache/searxng:rw
|
- ${Volumes_Path}/searxng-data:/var/cache/searxng:rw
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
searxng:
|
searxng:
|
||||||
|
|||||||
@@ -0,0 +1,269 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ============================================================
|
||||||
|
# File: proxy.sh
|
||||||
|
# Description: 通用代理管理脚本
|
||||||
|
# Usage:
|
||||||
|
# source proxy.sh # 加载默认配置
|
||||||
|
# proxy on # 开启代理
|
||||||
|
# proxy off # 关闭代理
|
||||||
|
# proxy status # 查看代理状态
|
||||||
|
# proxy test # 测试代理连通性
|
||||||
|
# proxy set <host> <port> # 临时设置代理地址
|
||||||
|
#
|
||||||
|
# 也可直接执行: bash proxy.sh [on|off|status|test|set ...]
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# -------------------- 默认配置 --------------------
|
||||||
|
PROXY_HOST="${PROXY_HOST:-127.0.0.1}"
|
||||||
|
PROXY_PORT="${PROXY_PORT:-7890}"
|
||||||
|
PROXY_TYPE="${PROXY_TYPE:-http}" # http 或 socks5
|
||||||
|
NO_PROXY_LIST="localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
|
||||||
|
|
||||||
|
# -------------------- 构建代理 URL --------------------
|
||||||
|
function _build_proxy_url() {
|
||||||
|
local type="${PROXY_TYPE:-http}"
|
||||||
|
local host="${PROXY_HOST:-127.0.0.1}"
|
||||||
|
local port="${PROXY_PORT:-7890}"
|
||||||
|
|
||||||
|
case "$type" in
|
||||||
|
http|HTTP) echo "http://${host}:${port}" ;;
|
||||||
|
socks5|socks) echo "socks5://${host}:${port}" ;;
|
||||||
|
socks4) echo "socks4://${host}:${port}" ;;
|
||||||
|
*) echo "${type}://${host}:${port}" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------- 开启代理 --------------------
|
||||||
|
function proxy_on() {
|
||||||
|
local url
|
||||||
|
url="$(_build_proxy_url)"
|
||||||
|
|
||||||
|
# --- 环境变量 ---
|
||||||
|
export http_proxy="$url"
|
||||||
|
export HTTP_PROXY="$url"
|
||||||
|
export https_proxy="$url"
|
||||||
|
export HTTPS_PROXY="$url"
|
||||||
|
export all_proxy="$url"
|
||||||
|
export ALL_PROXY="$url"
|
||||||
|
export no_proxy="$NO_PROXY_LIST"
|
||||||
|
export NO_PROXY="$NO_PROXY_LIST"
|
||||||
|
export ftp_proxy="$url"
|
||||||
|
export FTP_PROXY="$url"
|
||||||
|
export rsync_proxy="$url"
|
||||||
|
|
||||||
|
# --- Git ---
|
||||||
|
git config --global http.proxy "$url" 2>/dev/null
|
||||||
|
git config --global https.proxy "$url" 2>/dev/null
|
||||||
|
|
||||||
|
# --- NPM ---
|
||||||
|
npm config set proxy "$url" 2>/dev/null
|
||||||
|
npm config set https-proxy "$url" 2>/dev/null
|
||||||
|
|
||||||
|
# --- Yarn ---
|
||||||
|
yarn config set proxy "$url" 2>/dev/null
|
||||||
|
yarn config set https-proxy "$url" 2>/dev/null
|
||||||
|
|
||||||
|
# --- Docker(需要 sudo 权限写入配置目录)---
|
||||||
|
if [ -d /etc/systemd/system/docker.service.d ]; then
|
||||||
|
local docker_conf="/etc/systemd/system/docker.service.d/http-proxy.conf"
|
||||||
|
sudo bash -c "cat > '$docker_conf' <<EOF
|
||||||
|
[Service]
|
||||||
|
Environment=\"HTTP_PROXY=$url\"
|
||||||
|
Environment=\"HTTPS_PROXY=$url\"
|
||||||
|
Environment=\"NO_PROXY=$NO_PROXY_LIST\"
|
||||||
|
EOF"
|
||||||
|
sudo systemctl daemon-reload 2>/dev/null
|
||||||
|
sudo systemctl restart docker 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\033[32m[✓] 代理已开启 → \033[1m${url}\033[0m"
|
||||||
|
echo -e "\033[32m NO_PROXY → \033[1m${NO_PROXY_LIST}\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------- 关闭代理 --------------------
|
||||||
|
function proxy_off() {
|
||||||
|
# --- 环境变量 ---
|
||||||
|
unset http_proxy HTTP_PROXY
|
||||||
|
unset https_proxy HTTPS_PROXY
|
||||||
|
unset all_proxy ALL_PROXY
|
||||||
|
unset no_proxy NO_PROXY
|
||||||
|
unset ftp_proxy FTP_PROXY
|
||||||
|
unset rsync_proxy
|
||||||
|
|
||||||
|
# --- Git ---
|
||||||
|
git config --global --unset http.proxy 2>/dev/null
|
||||||
|
git config --global --unset https.proxy 2>/dev/null
|
||||||
|
|
||||||
|
# --- NPM ---
|
||||||
|
npm config delete proxy 2>/dev/null
|
||||||
|
npm config delete https-proxy 2>/dev/null
|
||||||
|
|
||||||
|
# --- Yarn ---
|
||||||
|
yarn config delete proxy 2>/dev/null
|
||||||
|
yarn config delete https-proxy 2>/dev/null
|
||||||
|
|
||||||
|
# --- Docker ---
|
||||||
|
local docker_conf="/etc/systemd/system/docker.service.d/http-proxy.conf"
|
||||||
|
if [ -f "$docker_conf" ]; then
|
||||||
|
sudo rm -f "$docker_conf"
|
||||||
|
sudo systemctl daemon-reload 2>/dev/null
|
||||||
|
sudo systemctl restart docker 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\033[31m[✓] 代理已关闭\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------- 查看代理状态 --------------------
|
||||||
|
function proxy_status() {
|
||||||
|
echo -e "\n\033[1m========== 代理状态 ==========\033[0m"
|
||||||
|
|
||||||
|
# 环境变量
|
||||||
|
echo -e "\n\033[1m[环境变量]\033[0m"
|
||||||
|
local env_vars=("http_proxy" "https_proxy" "all_proxy" "no_proxy" "ftp_proxy")
|
||||||
|
for var in "${env_vars[@]}"; do
|
||||||
|
local val="${!var}"
|
||||||
|
if [ -n "$val" ]; then
|
||||||
|
printf " \033[32m%-14s → %s\033[0m\n" "$var" "$val"
|
||||||
|
else
|
||||||
|
printf " \033[90m%-14s → (未设置)\033[0m\n" "$var"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Git 配置
|
||||||
|
echo -e "\n\033[1m[Git 配置]\033[0m"
|
||||||
|
local git_http git_https
|
||||||
|
git_http=$(git config --global --get http.proxy 2>/dev/null)
|
||||||
|
git_https=$(git config --global --get https.proxy 2>/dev/null)
|
||||||
|
if [ -n "$git_http" ] || [ -n "$git_https" ]; then
|
||||||
|
[ -n "$git_http" ] && printf " \033[32mhttp.proxy → %s\033[0m\n" "$git_http"
|
||||||
|
[ -n "$git_https" ] && printf " \033[32mhttps.proxy → %s\033[0m\n" "$git_https"
|
||||||
|
else
|
||||||
|
printf " \033[90m(未配置)\033[0m\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# NPM 配置
|
||||||
|
if command -v npm &>/dev/null; then
|
||||||
|
echo -e "\n\033[1m[NPM 配置]\033[0m"
|
||||||
|
local npm_proxy npm_https_proxy
|
||||||
|
npm_proxy=$(npm config get proxy 2>/dev/null)
|
||||||
|
npm_https_proxy=$(npm config get https-proxy 2>/dev/null)
|
||||||
|
if [ "$npm_proxy" != "null" ] && [ -n "$npm_proxy" ]; then
|
||||||
|
printf " \033[32mproxy → %s\033[0m\n" "$npm_proxy"
|
||||||
|
else
|
||||||
|
printf " \033[90mproxy → (未设置)\033[0m\n"
|
||||||
|
fi
|
||||||
|
if [ "$npm_https_proxy" != "null" ] && [ -n "$npm_https_proxy" ]; then
|
||||||
|
printf " \033[32mhttps-proxy → %s\033[0m\n" "$npm_https_proxy"
|
||||||
|
else
|
||||||
|
printf " \033[90mhttps-proxy → (未设置)\033[0m\n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------- 测试代理连通性 --------------------
|
||||||
|
function proxy_test() {
|
||||||
|
local url
|
||||||
|
url="$(_build_proxy_url)"
|
||||||
|
|
||||||
|
echo -e "\033[1m[测试代理] ${url}\033[0m\n"
|
||||||
|
|
||||||
|
# 测试 Google (需要代理)
|
||||||
|
echo -n " Google (proxy) → "
|
||||||
|
if curl -s -o /dev/null -w "%{http_code}" --max-time 5 --proxy "$url" https://www.google.com 2>/dev/null | grep -q "200\|301\|302"; then
|
||||||
|
echo -e "\033[32m✓ OK\033[0m"
|
||||||
|
else
|
||||||
|
echo -e "\033[31m✗ FAIL\033[0m"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 测试 GitHub (需要代理)
|
||||||
|
echo -n " GitHub (proxy) → "
|
||||||
|
if curl -s -o /dev/null -w "%{http_code}" --max-time 5 --proxy "$url" https://github.com 2>/dev/null | grep -q "200\|301\|302"; then
|
||||||
|
echo -e "\033[32m✓ OK\033[0m"
|
||||||
|
else
|
||||||
|
echo -e "\033[31m✗ FAIL\033[0m"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 测试本地直连
|
||||||
|
echo -n " Local (no proxy) → "
|
||||||
|
if curl -s -o /dev/null -w "%{http_code}" --max-time 3 --noproxy '*' https://www.baidu.com 2>/dev/null | grep -q "200\|301\|302"; then
|
||||||
|
echo -e "\033[32m✓ OK\033[0m"
|
||||||
|
else
|
||||||
|
echo -e "\033[31m✗ FAIL\033[0m"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------- 临时设置代理地址 --------------------
|
||||||
|
function proxy_set() {
|
||||||
|
if [ $# -lt 2 ]; then
|
||||||
|
echo -e "\033[33m用法: proxy set <host> <port> [http|socks5]\033[0m"
|
||||||
|
echo -e "\033[33m示例: proxy set 192.168.1.100 1080 socks5\033[0m"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
PROXY_HOST="$1"
|
||||||
|
PROXY_PORT="$2"
|
||||||
|
if [ -n "$3" ]; then
|
||||||
|
PROXY_TYPE="$3"
|
||||||
|
fi
|
||||||
|
echo -e "\033[32m[✓] 代理地址已设置为 ${PROXY_TYPE}://${PROXY_HOST}:${PROXY_PORT}\033[0m"
|
||||||
|
echo -e "\033[32m 执行 'proxy on' 启用新的代理地址\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------- 总入口函数 --------------------
|
||||||
|
function proxy() {
|
||||||
|
case "$1" in
|
||||||
|
on) proxy_on ;;
|
||||||
|
off) proxy_off ;;
|
||||||
|
status) proxy_status ;;
|
||||||
|
test) proxy_test ;;
|
||||||
|
set) shift; proxy_set "$@" ;;
|
||||||
|
toggle)
|
||||||
|
if [ -n "$http_proxy" ]; then
|
||||||
|
proxy_off
|
||||||
|
else
|
||||||
|
proxy_on
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
help|*)
|
||||||
|
echo -e "
|
||||||
|
\033[1m========== proxy.sh — 通用代理管理 ==========\033[0m
|
||||||
|
|
||||||
|
\033[1m用法:\033[0m
|
||||||
|
source proxy.sh # 加载脚本(必须先 source 才能用 proxy 命令)
|
||||||
|
|
||||||
|
proxy on # 开启代理(环境变量 + git + npm + docker)
|
||||||
|
proxy off # 关闭代理(清除所有配置)
|
||||||
|
proxy status # 查看当前代理状态
|
||||||
|
proxy test # 测试代理连通性
|
||||||
|
proxy toggle # 切换代理开/关
|
||||||
|
proxy set <h> <p> [type] # 设置代理地址
|
||||||
|
proxy help # 显示帮助
|
||||||
|
|
||||||
|
\033[1m默认配置(可通过环境变量覆盖):\033[0m
|
||||||
|
PROXY_HOST = ${PROXY_HOST}
|
||||||
|
PROXY_PORT = ${PROXY_PORT}
|
||||||
|
PROXY_TYPE = ${PROXY_TYPE} (http | socks5 | socks4)
|
||||||
|
|
||||||
|
\033[1m自定义示例:\033[0m
|
||||||
|
PROXY_HOST=10.0.0.5 PROXY_PORT=1080 PROXY_TYPE=socks5 source proxy.sh
|
||||||
|
proxy set 10.0.0.5 1080 socks5 # 临时修改
|
||||||
|
"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------- 执行入口 --------------------
|
||||||
|
# 如果被直接执行(非 source),解析命令行参数
|
||||||
|
if [ "${BASH_SOURCE[0]:-$0}" = "$0" ]; then
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
proxy "$@"
|
||||||
|
else
|
||||||
|
proxy help
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# source 方式加载,显示提示
|
||||||
|
echo -e "\033[36m[proxy.sh] 已加载。使用 'proxy help' 查看用法。\033[0m"
|
||||||
|
fi
|
||||||
+353
@@ -0,0 +1,353 @@
|
|||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
通用代理管理脚本 (PowerShell 版)
|
||||||
|
.DESCRIPTION
|
||||||
|
source/加载后使用 proxy 命令管理代理开/关/状态/测试
|
||||||
|
.NOTES
|
||||||
|
File: proxy.ps1
|
||||||
|
用法:
|
||||||
|
. .\proxy.ps1 # 加载脚本
|
||||||
|
proxy on # 开启代理
|
||||||
|
proxy off # 关闭代理
|
||||||
|
proxy status # 查看代理状态
|
||||||
|
proxy test # 测试代理连通性
|
||||||
|
proxy set <host> <port> [type] # 临时设置代理地址
|
||||||
|
proxy toggle # 切换开/关
|
||||||
|
proxy help # 显示帮助
|
||||||
|
#>
|
||||||
|
|
||||||
|
# -------------------- 默认配置 --------------------
|
||||||
|
if (-not $env:_PROXY_HOST) { $env:_PROXY_HOST = "127.0.0.1" }
|
||||||
|
if (-not $env:_PROXY_PORT) { $env:_PROXY_PORT = "7890" }
|
||||||
|
if (-not $env:_PROXY_TYPE) { $env:_PROXY_TYPE = "http" } # http | socks5 | socks4
|
||||||
|
|
||||||
|
$global:NO_PROXY_LIST = "localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
|
||||||
|
|
||||||
|
# -------------------- 辅助:构建代理 URL --------------------
|
||||||
|
function _BuildProxyUrl {
|
||||||
|
$type = $env:_PROXY_TYPE
|
||||||
|
$host_addr = $env:_PROXY_HOST
|
||||||
|
$port = $env:_PROXY_PORT
|
||||||
|
|
||||||
|
switch ($type.ToLower()) {
|
||||||
|
"http" { return "http://$host_addr`:$port" }
|
||||||
|
"socks5" { return "socks5://$host_addr`:$port" }
|
||||||
|
"socks4" { return "socks4://$host_addr`:$port" }
|
||||||
|
default { return "$type`://$host_addr`:$port" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------- 辅助:控制台 WinINET 代理 (系统级 IE/Edge) --------------------
|
||||||
|
function _SetWinInetProxy([string]$proxyUrl) {
|
||||||
|
$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
|
||||||
|
if ($proxyUrl) {
|
||||||
|
Set-ItemProperty -Path $regPath -Name ProxyEnable -Value 1
|
||||||
|
Set-ItemProperty -Path $regPath -Name ProxyServer -Value ($proxyUrl -replace '^\w+://', '')
|
||||||
|
Set-ItemProperty -Path $regPath -Name ProxyOverride -Value $global:NO_PROXY_LIST
|
||||||
|
} else {
|
||||||
|
Set-ItemProperty -Path $regPath -Name ProxyEnable -Value 0
|
||||||
|
}
|
||||||
|
# 广播 WM_SETTINGCHANGE,让其他程序感知代理变更
|
||||||
|
$sig = @'
|
||||||
|
[DllImport("wininet.dll", SetLastError=true)]
|
||||||
|
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
|
||||||
|
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
|
||||||
|
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
|
||||||
|
'@
|
||||||
|
try {
|
||||||
|
Add-Type -MemberDefinition $sig -Namespace WinAPI -Name ProxyHelper -ErrorAction SilentlyContinue
|
||||||
|
[WinAPI.ProxyHelper]::InternetSetOption([IntPtr]::Zero, 39, [IntPtr]::Zero, 0) | Out-Null # PROXY_SETTINGS_CHANGED
|
||||||
|
$HWND_BROADCAST = [IntPtr]0xffff
|
||||||
|
$WM_SETTINGCHANGE = 0x1A
|
||||||
|
$result = [UIntPtr]::Zero
|
||||||
|
[WinAPI.ProxyHelper]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::Zero, "Environment", 2, 2000, [ref]$result) | Out-Null
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ====================================================================
|
||||||
|
# 开启代理
|
||||||
|
# ====================================================================
|
||||||
|
function Proxy-On {
|
||||||
|
$url = _BuildProxyUrl
|
||||||
|
|
||||||
|
# --- 进程级环境变量 ---
|
||||||
|
$env:http_proxy = $url
|
||||||
|
$env:HTTP_PROXY = $url
|
||||||
|
$env:https_proxy = $url
|
||||||
|
$env:HTTPS_PROXY = $url
|
||||||
|
$env:all_proxy = $url
|
||||||
|
$env:ALL_PROXY = $url
|
||||||
|
$env:no_proxy = $global:NO_PROXY_LIST
|
||||||
|
$env:NO_PROXY = $global:NO_PROXY_LIST
|
||||||
|
$env:ftp_proxy = $url
|
||||||
|
$env:FTP_PROXY = $url
|
||||||
|
$env:rsync_proxy = $url
|
||||||
|
|
||||||
|
# --- 用户级环境变量(持久化,新开终端也生效)---
|
||||||
|
[Environment]::SetEnvironmentVariable("http_proxy", $url, "User")
|
||||||
|
[Environment]::SetEnvironmentVariable("https_proxy", $url, "User")
|
||||||
|
[Environment]::SetEnvironmentVariable("all_proxy", $url, "User")
|
||||||
|
[Environment]::SetEnvironmentVariable("no_proxy", $global:NO_PROXY_LIST, "User")
|
||||||
|
|
||||||
|
# --- Git ---
|
||||||
|
git config --global http.proxy $url 2>$null
|
||||||
|
git config --global https.proxy $url 2>$null
|
||||||
|
|
||||||
|
# --- NPM ---
|
||||||
|
npm config set proxy $url 2>$null
|
||||||
|
npm config set https-proxy $url 2>$null
|
||||||
|
|
||||||
|
# --- Yarn ---
|
||||||
|
yarn config set proxy $url 2>$null
|
||||||
|
yarn config set https-proxy $url 2>$null
|
||||||
|
|
||||||
|
# --- Windows 系统 WinINET (IE/Edge/Chrome 等) ---
|
||||||
|
_SetWinInetProxy $url
|
||||||
|
|
||||||
|
Write-Host "[✓] 代理已开启 → " -ForegroundColor Green -NoNewline
|
||||||
|
Write-Host $url -ForegroundColor White
|
||||||
|
Write-Host " NO_PROXY → " -ForegroundColor Green -NoNewline
|
||||||
|
Write-Host $global:NO_PROXY_LIST -ForegroundColor White
|
||||||
|
}
|
||||||
|
|
||||||
|
# ====================================================================
|
||||||
|
# 关闭代理
|
||||||
|
# ====================================================================
|
||||||
|
function Proxy-Off {
|
||||||
|
# --- 进程级环境变量 ---
|
||||||
|
$vars = @("http_proxy","HTTP_PROXY","https_proxy","HTTPS_PROXY","all_proxy","ALL_PROXY",
|
||||||
|
"no_proxy","NO_PROXY","ftp_proxy","FTP_PROXY","rsync_proxy")
|
||||||
|
foreach ($v in $vars) { Remove-Item -Path "Env:$v" -ErrorAction SilentlyContinue }
|
||||||
|
|
||||||
|
# --- 用户级环境变量 ---
|
||||||
|
foreach ($v in @("http_proxy","https_proxy","all_proxy","no_proxy")) {
|
||||||
|
[Environment]::SetEnvironmentVariable($v, $null, "User")
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Git ---
|
||||||
|
git config --global --unset http.proxy 2>$null
|
||||||
|
git config --global --unset https.proxy 2>$null
|
||||||
|
|
||||||
|
# --- NPM ---
|
||||||
|
npm config delete proxy 2>$null
|
||||||
|
npm config delete https-proxy 2>$null
|
||||||
|
|
||||||
|
# --- Yarn ---
|
||||||
|
yarn config delete proxy 2>$null
|
||||||
|
yarn config delete https-proxy 2>$null
|
||||||
|
|
||||||
|
# --- Windows 系统 WinINET ---
|
||||||
|
_SetWinInetProxy $null
|
||||||
|
|
||||||
|
Write-Host "[✓] 代理已关闭" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
# ====================================================================
|
||||||
|
# 查看代理状态
|
||||||
|
# ====================================================================
|
||||||
|
function Proxy-Status {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "========== 代理状态 ==========" -ForegroundColor White
|
||||||
|
|
||||||
|
# 环境变量
|
||||||
|
Write-Host "`n[环境变量]" -ForegroundColor White
|
||||||
|
$envVars = @("http_proxy", "https_proxy", "all_proxy", "no_proxy", "ftp_proxy")
|
||||||
|
foreach ($v in $envVars) {
|
||||||
|
$val = [Environment]::GetEnvironmentVariable($v, "Process")
|
||||||
|
if ($val) {
|
||||||
|
Write-Host (" {0,-14} → {1}" -f $v, $val) -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host (" {0,-14} → (未设置)" -f $v) -ForegroundColor DarkGray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# 用户级环境变量
|
||||||
|
Write-Host "`n[用户级环境变量 (持久化)]" -ForegroundColor White
|
||||||
|
foreach ($v in @("http_proxy", "https_proxy", "all_proxy", "no_proxy")) {
|
||||||
|
$val = [Environment]::GetEnvironmentVariable($v, "User")
|
||||||
|
if ($val) {
|
||||||
|
Write-Host (" {0,-14} → {1}" -f $v, $val) -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host (" {0,-14} → (未设置)" -f $v) -ForegroundColor DarkGray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git
|
||||||
|
Write-Host "`n[Git 配置] (global)" -ForegroundColor White
|
||||||
|
$gitHttp = git config --global --get http.proxy 2>$null
|
||||||
|
$gitHttps = git config --global --get https.proxy 2>$null
|
||||||
|
if ($gitHttp -or $gitHttps) {
|
||||||
|
if ($gitHttp) { Write-Host " http.proxy → $gitHttp" -ForegroundColor Green }
|
||||||
|
if ($gitHttps) { Write-Host " https.proxy → $gitHttps" -ForegroundColor Green }
|
||||||
|
} else {
|
||||||
|
Write-Host " (未配置)" -ForegroundColor DarkGray
|
||||||
|
}
|
||||||
|
|
||||||
|
# NPM
|
||||||
|
if (Get-Command npm -ErrorAction SilentlyContinue) {
|
||||||
|
Write-Host "`n[NPM 配置]" -ForegroundColor White
|
||||||
|
$npmProxy = npm config get proxy 2>$null
|
||||||
|
$npmHttps = npm config get https-proxy 2>$null
|
||||||
|
if ($npmProxy -and $npmProxy -ne "null" -and $npmProxy -ne "undefined") {
|
||||||
|
Write-Host " proxy → $npmProxy" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host " proxy → (未设置)" -ForegroundColor DarkGray
|
||||||
|
}
|
||||||
|
if ($npmHttps -and $npmHttps -ne "null" -and $npmHttps -ne "undefined") {
|
||||||
|
Write-Host " https-proxy → $npmHttps" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host " https-proxy → (未设置)" -ForegroundColor DarkGray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Windows 系统代理
|
||||||
|
Write-Host "`n[Windows 系统 WinINET 代理]" -ForegroundColor White
|
||||||
|
$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
|
||||||
|
if (Test-Path $regPath) {
|
||||||
|
$enabled = (Get-ItemProperty -Path $regPath -Name ProxyEnable -ErrorAction SilentlyContinue).ProxyEnable
|
||||||
|
$server = (Get-ItemProperty -Path $regPath -Name ProxyServer -ErrorAction SilentlyContinue).ProxyServer
|
||||||
|
if ($enabled -eq 1) {
|
||||||
|
Write-Host " ProxyEnable → 1" -ForegroundColor Green
|
||||||
|
Write-Host " ProxyServer → $server" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host " ProxyEnable → 0 (已禁用)" -ForegroundColor DarkGray
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host " (无法读取注册表)" -ForegroundColor DarkGray
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# ====================================================================
|
||||||
|
# 测试代理连通性
|
||||||
|
# ====================================================================
|
||||||
|
function Proxy-Test {
|
||||||
|
$url = _BuildProxyUrl
|
||||||
|
Write-Host "[测试代理] $url`n" -ForegroundColor White
|
||||||
|
|
||||||
|
# Google (通过代理)
|
||||||
|
Write-Host " Google (proxy) → " -NoNewline
|
||||||
|
try {
|
||||||
|
$r = Invoke-WebRequest -Uri "https://www.google.com" -Proxy $url -TimeoutSec 5 -UseBasicParsing -ErrorAction Stop
|
||||||
|
if ($r.StatusCode -in 200,301,302) { Write-Host "✓ OK ($($r.StatusCode))" -ForegroundColor Green }
|
||||||
|
else { Write-Host "✗ FAIL ($($r.StatusCode))" -ForegroundColor Red }
|
||||||
|
} catch { Write-Host "✗ FAIL" -ForegroundColor Red }
|
||||||
|
|
||||||
|
# GitHub (通过代理)
|
||||||
|
Write-Host " GitHub (proxy) → " -NoNewline
|
||||||
|
try {
|
||||||
|
$r = Invoke-WebRequest -Uri "https://github.com" -Proxy $url -TimeoutSec 5 -UseBasicParsing -ErrorAction Stop
|
||||||
|
if ($r.StatusCode -in 200,301,302) { Write-Host "✓ OK ($($r.StatusCode))" -ForegroundColor Green }
|
||||||
|
else { Write-Host "✗ FAIL ($($r.StatusCode))" -ForegroundColor Red }
|
||||||
|
} catch { Write-Host "✗ FAIL" -ForegroundColor Red }
|
||||||
|
|
||||||
|
# 本地直连 (不走代理)
|
||||||
|
Write-Host " Baidu (direct) → " -NoNewline
|
||||||
|
try {
|
||||||
|
$r = Invoke-WebRequest -Uri "https://www.baidu.com" -TimeoutSec 3 -UseBasicParsing -NoProxy -ErrorAction Stop
|
||||||
|
if ($r.StatusCode -in 200,301,302) { Write-Host "✓ OK ($($r.StatusCode))" -ForegroundColor Green }
|
||||||
|
else { Write-Host "✗ FAIL ($($r.StatusCode))" -ForegroundColor Red }
|
||||||
|
} catch {
|
||||||
|
# PowerShell 5.1 不支持 -NoProxy,退而用 curl
|
||||||
|
try {
|
||||||
|
$code = (curl.exe -s -o NUL -w "%{http_code}" --max-time 3 --noproxy "*" https://www.baidu.com 2>$null)
|
||||||
|
if ($code -match "200|301|302") { Write-Host "✓ OK ($code)" -ForegroundColor Green }
|
||||||
|
else { Write-Host "✗ FAIL" -ForegroundColor Red }
|
||||||
|
} catch { Write-Host "✗ FAIL" -ForegroundColor Red }
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# ====================================================================
|
||||||
|
# 临时设置代理地址
|
||||||
|
# ====================================================================
|
||||||
|
function Proxy-Set {
|
||||||
|
param(
|
||||||
|
[Parameter(Position=0)][string]$ProxyHost,
|
||||||
|
[Parameter(Position=1)][string]$ProxyPort,
|
||||||
|
[Parameter(Position=2)][string]$ProxyType = "http"
|
||||||
|
)
|
||||||
|
if (-not $ProxyHost -or -not $ProxyPort) {
|
||||||
|
Write-Host "用法: proxy set <host> <port> [http|socks5]" -ForegroundColor Yellow
|
||||||
|
Write-Host '示例: proxy set 192.168.1.100 1080 socks5' -ForegroundColor Yellow
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$env:_PROXY_HOST = $ProxyHost
|
||||||
|
$env:_PROXY_PORT = $ProxyPort
|
||||||
|
$env:_PROXY_TYPE = $ProxyType
|
||||||
|
|
||||||
|
Write-Host "[✓] 代理地址已设置为 ${ProxyType}://${ProxyHost}:${ProxyPort}" -ForegroundColor Green
|
||||||
|
Write-Host " 执行 'proxy on' 启用新的代理地址" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
|
||||||
|
# ====================================================================
|
||||||
|
# 主入口:proxy 命令
|
||||||
|
# ====================================================================
|
||||||
|
function proxy {
|
||||||
|
param(
|
||||||
|
[Parameter(Position=0)][string]$Action = "help",
|
||||||
|
[Parameter(Position=1, ValueFromRemainingArguments)][string[]]$Args
|
||||||
|
)
|
||||||
|
|
||||||
|
switch ($Action.ToLower()) {
|
||||||
|
"on" { Proxy-On }
|
||||||
|
"off" { Proxy-Off }
|
||||||
|
"status" { Proxy-Status }
|
||||||
|
"test" { Proxy-Test }
|
||||||
|
"toggle" {
|
||||||
|
if ($env:http_proxy) { Proxy-Off } else { Proxy-On }
|
||||||
|
}
|
||||||
|
"set" {
|
||||||
|
if ($Args -and $Args.Count -ge 2) {
|
||||||
|
$type = if ($Args.Count -ge 3) { $Args[2] } else { "http" }
|
||||||
|
Proxy-Set -ProxyHost $Args[0] -ProxyPort $Args[1] -ProxyType $type
|
||||||
|
} else {
|
||||||
|
Proxy-Set
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"help" {
|
||||||
|
Write-Host @"
|
||||||
|
|
||||||
|
========== proxy.ps1 — 通用代理管理 ==========
|
||||||
|
|
||||||
|
用法:
|
||||||
|
. .\proxy.ps1 # 加载脚本(Dot-Source)
|
||||||
|
proxy on # 开启代理 (环境变量 + 系统WinINET + git + npm)
|
||||||
|
proxy off # 关闭代理
|
||||||
|
proxy status # 查看代理状态
|
||||||
|
proxy test # 测试代理连通性
|
||||||
|
proxy toggle # 切换开/关
|
||||||
|
proxy set <host> <port> [type]# 设置代理地址
|
||||||
|
proxy help # 显示帮助
|
||||||
|
|
||||||
|
默认配置 (可通过环境变量覆盖):
|
||||||
|
_PROXY_HOST = $($env:_PROXY_HOST)
|
||||||
|
_PROXY_PORT = $($env:_PROXY_PORT)
|
||||||
|
_PROXY_TYPE = $($env:_PROXY_TYPE) (http | socks5 | socks4)
|
||||||
|
|
||||||
|
自定义示例:
|
||||||
|
`$env:_PROXY_HOST = "10.0.0.5" # 修改主机
|
||||||
|
`$env:_PROXY_PORT = "1080" # 修改端口
|
||||||
|
proxy on # 启用
|
||||||
|
|
||||||
|
"@ -ForegroundColor Cyan
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
Write-Host "未知命令: $Action (使用 'proxy help' 查看帮助)" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------- 加载提示 --------------------
|
||||||
|
if ($MyInvocation.Line -notmatch '\$\s*\(?\s*\.\s+.*proxy\.ps1') {
|
||||||
|
# 被直接执行而非 dot-source 时
|
||||||
|
if ($args.Count -eq 0) {
|
||||||
|
# 无参数直接执行,先 dot-source 自己
|
||||||
|
Write-Host "[proxy.ps1] 请使用 '. .\proxy.ps1' 来加载脚本。" -ForegroundColor Yellow
|
||||||
|
Write-Host "[proxy.ps1] 如果要直接执行命令, 请运行: .\proxy.ps1 on" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "[proxy.ps1] 已加载。使用 'proxy help' 查看用法。" -ForegroundColor Cyan
|
||||||
|
}
|
||||||
+107
@@ -0,0 +1,107 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# 代理配置 - 请根据实际情况修改以下值
|
||||||
|
PROXY_HOST="127.0.0.1"
|
||||||
|
PROXY_HTTP_PORT="7890"
|
||||||
|
PROXY_SOCKS_PORT="7890"
|
||||||
|
|
||||||
|
# HTTP/HTTPS 代理地址
|
||||||
|
HTTP_PROXY_URL="http://${PROXY_HOST}:${PROXY_HTTP_PORT}"
|
||||||
|
SOCKS_PROXY_URL="socks5://${PROXY_HOST}:${PROXY_SOCKS_PORT}"
|
||||||
|
|
||||||
|
# 不使用代理的地址
|
||||||
|
NO_PROXY_VALUE="localhost,127.0.0.1,localaddress,.localdomain.com,.example.com,.hermesagent.org.cn,mcp.hermesagent.org.cn"
|
||||||
|
|
||||||
|
function proxy_on() {
|
||||||
|
export http_proxy="${HTTP_PROXY_URL}"
|
||||||
|
export https_proxy="${HTTP_PROXY_URL}"
|
||||||
|
export all_proxy="${SOCKS_PROXY_URL}"
|
||||||
|
export no_proxy="${NO_PROXY_VALUE}"
|
||||||
|
|
||||||
|
# 同时设置大写版本(某些程序需要)
|
||||||
|
export HTTP_PROXY="${HTTP_PROXY_URL}"
|
||||||
|
export HTTPS_PROXY="${HTTP_PROXY_URL}"
|
||||||
|
export ALL_PROXY="${SOCKS_PROXY_URL}"
|
||||||
|
export NO_PROXY="${NO_PROXY_VALUE}"
|
||||||
|
|
||||||
|
echo -e "\033[32m┌──────────────────────────────────────┐\033[0m"
|
||||||
|
echo "│ ✅ 代理已启用 │"
|
||||||
|
echo "├──────────────────────────────────────┤"
|
||||||
|
echo "│ http_proxy : ${HTTP_PROXY_URL}"
|
||||||
|
echo "│ https_proxy: ${HTTP_PROXY_URL}"
|
||||||
|
echo "│ all_proxy : ${SOCKS_PROXY_URL}"
|
||||||
|
echo -e "\033[32m└──────────────────────────────────────┘\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
function proxy_off() {
|
||||||
|
unset http_proxy https_proxy all_proxy no_proxy
|
||||||
|
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY
|
||||||
|
|
||||||
|
echo -e "\033[31m┌──────────────────────────────────────┐\033[0m"
|
||||||
|
echo "│ ❌ 代理已关闭 │"
|
||||||
|
echo -e "\033[31m└──────────────────────────────────────┘\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
function proxy_status() {
|
||||||
|
echo -e "\033[36m┌──────────────────────────────────────┐\033[0m"
|
||||||
|
echo "│ 📊 代理状态 │"
|
||||||
|
echo -e "├──────────────────────────────────────┤\033[0m"
|
||||||
|
|
||||||
|
if [ -z "$http_proxy" ]; then
|
||||||
|
echo -e "\033[31m│ 状态: 未启用 │\033[0m"
|
||||||
|
else
|
||||||
|
echo -e "\033[32m│ 状态: 已启用 │\033[0m"
|
||||||
|
echo "│ http_proxy : $http_proxy"
|
||||||
|
echo "│ https_proxy: $https_proxy"
|
||||||
|
echo "│ all_proxy : $all_proxy"
|
||||||
|
echo "│ no_proxy : $no_proxy"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\033[36m└──────────────────────────────────────┘\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
function proxy_test() {
|
||||||
|
# 检查 curl 是否可用
|
||||||
|
if ! command -v curl >/dev/null 2>&1; then
|
||||||
|
echo "curl 未安装,无法测试代理" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\033[33m测试代理连通性...\033[0m"
|
||||||
|
|
||||||
|
# 1. 本地代理端口是否在监听(不依赖外网,最快的失败定位)
|
||||||
|
echo -n "代理端口 ${PROXY_HOST}:${PROXY_HTTP_PORT}: "
|
||||||
|
if (exec 3<>/dev/tcp/"${PROXY_HOST}"/"${PROXY_HTTP_PORT}") 2>/dev/null; then
|
||||||
|
exec 3<&- 3>&-
|
||||||
|
echo -e "\033[32m✓ 可达\033[0m"
|
||||||
|
else
|
||||||
|
echo -e "\033[31m✗ 不可达(请确认代理客户端已启动)\033[0m"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. 通过代理访问 GitHub(翻墙连通性测试),不通则试 Google
|
||||||
|
echo -n "代理访问 https://github.com: "
|
||||||
|
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 8 \
|
||||||
|
-x "${HTTP_PROXY_URL}" https://github.com 2>/dev/null)
|
||||||
|
if [ -n "$code" ] && [ "$code" -ge 200 ] && [ "$code" -lt 400 ]; then
|
||||||
|
echo -e "\033[32m✓ HTTP ${code}\033[0m"
|
||||||
|
else
|
||||||
|
echo -e "\033[31m✗ 失败(${code:-N/A})\033[0m"
|
||||||
|
echo -n "代理访问 https://www.google.com: "
|
||||||
|
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 8 \
|
||||||
|
-x "${HTTP_PROXY_URL}" https://www.google.com 2>/dev/null)
|
||||||
|
if [ -n "$code" ] && [ "$code" -ge 200 ] && [ "$code" -lt 400 ]; then
|
||||||
|
echo -e "\033[32m✓ HTTP ${code}\033[0m"
|
||||||
|
else
|
||||||
|
echo -e "\033[31m✗ 失败(${code:-N/A})\033[0m"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. 显示当前出口 IP(直连)
|
||||||
|
echo -n "直连出口 IP: "
|
||||||
|
curl --max-time 5 myip.ipip.net 2>/dev/null || echo "获取失败"
|
||||||
|
|
||||||
|
# 4. 显示代理出口 IP(走代理,通过 HTTPS CONNECT 获取更稳定)
|
||||||
|
echo -n "代理出口 IP: "
|
||||||
|
curl -w "\n" --max-time 8 -x "${HTTP_PROXY_URL}" inet-ip.info 2>/dev/null || echo "获取失败"
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# ============================================================
|
||||||
|
# tasks 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p tasks --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG=baldissaramatheus/tasks.md:2.5.4
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/tasks.md
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# path:: mkdir -pv /data/volumes/tasks.md/{tasks,config}
|
||||||
|
# pull:: docker compose -p tasks.md --env-file ./tasks.md/env.cfg -f ./tasks.md/stack.yml pull
|
||||||
|
# run:: docker compose -p tasks.md --env-file ./tasks.md/env.cfg -f ./tasks.md/stack.yml up -d
|
||||||
|
|
||||||
|
services:
|
||||||
|
tasks.md:
|
||||||
|
image: ${IMAGE_TAG}
|
||||||
|
container_name: tasks.md
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
volumes:
|
||||||
|
- ${Volumes_Path}/tasks:/tasks
|
||||||
|
- ${Volumes_Path}/config:/config
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- 5480:8080
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# ============================================================
|
||||||
|
# traefik 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p traefik --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG_V3=traefik:v3.5.1
|
||||||
|
|
||||||
|
IMAGE_TAG_V2=traefik:v2.11.29
|
||||||
|
|
||||||
|
IMAGE_TAG_LATEST=traefik:latest
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# ========== 经典模式 ==========
|
||||||
|
# 如果为 true,不使用任何颜色或图标,与标准 ls 行为类似
|
||||||
|
classic: false
|
||||||
|
|
||||||
|
# ========== 分块(Blocks) ==========
|
||||||
|
# 定义每行显示哪些信息块,按顺序排列
|
||||||
|
blocks:
|
||||||
|
- permission # 文件权限 (rwxr-xr-x)
|
||||||
|
- user # 文件所有者
|
||||||
|
- group # 用户组
|
||||||
|
- size # 文件大小
|
||||||
|
- date # 日期/时间
|
||||||
|
- name # 文件名(必须包含)
|
||||||
|
|
||||||
|
# ========== 颜色主题 ==========
|
||||||
|
color:
|
||||||
|
# 何时使用颜色:always(总是)、auto(自动)、never(从不)
|
||||||
|
when: auto
|
||||||
|
|
||||||
|
# 自定义文件类型颜色(覆盖默认值)
|
||||||
|
theme: custom
|
||||||
|
|
||||||
|
# ========== 日期格式 ==========
|
||||||
|
date: "+%Y-%m-%d %H:%M:%S" # 可选:relative(相对时间)、iso(ISO格式)
|
||||||
|
|
||||||
|
# ========== 跟随符号链接 ============
|
||||||
|
dereference: false
|
||||||
|
|
||||||
|
# ========== 图标 ==========
|
||||||
|
icons:
|
||||||
|
# 何时显示图标:always、auto、never
|
||||||
|
when: auto
|
||||||
|
|
||||||
|
# 图标主题(需要对应的 Nerd Font)
|
||||||
|
theme: fancy # 或 unicode
|
||||||
|
|
||||||
|
# 分隔符(图标与文件名之间的字符)
|
||||||
|
separator: " "
|
||||||
|
|
||||||
|
# ========== 忽略选项 ==========
|
||||||
|
ignore-globs:
|
||||||
|
- "*.bak" # 忽略所有 .bak 文件
|
||||||
|
- ".git" # 忽略 .git 目录
|
||||||
|
- "__pycache__" # 忽略 Python 缓存
|
||||||
|
|
||||||
|
# ========== 布局 ==========
|
||||||
|
layout: grid # grid(网格)| tree(树状)| oneline(单行)
|
||||||
|
|
||||||
|
# ========== 递归深度(--tree 时有效) ==========
|
||||||
|
recursion:
|
||||||
|
enabled: false
|
||||||
|
depth: 3 # 递归显示的最大深度
|
||||||
|
|
||||||
|
# ========== 排序 ==========
|
||||||
|
sorting:
|
||||||
|
column: name # 排序字段:name、size、time、version、extension
|
||||||
|
# reverse: false # 是否倒序
|
||||||
|
# dir-grouping: first # 目录排序:first(靠前)、last(靠后)、none
|
||||||
|
|
||||||
|
# ========== 符号链接 ==========
|
||||||
|
# 是否显示符号链接的目标路径
|
||||||
|
no-symlink: false
|
||||||
|
symlink-arrow: " ➜ "
|
||||||
|
|
||||||
|
# ========== 总大小 ==========
|
||||||
|
total-size: false # 是否显示总大小(在目录底部)
|
||||||
|
|
||||||
|
# ========== 截断所有者名 ==========
|
||||||
|
truncate-owner:
|
||||||
|
after: 8 # 用户名超过多少字符截断
|
||||||
|
|
||||||
|
# ========== 超链接 ==========
|
||||||
|
hyperlink: never # always | auto | never 是否生成终端超链接
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# 文件类型颜色
|
||||||
|
file-type:
|
||||||
|
directory:
|
||||||
|
foreground: cyan
|
||||||
|
bold: true
|
||||||
|
symlink:
|
||||||
|
foreground: magenta
|
||||||
|
italic: true
|
||||||
|
executable:
|
||||||
|
foreground: green
|
||||||
|
bold: true
|
||||||
|
socket:
|
||||||
|
foreground: red
|
||||||
|
pipe:
|
||||||
|
foreground: yellow
|
||||||
|
block-device:
|
||||||
|
foreground: red
|
||||||
|
char-device:
|
||||||
|
foreground: yellow
|
||||||
|
|
||||||
|
# 文件扩展名颜色(覆盖文件类型颜色)
|
||||||
|
extensions:
|
||||||
|
rs:
|
||||||
|
foreground: white
|
||||||
|
bold: true
|
||||||
|
py:
|
||||||
|
foreground: yellow
|
||||||
|
js:
|
||||||
|
foreground: green
|
||||||
|
md:
|
||||||
|
foreground: cyan
|
||||||
|
italic: true
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# RUN:: docker compose -p prod-dbs --env-file ./victoriametrics/env.cfg -f ./victoriametrics/compose.yml up -d
|
||||||
|
|
||||||
services:
|
services:
|
||||||
victoriametrics:
|
victoriametrics:
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# ============================================================
|
||||||
|
# victoriametrics 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p victoriametrics --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
IMAGE_TAG=victoriametrics/victoria-metrics:v1.126.0
|
||||||
|
|
||||||
|
Volumes_Path=/data/volumes/VictoriaMetrics
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# ============================================================
|
||||||
|
# webout 部署 — 公共环境变量模板(不含敏感信息)
|
||||||
|
# 复制为 env.cfg 后填入真实值,env.cfg 已被 .gitignore 忽略
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# cp env.cfg.example env.cfg
|
||||||
|
# $EDITOR env.cfg # 填入真实密码/密钥后保存
|
||||||
|
# docker compose -p webout --env-file ./env.cfg -f ./stack.yml up -d
|
||||||
|
#
|
||||||
|
#IMAGE_TAG=hub.tp229.com:3500/caddy:2.8.4
|
||||||
|
|
||||||
|
IMAGE_TAG=caddy:2.10.0
|
||||||
|
|
||||||
|
BUILD_IMAGE_TAG=caddy:2.10.0-builder
|
||||||
|
|
||||||
|
WEBDAV_IMAGE_TAG=cnphpbb/caddy-webdav:2-alpine
|
||||||
|
|
||||||
|
TXC_DEPLOY_ROOT=/data/deploy.stack
|
||||||
|
|
||||||
|
TXC_VOLUMES_ROOT=/data/volumes
|
||||||
|
|
||||||
|
CADDY_CONFIG_ROOT=/data/configs
|
||||||
Reference in New Issue
Block a user