DEPLOYMENT.md 30 KB

FranklinWH Toolbox 全量部署文档

本文档描述如何在一台全新的 Ubuntu 服务器上,从零部署 FranklinWH Toolbox (Vue 3 前端 + Go 后端)的完整流程,包括所有依赖数据库的安装、配置、建库建表、 反向代理与 systemd 服务。安装方式与版本参照当前生产服务器的实际部署。

参考环境(当前服务器实测):Ubuntu 22.04.5 LTS,Go 1.26,Node 22.15,pnpm 8.6, PostgreSQL 14,MongoDB 8.0,Redis 7.4,MinIO(RELEASE 版),Caddy 2.11。


⚑ 部署前需要你确认/填写的清单(TODO)

下面列出必须由你确认或填写的项。脚本与 config.env.example 中对应位置均已用 # TODO: 注释标出,可搜索 TODO 快速定位。

📋 完整的可勾选清单(含填写项与部署步骤)见 CHECKLIST.md。

必填(不改则无法正常运行 / 有安全风险)

  • PostgreSQL 业务口令 fwh_toolbox 角色密码:init_databases.sh 的 PG_FWH_PASSWORD 与 config.env 的 POSTGRES_DSN 中 password= 必须一致。
  • MinIO 管理员口令 MINIO_ROOT_USER/MINIO_ROOT_PASSWORD(勿用默认 minioadmin)。
  • MinIO 业务密钥 config.env 的 MINIO_ACCESS_KEY/MINIO_SECRET_KEY。
  • FWH 生产账号 config.env 的 FWH_USER/FWH_PASSWORD。
  • FWH MQTT 证书 放入 server/cert/pro/,并核对 config.env 中路径。
  • Casdoor 数据库口令 CASDOOR_PG_PASSWORD(勿用默认 casdoor)。
  • Casdoor 应用信息 在 Casdoor 建 organization_franklinwh_toolbox / app-franklinwh-toolbox,若新建应用需把 clientId/secret/证书同步到源码 (service/utils/casdoor/casdoor.go、src/utils/casdoor/casdoor.ts)后重新构建。
  • 域名 反向代理 Caddyfile 中的 你的域名、Casdoor origin/回调 URL。
  • 远端 MySQL config.env 的 MYSQL_DSN(用到站点信息查询功能时必填)。

需确认(有默认值,请核对是否符合你的环境)

  • 部署根目录 DEPLOY_ROOT(默认 /var/www/fwh-toolbox)与运行用户 RUN_USER。
  • 端口:后端 APP_PORT=8301、Asynqmon 8302、MinIO 9198/9199、Casdoor 8010。
  • APP_ENV(pro/dev)、MONGO_DSN 库名(生产 FwhToolboxDb)、MINIO_BUCKET_NAME。
  • KIRO_RUN_AS_USER/KIRO_HOME 改成目标机实际用户。

可选(用到对应功能才填)

  • FWH 测试环境账号与 MQTT(FWH_TEST_*)。
  • Plane 集成(PLANE_*)。

交互式脚本 deploy/scripts/setup.sh 会逐项提示你填写以上内容,推荐优先使用。


目录

  1. 快速开始:交互式一键部署
  2. 架构总览
  3. 端口与目录约定
  4. 基础环境与依赖安装
  5. 数据库安装
  6. 数据库初始化与数据表导入
  7. 后端配置
  8. 构建与部署后端
  9. 构建与部署前端
  10. 反向代理(Caddy)
  11. Casdoor 认证服务安装与配置
  12. 启动、验证与排错
  13. 附录:一键脚本清单

0. 快速开始:交互式一键部署

如果只想尽快完成部署,直接运行交互式脚本 deploy/scripts/setup.sh。它会分步引导 你选择/填写内容,并支持本地与远程(SSH)两种目标:

cd deploy/scripts
chmod +x setup.sh
./setup.sh

向导流程:

  1. 选择模式:本地 (local) 或 远程 (remote,通过 SSH)
  2. 选择步骤:初始化数据库 / 部署后端 / 部署前端(可自由勾选)
  3. (远程)填写 SSH 连接:主机、端口、用户、私钥,并自动测试连通性
  4. 填写配置:部署目录、运行用户、PostgreSQL/Mongo/Redis/MinIO/MySQL 等
  5. 自动生成 config.env → 本机构建前端 dist 与后端二进制 → (远程时)打包上传 → 执行所选步骤

设计要点:

  • 本地构建 + 远程安装:前端/后端在运行脚本的机器上构建,再上传到远程, 因此远程主机无需安装 Go/Node。
  • 脚本只做建库建表建桶与服务部署,不自动安装数据库引擎;数据库软件的 安装仍请参考下文第 3、4 章(可在目标机预先装好 PostgreSQL/MongoDB/Redis/MinIO)。
  • 反向代理(Caddy)需按第 9 章手动配置。

想了解每一步的底层动作、或需要单独执行某一环节,请继续阅读后续章节; setup.sh 内部即是对第 5~8 章操作的编排。


1. 架构总览

                        ┌─────────────────────────────────────────┐
   浏览器 ── HTTPS ────▶ │  Caddy (反向代理, :80/:443)              │
                        │   /fwh-toolbox/*      → 前端静态 (:8300) │
                        │   /fwh-toolbox/api/*  → 后端 API (:8301) │
                        └───────────────┬─────────────────────────┘
                                        │
        ┌───────────────────────────────┼──────────────────────────────┐
        ▼                               ▼                              ▼
┌───────────────┐            ┌────────────────────┐          ┌──────────────────┐
│ 前端静态文件   │            │ Go 后端            │          │ fwh-mcp-server   │
│ Apache :8300  │            │ fwh-toolbox-server │          │ (MCP,可选)       │
│ /var/www/...  │            │ localhost:8301     │          └──────────────────┘
└───────────────┘            │ Asynqmon :8302     │
                             └─────────┬──────────┘
                                       │
    ┌──────────────┬───────────────────┼───────────────┬────────────────┐
    ▼              ▼                   ▼               ▼                ▼
┌─────────┐  ┌──────────┐        ┌──────────┐   ┌──────────┐    ┌─────────────────┐
│PostgreSQL│  │ MongoDB  │        │  Redis   │   │  MinIO   │    │ 远端 MySQL(只读) │
│  :5432   │  │ :27017   │        │  :6379   │   │  :9198   │    │ FWH 生产库       │
│ 本地     │  │ 本地     │        │ 本地     │   │ 本地     │    │ 远程 34.x:3308   │
└─────────┘  └──────────┘        └──────────┘   └──────────┘    └─────────────────┘

数据库职责说明:

数据库 位置 用途
PostgreSQL 本地 保存站点原始数据(original schema,运行时按雪花ID动态建表)与告警快照(alarm_snapshot schema,两张固定表)
MongoDB 本地 保存业务文档数据,集合首次写入时自动创建(生产库 FwhToolboxDb)
Redis 本地 缓存 + Asynq 异步任务队列(任务使用 DB 12)
MinIO 本地 对象存储(快照/日志/故障录波等文件),bucket fwh-toolbox
MySQL 远程只读 FranklinWH 生产库 home_energy_storage_server,仅查询站点信息(iot_gateway 表)。新服务器无需安装 MySQL,只需网络可达并在 config.env 配置只读账号

注:后端代码中 MySQL 初始化默认被注释(见 service/database/database.go), 是否启用取决于所用功能;PostgreSQL 与 MongoDB 为必需。


2. 端口与目录约定

组件 端口 绑定 备注
后端 API 8301 127.0.0.1 APP_PORT,仅本机,经反代对外
Asynqmon 8302 0.0.0.0 ASYNQMON_PORT,任务监控面板 /asynqmon
前端静态 8300 由 Web 服务器(Apache/Nginx)托管 dist 目录
PostgreSQL 5432 本地
MongoDB 27017 127.0.0.1
Redis 6379 127.0.0.1
MinIO API 9198 本地 S3 API
MinIO 控制台 9199 本地 Web 控制台
Caddy 80 / 443 对外 反向代理入口

部署目录(与线上一致):

/var/www/fwh-toolbox/
├── fwh-toolbox/          # 前端构建产物(dist/* 拷贝到此)
└── server/               # 后端运行目录
    ├── fwh-toolbox-server    # 后端主程序二进制
    ├── fwh-mcp-server        # MCP 服务二进制(可选)
    ├── config.env            # 后端配置(由 config.env.example 复制修改)
    └── cert/                 # FWH MQTT 证书 (pro/ 与 test/)

3. 基础环境与依赖安装

以下命令在全新 Ubuntu 22.04 上以具备 sudo 权限的用户执行。

3.1 系统更新与基础工具

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget git build-essential ca-certificates gnupg lsb-release

3.2 Go 1.26

参照线上使用官方二进制安装(不使用 apt 版本,避免过旧):

GO_VERSION=1.26.4
wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee /etc/profile.d/go.sh
source /etc/profile.d/go.sh
go version    # 期望输出 go version go1.26.x linux/amd64

3.3 Node.js 22 + pnpm

# Node 22 (NodeSource)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node -v        # v22.x

# pnpm(项目使用 pnpm,lock 文件为 pnpm-lock.yaml)
sudo npm install -g pnpm@8
pnpm -v        # 8.x

3.4 uv(Python 包/工具管理器,可选)

后端 AI 对话 / MCP 相关能力可能通过 uvx 拉起基于 Python 的 MCP server,需要 uv。 install_deps.sh 会自动检测并安装(缺失时),也可手动安装:

# 官方脚本,安装到 /usr/local/bin(全局可用,不修改 shell profile)
curl -LsSf https://astral.sh/uv/install.sh \
  | sudo env UV_INSTALL_DIR=/usr/local/bin sh -s -- --no-modify-path
uv --version   # 期望输出 uv 0.x.x

4. 数据库安装

自动检测/安装:可直接用 deploy/scripts/install_deps.sh 一次性完成本章 各数据库引擎的检测与(缺失时)安装(幂等,可重复运行):

> cd deploy/scripts && chmod +x install_deps.sh
> DETECT_ONLY=1 ./install_deps.sh                 # 仅检测各组件是否已安装
> MINIO_ROOT_USER='admin' MINIO_ROOT_PASSWORD='强密码' \
>   ./install_deps.sh postgres mongo redis minio mc docker   # 检测并安装缺失项
> ```
>
> 下面各小节是等价的手动步骤与版本参考(与线上一致)。

### 4.1 PostgreSQL 14

bash sudo apt install -y postgresql postgresql-contrib sudo systemctl enable --now postgresql psql --version # PostgreSQL 14.x


### 4.2 MongoDB 8.0

Ubuntu 官方仓库没有 MongoDB,使用官方源:

bash curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | \ sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/8.0 multiverse" | \ sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list sudo apt update sudo apt install -y mongodb-org sudo systemctl enable --now mongod mongosh --eval 'db.runCommand({ping:1})'


> 线上 MongoDB 绑定 `127.0.0.1:27017`。如需限制,编辑 `/etc/mongod.conf` 的
> `net.bindIp: 127.0.0.1`。

### 4.3 Redis 7.x

bash sudo apt install -y redis-server sudo systemctl enable --now redis-server redis-cli ping # PONG


> 后端将 Asynq 任务队列放在 Redis **DB 12**,无需额外配置。

### 4.4 MinIO(对象存储)

参照线上使用官方二进制 + 独立 `minio-user` + systemd:

bash

1. 下载二进制

sudo wget -O /usr/local/bin/minio https://dl.min.io/server/minio/release/linux-amd64/minio sudo chmod +x /usr/local/bin/minio

2. 创建运行用户与数据目录

sudo useradd -r minio-user -s /sbin/nologin || true sudo mkdir -p /var/lib/minio/data sudo chown -R minio-user:minio-user /var/lib/minio

3. 环境变量文件

sudo tee /etc/default/minio > /dev/null <<'EOF' MINIO_VOLUMES="/var/lib/minio/data"

API :9198,控制台 :9199(与线上一致)

MINIO_OPTS="--address :9198 --console-address :9199" MINIO_ROOT_USER="CHANGE_ME_ADMIN" MINIO_ROOT_PASSWORD="CHANGE_ME_STRONG_PASSWORD" EOF

4. systemd 服务

sudo tee /etc/systemd/system/minio.service > /dev/null <<'EOF' [Unit] Description=MinIO Documentation=https://docs.min.io Wants=network-online.target After=network-online.target AssertFileIsExecutable=/usr/local/bin/minio

[Service] Type=notify WorkingDirectory=/usr/local User=minio-user Group=minio-user EnvironmentFile=-/etc/default/minio ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES Restart=always LimitNOFILE=1048576 TasksMax=infinity OOMScoreAdjust=-1000

[Install] WantedBy=multi-user.target EOF

sudo systemctl daemon-reload sudo systemctl enable --now minio


安装 `mc`(MinIO Client,用于建 bucket):

bash sudo wget -O /usr/local/bin/mc https://dl.min.io/client/mc/release/linux-amd64/mc sudo chmod +x /usr/local/bin/mc


### 4.5 远端 MySQL

**新服务器不需要安装 MySQL**。它连接的是 FranklinWH 的远程生产库
(示例 `34.211.183.235:3308` 的 `home_energy_storage_server`),只需:

- 保证服务器网络能访问该地址与端口;
- 在 `config.env` 的 `MYSQL_DSN` 中填入只读账号。

仓库中 `service/database/sql/home_energy_storage_server_iot_gateway_2025-08-11_152722.sql`
是该远程库 `iot_gateway` 表的结构快照,仅供参考/本地测试导入使用。

---

## 5. 数据库初始化与数据表导入

### 5.1 PostgreSQL:建角色 / 建库 / 建 schema / 建表

后端的 `alarm_snapshot` 两张表**不会**自动迁移,需要预先创建;`original` schema
下的原始数据表在运行时按雪花ID动态创建,因此只需建好 schema。仓库提供了幂等 SQL:

`deploy/sql/init_pgsql.sql`

一键执行(推荐使用脚本,见下节);或手动:

bash

使用自定义密码执行;不传则默认 fwh_toolbox(仅限本地开发)

密码直接传入、无需加引号(脚本内部用 %L 安全转义)

sudo -u postgres psql -v ON_ERROR_STOP=1 \ -v fwh_pwd=你的强密码 \ -f deploy/sql/init_pgsql.sql


执行后将得到:

- 角色 `fwh_toolbox`(可登录)
- 数据库 `fwh_toolbox_db`(owner=`fwh_toolbox`)
- schema:`original`、`alarm_snapshot`、`public`
- 表:`alarm_snapshot.site_alarm_snapshot_data`、
  `alarm_snapshot.site_alarm_snapshot_file_record`

验证:

bash sudo -u postgres psql -d fwh_toolbox_db -c "\dn" sudo -u postgres psql -d fwh_toolbox_db -c "\dt alarm_snapshot.*"


### 5.2 一键初始化所有本地数据库

仓库提供 `deploy/scripts/init_databases.sh`,会完成 PostgreSQL 初始化、
MongoDB/Redis 连通性检查、MinIO bucket 创建:

bash cd deploy/scripts chmod +x init_databases.sh

PG_FWH_PASSWORD='你的强密码' \ MINIO_ROOT_USER='你的MinIO管理员' \ MINIO_ROOT_PASSWORD='你的MinIO密码' \ MINIO_BUCKET='fwh-toolbox' \ ./init_databases.sh


### 5.3 MongoDB

无需手动建集合——集合会在后端首次写入时自动创建。生产环境使用库名
`FwhToolboxDb`(在 `MONGO_DSN` 末尾指定)。若要从旧库迁移数据:

bash

导出(旧服务器)

mongodump --uri="mongodb://127.0.0.1:27017/FwhToolboxDb" --out=/tmp/fwhdump

导入(新服务器)

mongorestore --uri="mongodb://127.0.0.1:27017" /tmp/fwhdump


### 5.4 迁移已有 PostgreSQL 业务数据(可选)

若需把旧服务器的完整业务数据搬到新服务器:

bash

旧服务器导出(含 original 动态表 + alarm_snapshot 表)

sudo -u postgres pg_dump -Fc -d fwh_toolbox_db -f /tmp/fwh_toolbox_db.dump

新服务器恢复(先用 init_pgsql.sql 建好角色/库,再恢复)

sudo -u postgres pg_restore -d fwh_toolbox_db --no-owner --role=fwh_toolbox /tmp/fwh_toolbox_db.dump


---

## 6. 后端配置

后端使用 Viper 读取配置,优先级:`./.env` → `./config.env`,环境变量可覆盖。
仓库提供模板 `deploy/config.env.example`。

bash

复制模板到 service 目录(本地运行)或直接到部署目录 /var/www/fwh-toolbox/server/

cp deploy/config.env.example service/config.env

编辑 config.env,至少修改:

POSTGRES_DSN 中的 password

MONGO_DSN(生产用 FwhToolboxDb)

MINIO_ACCESS_KEY / MINIO_SECRET_KEY

MYSQL_DSN 只读账号

FWH_PASSWORD / FWH_TEST_PASSWORD 等密钥


关键项对照(详见模板注释):

| 变量 | 示例/默认 | 说明 |
| --- | --- | --- |
| `APP_PORT` | `8301` | 后端监听端口(localhost) |
| `ASYNQMON_PORT` | `8302` | 任务监控面板端口 |
| `POSTGRES_DSN` | `host=localhost user=fwh_toolbox password=... dbname=fwh_toolbox_db port=5432 sslmode=disable` | 本地 PG |
| `MONGO_DSN` | `mongodb://127.0.0.1:27017/FwhToolboxDb` | 本地 Mongo |
| `REDIS_ADDR` | `localhost:6379` | 本地 Redis |
| `MINIO_ENDPOINT` | `localhost:9198` | MinIO S3 API |
| `MINIO_BUCKET_NAME` | `fwh-toolbox` | 业务 bucket |
| `MYSQL_DSN` | 远程只读账号 | FWH 生产库 |

> **MQTT 证书**:把 `cert/pro/` 与 `cert/test/` 下的 CA/证书/私钥放到
> `server/cert/` 对应目录(路径与 `config.env` 中 `FWH_MQTT_*` 保持相对一致)。
> 证书文件属敏感凭据,请勿提交到仓库。

---

## 7. 构建与部署后端

### 7.1 手动方式

bash cd service GOOS=linux GOARCH=amd64 go build -o fwh-toolbox-server ./ GOOS=linux GOARCH=amd64 go build -o fwh-mcp-server ./cmd/mcp/

sudo mkdir -p /var/www/fwh-toolbox/server sudo mv fwh-toolbox-server fwh-mcp-server /var/www/fwh-toolbox/server/ sudo cp config.env /var/www/fwh-toolbox/server/config.env

拷贝证书目录

sudo cp -r cert /var/www/fwh-toolbox/server/


### 7.2 systemd 服务

创建 `/etc/systemd/system/fwh-toolbox-server.service`:

ini [Unit] Description=fwh-toolbox-server service After=network.target postgresql.service mongod.service redis-server.service minio.service

[Service] ExecStart=/var/www/fwh-toolbox/server/fwh-toolbox-server Restart=always User=jerry-remote WorkingDirectory=/var/www/fwh-toolbox/server CPUQuota=200% MemoryLimit=2G

[Install] WantedBy=multi-user.target


bash sudo systemctl daemon-reload sudo systemctl enable --now fwh-toolbox-server sudo systemctl status fwh-toolbox-server --no-pager


> `User` 应与配置的 `KIRO_RUN_AS_USER` 一致,并保证该用户对
> `WorkingDirectory` 及 `cert/`、`function/` 等目录有读写权限。

### 7.3 一键脚本

bash cd deploy/scripts chmod +x deploy.sh ./deploy.sh backend # 仅后端


---

## 8. 构建与部署前端

前端使用 Vite(rolldown-vite),生产环境变量见 `.env.production`:

- `VITE_PUBLIC_PATH = /fwh-toolbox/`(与反代路径一致)
- `VITE_API_URL = /fwh-toolbox/api`
- `VITE_ROUTER_MODE = hash`

### 8.1 手动方式

bash

仓库根目录

pnpm install --frozen-lockfile pnpm build # 产物在 ./dist

sudo mkdir -p /var/www/fwh-toolbox/fwh-toolbox sudo rm -rf /var/www/fwh-toolbox/fwh-toolbox/* sudo cp -rf ./dist/* /var/www/fwh-toolbox/fwh-toolbox/


> `package.json` 中的 `install` 脚本即等价于上面的拷贝操作。

### 8.2 前端静态托管

线上由本地 Web 服务器(Apache,监听 8300)托管该静态目录,再由 Caddy 反代。
用 Apache 为例,站点根指向 `/var/www/fwh-toolbox/fwh-toolbox`,监听 8300。
也可直接用 Caddy 的 `file_server` 托管,省去 Apache。

### 8.3 一键脚本

bash cd deploy/scripts ./deploy.sh frontend # 仅前端

或 ./deploy.sh all # 前端 + 后端


---

## 9. 反向代理(Caddy)

安装 Caddy 2:

bash sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \ sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \ sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update && sudo apt install -y caddy


在站点 Caddyfile 中加入以下片段(`你的域名` 替换为实际域名)。前端静态走 8300,
API 走 8301(与 `VITE_API_URL=/fwh-toolbox/api` 对应):

caddyfile 你的域名 {

tls internal        # 生产用真实证书时替换为 ACME/DNS 配置
encode zstd gzip

# fwh-toolbox 前端 + API
redir /fwh-toolbox /fwh-toolbox/ 301
handle /fwh-toolbox/* {
    # API:/fwh-toolbox/api/* -> 后端 8301(去掉前缀)
    handle_path /fwh-toolbox/api/* {
        reverse_proxy localhost:8301
    }
    # 其余:前端静态 8300
    reverse_proxy localhost:8300
}

# MinIO 控制台(可选)
redir /fwh-minio /fwh-minio/ 301
handle_path /fwh-minio/* {
    reverse_proxy localhost:9199
}

}


> 线上实际由 Apache 在 8300 托管静态、Caddy 统一入口反代;也可让 Caddy 直接
> `file_server` 托管 `/var/www/fwh-toolbox/fwh-toolbox`,二选一即可。

重载:

bash sudo systemctl reload caddy

或 caddy reload --config /etc/caddy/Caddyfile


---

## 10. Casdoor 认证服务安装与配置

前后端的登录鉴权由 [Casdoor](https://casdoor.org/) 提供(OAuth/OIDC + JWT)。
线上以 **Docker** 方式运行 `casbin/casdoor`,容器端口 `8000` 映射到宿主 `8010`,
后端 PostgreSQL 中有独立的 `casdoor` 数据库存放其数据,Caddy 将 `/casdoor/*`
反代到 `localhost:8010`。

### 10.1 一键安装(推荐)

bash cd deploy/scripts chmod +x install_casdoor.sh CASDOOR_PG_PASSWORD='强密码' ./install_casdoor.sh


脚本会:

1. 在本地 PostgreSQL 创建角色 `casdoor` 与数据库 `casdoor`(幂等);
2. 在 `~/docker/casdoor/` 生成 `docker-compose.yml` 与 `conf/app.conf`;
3. 首次以 `--createDatabase=true` 建表并写入初始数据;
4. `docker compose up -d` 启动容器(默认端口 `8010`)。

> 也可在 `setup.sh` 向导中勾选「安装 Casdoor」步骤,本地/远程均支持
> (远程会自动确保 Docker 已安装)。

可用环境变量:`CASDOOR_DIR`、`CASDOOR_PORT`、`CASDOOR_PG_USER`、
`CASDOOR_PG_PASSWORD`、`CASDOOR_DB_NAME`、`CASDOOR_ORIGIN`。

### 10.2 PostgreSQL 连接说明(容器 → 宿主机)

Casdoor 在容器内,需通过 `host.docker.internal`(compose 里已配 `host-gateway`)
访问宿主机 PostgreSQL。确保宿主 PostgreSQL 允许该连接:

bash

postgresql.conf

listen_addresses = '*' # 或至少包含 docker 网关地址

pg_hba.conf 增加一行(Docker 默认网段)

host casdoor casdoor 172.16.0.0/12 scram-sha-256

sudo systemctl reload postgresql


`app.conf` 中的数据源形如:

ini driverName = postgres dataSourceName = user=casdoor password=*** host=host.docker.internal port=5432 sslmode=disable dbname= dbName = casdoor


### 10.3 手动安装(等价步骤)

bash mkdir -p ~/docker/casdoor/conf && cd ~/docker/casdoor

docker-compose.yml

cat > docker-compose.yml <<'EOF' services: casdoor:

restart: always
image: casbin/casdoor:latest
entrypoint: /bin/sh -c './server'
ports:
  - "8010:8000"
environment:
  RUNNING_IN_DOCKER: "true"
extra_hosts:
  - "host.docker.internal:host-gateway"
volumes:
  - ./conf:/conf/

EOF

conf/app.conf 见 install_casdoor.sh 生成的模板

docker compose up -d


### 10.4 在 Casdoor 中配置组织与应用

首次访问 `http://<服务器>:8010`(或经反代 `/casdoor`),默认管理员 **admin / 123**
(登录后请立即改密)。然后:

1. **创建组织**:名称必须为 `organization_franklinwh_toolbox`
   (与前后端硬编码一致)。
2. **创建应用**:名称 `app-franklinwh-toolbox`,归属上面的组织。
   - 记录 **Client ID** 与 **Client Secret**;
   - 在 **Redirect URLs** 添加前端回调地址:
     - 生产:`https://<域名>/fwh-toolbox/casdoor/callback`
     - 测试:`https://<域名>/fwh-toolbox-test/casdoor/callback`
     (前端 `redirectPath = ${VITE_PUBLIC_PATH}/casdoor/callback`)
   - 勾选授权模式(Authorization Code)与需要的登录方式。
3. **获取应用证书**:在应用的 Cert 中查看/下载 X.509 证书(PEM),
   后端用它验证 JWT 签名。

### 10.5 前后端如何消费 Casdoor

- **前端**(`src/utils/casdoor/casdoor.ts`)硬编码:
  `serverUrl = /casdoor`、`clientId`、`appName = app-franklinwh-toolbox`、
  `organizationName = organization_franklinwh_toolbox`、
  `redirectPath = ${VITE_PUBLIC_PATH}/casdoor/callback`。
  如更换 Casdoor 应用,需同步修改此文件里的 `ClientId` 并重新构建前端。
- **后端**(`service/utils/casdoor/casdoor.go`)硬编码:
  `endpoint`、`clientId`、`clientSecret`、`certificate`、`organizationName`、
  `applicationName`。更换应用/证书后需修改这些常量并重新构建后端。

> ⚠️ 这些值当前写死在源码中而非 `config.env`。在新环境部署时,
> 若沿用同一套 Casdoor 应用与证书则无需改动;若新建 Casdoor 应用,
> 必须更新上述前后端源码常量并重新构建。

### 10.6 反向代理

Caddyfile 中加入(`/casdoor/*` → 容器映射端口 8010):

caddyfile 你的域名 {

# ... 其他 handle ...

redir /casdoor /casdoor/ 301
handle_path /casdoor/* {
    reverse_proxy localhost:8010
}

}


`handle_path` 会去掉 `/casdoor` 前缀,与 Casdoor 容器根路径匹配。

### 10.7 验证

bash docker compose -f ~/docker/casdoor/docker-compose.yml ps curl -sS http://127.0.0.1:8010/ | head # 返回 Casdoor 首页 sudo -u postgres psql -d casdoor -c "\dt" | head # 应有 casdoor 的数据表

经反代

curl -skS https://<域名>/casdoor/ | head


---

## 11. 启动、验证与排错

### 11.1 启动顺序

bash sudo systemctl status postgresql mongod redis-server minio --no-pager sudo systemctl restart fwh-toolbox-server sudo systemctl reload caddy


### 11.2 验证

bash

后端存活(本机)

curl -sS http://127.0.0.1:8301/swagger/index.html | head

任务面板

curl -sS http://127.0.0.1:8302/asynqmon/ | head

前端(经反代)

curl -skS https://你的域名/fwh-toolbox/ | head

PostgreSQL

sudo -u postgres psql -d fwh_toolbox_db -c "\dt alarm_snapshot.*"

MinIO bucket

mc ls fwhlocal/


### 11.3 日志

bash sudo journalctl -u fwh-toolbox-server -f

项目自带脚本

service/cmd/showTodayLog.sh service/cmd/showTodayErrorLog.sh


### 11.4 常见问题

- **后端启动 panic:database init failed** —— PostgreSQL 未就绪或 `POSTGRES_DSN`
  错误。确认库/角色已由 `init_pgsql.sql` 创建、密码一致、`sslmode=disable`。
- **Mongo ping error** —— `mongod` 未运行或 `MONGO_DSN` 主机端口错误。
- **前端 404 / 资源路径错乱** —— `VITE_PUBLIC_PATH` 必须为 `/fwh-toolbox/`,
  且反代路径一致。
- **API 请求 404** —— 检查 Caddy 的 `handle_path /fwh-toolbox/api/*` 是否正确
  去前缀并指向 8301。
- **MinIO 上传失败** —— bucket 不存在或 AK/SK 不匹配,用 `mc` 检查。

---

## 12. 附录:一键脚本清单

| 文件 | 作用 |
| --- | --- |
| `deploy/DEPLOYMENT.md` | 本部署文档 |
| `deploy/CHECKLIST.md` | 部署清单(需填写项 + 步骤,可勾选) |
| `deploy/scripts/setup.sh` | **交互式一键部署**(本地/远程,分步选择与填写) |
| `deploy/scripts/install_deps.sh` | 检测并(按需)安装 PostgreSQL/MongoDB/Redis/MinIO/mc/Docker(`DETECT_ONLY=1` 仅检测) |
| `deploy/scripts/install_casdoor.sh` | 以 Docker 部署 Casdoor + 建其 PostgreSQL 库/角色 |
| `deploy/sql/init_pgsql.sql` | PostgreSQL 从零建角色/库/schema/表(幂等) |
| `deploy/scripts/init_databases.sh` | 初始化本地数据库(PG 建表 + Mongo/Redis 检查 + MinIO 建桶) |
| `deploy/scripts/deploy.sh` | 构建并部署前端/后端(`all`/`frontend`/`backend`) |
| `deploy/config.env.example` | 后端配置模板 |
| `service/cmd/deploy_toolbox.sh` | 仅构建部署后端主程序(历史脚本) |
| `service/cmd/deploy_mcp.sh` | 仅构建部署 MCP(历史脚本) |

### 全新服务器最短部署路径

最省事:直接跑交互式向导 `./deploy/scripts/setup.sh`(勾选“安装依赖”“安装 Casdoor”
“初始化数据库”“部署后端/前端”即可)。以下为等价的分步命令:

bash

0) 克隆代码

git clone FranklinWH-ToolBox && cd FranklinWH-ToolBox

1) 检测/安装依赖(数据库引擎 + Docker)

cd deploy/scripts && chmod +x *.sh MINIO_ROOT_USER='admin' MINIO_ROOT_PASSWORD='强密码' \ ./install_deps.sh postgres mongo redis minio mc docker

2) 安装 Casdoor(认证服务,Docker)

CASDOOR_PG_PASSWORD='强密码' ./install_casdoor.sh

3) 初始化数据库(建库/建表/建桶)

PG_FWH_PASSWORD='强密码' MINIO_ROOT_USER='admin' MINIO_ROOT_PASSWORD='强密码' ./init_databases.sh

4) 配置后端(回到仓库根目录)

cd ../.. cp deploy/config.env.example service/config.env && vim service/config.env # 填入真实密钥 mkdir -p service/cert/pro service/cert/test # 放入 MQTT 证书

5) 部署前后端

./deploy/scripts/deploy.sh all

6) 配置并重载 Caddy(第 9 章)+ 在 Casdoor 建组织/应用(第 10 章),完成

```