chore: Docker 双服务 + Makefile/build.ps1 双进程目标 + README 架构更新
- Dockerfile 改为 Node 24 运行时:Vike 产物 + Go API 二进制共用镜像 - docker-compose 双容器:web(:3000 对外 SSR) + api(:3001 内部,持 /data 卷) - entrypoint 改用 gosu 降权(Debian 基础镜像),健康检查用 node fetch - Makefile/build.ps1:build 不再打包前端,新增 serve(本地双进程)与 web-build - README 同步双服务架构、端口/环境变量、部署与开发说明
This commit is contained in:
140
README.md
140
README.md
@@ -13,7 +13,7 @@
|
||||
[](LICENSE)
|
||||
[](https://hub.docker.com/r/hangzhang714128/jiang13-forum)
|
||||
[](go.mod)
|
||||
[](frontend/package.json)
|
||||
[](frontend/package.json)
|
||||
[](#)
|
||||
|
||||
[在线演示](https://bbs.iioio.com/) ·
|
||||
@@ -114,11 +114,12 @@
|
||||
|
||||
### 部署体验
|
||||
|
||||
- **单二进制** — `go:embed` 打包前端,无需再单独部署静态资源
|
||||
- **双服务架构** — Node(:3000 对外:SSR + 静态资源 + API 反代)+ Go(:3001 内部:纯 API),职责单一、可独立扩缩
|
||||
- **服务端渲染** — 首页 / 板块 / 帖子详情由 Vike SSR 真渲染,SEO 友好、首屏直出;其余页面 SPA 接管
|
||||
- **零依赖数据库** — SQLite 内建,数据目录由 `app.ini` 统一管理
|
||||
- **跨平台** — Windows / Linux / macOS 一键编译
|
||||
- **跨平台** — Windows / Linux / macOS 一键编译 Go API
|
||||
- **系统服务** — 内置 Linux systemd / Windows Service 注册
|
||||
- **Docker 单容器** — 多阶段镜像,挂载 `data/` 即可持久化
|
||||
- **Docker 双容器** — 同一镜像两种角色,`docker compose up` 一键起
|
||||
|
||||
---
|
||||
|
||||
@@ -126,7 +127,7 @@
|
||||
|
||||
### 1. 编译
|
||||
|
||||
**Windows(推荐):**
|
||||
Go API 二进制(不含前端,Windows):
|
||||
|
||||
```bat
|
||||
build.bat
|
||||
@@ -142,9 +143,21 @@ make build
|
||||
|
||||
**手动分步(全平台):**
|
||||
|
||||
```bash
|
||||
go build -trimpath -ldflags "-s -w" -o dist/jiang13 ./cmd/jiang13
|
||||
```
|
||||
|
||||
前端构建(Vike,产出 `frontend/dist/client` + `dist/server`):
|
||||
|
||||
```bash
|
||||
cd frontend && npm install && npm run build
|
||||
cd .. && go build -trimpath -ldflags "-s -w" -o dist/jiang13 ./cmd/jiang13
|
||||
```
|
||||
|
||||
本地生产模式一键起双服务(Node :3000 对外 + Go API :3001):
|
||||
|
||||
```bash
|
||||
make serve # Linux / macOS
|
||||
build.bat -Target serve # Windows
|
||||
```
|
||||
|
||||
跨平台编译:
|
||||
@@ -180,31 +193,38 @@ make compose-up
|
||||
|
||||
**拉取已构建镜像(Docker Hub):**
|
||||
|
||||
同一镜像两种角色,建议直接用 `docker-compose.yml`(已含完整配置):
|
||||
|
||||
```bash
|
||||
docker pull hangzhang714128/jiang13-forum:latest
|
||||
docker run -d --name jiang13 \
|
||||
-p 3000:3000 \
|
||||
-v jiang13-data:/data \
|
||||
--restart unless-stopped \
|
||||
hangzhang714128/jiang13-forum:latest
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
**数据持久化:** 容器内 `/data` 对应 SQLite、上传、日志与 JWT 密钥,与下方「数据目录」结构一致。可用 Docker volume 或绑定宿主机目录。镜像启动时会自动将 `/data` 卷属主修正为 uid `1000`(`jiang13` 用户),适配 1Panel 等面板挂载的目录。
|
||||
Compose 会启动两个容器:
|
||||
|
||||
| 容器 | 角色 | 端口 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `web` | Node 渲染服务器 | `3000` 对外 | Vike SSR + 静态资源 + API 反代(`GO_API_URL=http://api:3001`) |
|
||||
| `api` | Go API | `3001` 内部 | 纯 API 服务,持有 `/data` 数据卷 |
|
||||
|
||||
**数据持久化:** `api` 容器内 `/data` 对应 SQLite、上传、日志与 JWT 密钥,与下方「数据目录」结构一致。可用 Docker volume 或绑定宿主机目录。镜像启动时会自动将 `/data` 卷属主修正为 uid `1000`,适配 1Panel 等面板挂载的目录。
|
||||
|
||||
**若使用旧版镜像仍报 permission denied**,可在宿主机执行:`chown -R 1000:1000 /你的数据目录`
|
||||
|
||||
**可选环境变量(容器编排):**
|
||||
|
||||
| 变量 | 说明 |
|
||||
|------|------|
|
||||
| `JIANG13_HTTP_PORT` | HTTP 端口(默认 `3000`) |
|
||||
| `JIANG13_DATA` | 数据目录(默认 `/data`) |
|
||||
| `JIANG13_JWT_SECRET` | JWT 密钥(留空则自动生成并写入 `/data/.jwt_secret`) |
|
||||
| `JIANG13_CONFIG` | 配置文件路径 |
|
||||
| `JIANG13_WORK_PATH` | 工作目录 |
|
||||
| `JIANG13_COMMUNITY_HUB` | 维护者选项:设为 `1` 时本站作为社区枢纽收报。官方站 `bbs.iioio.com` 会按域名自动成为枢纽,无需此变量;仅非官网的枢纽镜像 / 预发需要显式开启(见 `app.ini.example`) |
|
||||
| 变量 | 容器 | 说明 |
|
||||
|------|------|------|
|
||||
| `GO_API_URL` | web | Go API 地址(默认 `http://127.0.0.1:3001`,Compose 中为 `http://api:3001`) |
|
||||
| `PORT` | web | Node 渲染服务器监听端口(默认 `3000`) |
|
||||
| `JIANG13_HTTP_PORT` | api | HTTP 端口(默认 `3000`,Compose 中为 `3001`) |
|
||||
| `JIANG13_DATA` | api | 数据目录(默认 `/data`) |
|
||||
| `JIANG13_JWT_SECRET` | api | JWT 密钥(留空则自动生成并写入 `/data/.jwt_secret`) |
|
||||
| `JIANG13_CONFIG` | api | 配置文件路径 |
|
||||
| `JIANG13_WORK_PATH` | api | 工作目录 |
|
||||
| `JIANG13_COMMUNITY_HUB` | api | 维护者选项:设为 `1` 时本站作为社区枢纽收报。官方站 `bbs.iioio.com` 会按域名自动成为枢纽,无需此变量;仅非官网的枢纽镜像 / 预发需要显式开启(见 `app.ini.example`) |
|
||||
|
||||
**健康检查:** `GET /health` 返回 `{"status":"ok"}`,供 Docker / 负载均衡探活。
|
||||
**健康检查:** Go API `GET /health`、Node 渲染服务器 `GET /healthz`,均返回 200,供 Docker / 负载均衡探活。
|
||||
|
||||
**发布镜像到 Docker Hub(手动):**
|
||||
|
||||
@@ -238,14 +258,16 @@ docker push hangzhang714128/jiang13-forum:latest
|
||||
|
||||
**1Panel 部署提示:**
|
||||
|
||||
1. 容器镜像填 `hangzhang714128/jiang13-forum:latest`
|
||||
2. 端口映射 `3000:3000`
|
||||
3. 挂载数据卷到容器内 `/data`(镜像会自动修正目录权限)
|
||||
1. 用 Compose 编排(`docker-compose.yml`)或手动创建两个容器:`api`(Go,内部 `3001`,挂载 `/data`)与 `web`(Node,映射 `3000:3000`)
|
||||
2. `web` 容器环境变量 `GO_API_URL` 指向 `api` 容器(如 `http://api:3001`)
|
||||
3. 数据卷只需挂在 `api` 容器的 `/data`(镜像会自动修正目录权限)
|
||||
4. 首次访问 `http://服务器IP:3000/register` 注册管理员
|
||||
|
||||
### 3. 直接启动(二进制)
|
||||
|
||||
不想自己编译时,从 [Gitea Releases](https://git.iioio.com/freefire/jiang13-forum/releases) 下载与 Docker 同版本号的文件即可:
|
||||
Go 二进制仅提供 API,完整站点需同时运行 Node 渲染服务器(构建前端后 `frontend/server/index.mjs`)。最简单的方式是用上面的 Docker Compose,或本地 `make serve` / `build.bat -Target serve` 一键起双进程。
|
||||
|
||||
如需手动部署二进制,从 [Gitea Releases](https://git.iioio.com/freefire/jiang13-forum/releases) 下载与 Docker 同版本号的文件:
|
||||
|
||||
| 文件 | 平台 |
|
||||
|------|------|
|
||||
@@ -254,35 +276,24 @@ docker push hangzhang714128/jiang13-forum:latest
|
||||
|
||||
当前 **1.1.7:** [Windows](https://git.iioio.com/freefire/jiang13-forum/releases/download/v1.1.7/jiang13-1.1.7-windows-amd64.exe) · [Linux](https://git.iioio.com/freefire/jiang13-forum/releases/download/v1.1.7/jiang13-1.1.7-linux-amd64)
|
||||
|
||||
把文件放到目标目录后直接运行(首次会在同目录生成 `app.ini`):
|
||||
两个进程一起跑(Go API :3001 + Node :3000 对外):
|
||||
|
||||
```bash
|
||||
# Windows
|
||||
.\jiang13-1.1.7-windows-amd64.exe
|
||||
# 或改名为 jiang13.exe 后:
|
||||
.\jiang13.exe
|
||||
# 1) 启动 Go API
|
||||
./jiang13 --port 3001 --data ./data
|
||||
|
||||
# Linux
|
||||
chmod +x jiang13-1.1.7-linux-amd64
|
||||
./jiang13-1.1.7-linux-amd64
|
||||
# 2) 另开终端,构建并启动 Node 渲染服务器
|
||||
cd frontend && npm install && npm run build
|
||||
PORT=3000 GO_API_URL=http://127.0.0.1:3001 npm start
|
||||
```
|
||||
|
||||
本地刚编译的产物在 `dist/`:
|
||||
Windows:
|
||||
|
||||
```bash
|
||||
# Windows
|
||||
.\dist\jiang13.exe
|
||||
|
||||
# Linux / macOS
|
||||
./dist/jiang13
|
||||
```
|
||||
|
||||
也可先复制示例配置再改端口 / 数据目录:
|
||||
|
||||
```bash
|
||||
cp app.ini.example /opt/jiang13/app.ini
|
||||
# 编辑 app.ini 后:
|
||||
./jiang13
|
||||
```powershell
|
||||
.\jiang13.exe --port 3001 --data .\data
|
||||
# 另开 PowerShell:
|
||||
cd frontend; npm install; npm run build
|
||||
$env:PORT = '3000'; $env:GO_API_URL = 'http://127.0.0.1:3001'; npm start
|
||||
```
|
||||
|
||||
### 4. 首次使用
|
||||
@@ -354,16 +365,17 @@ C:\jiang13\jiang13.exe --service start
|
||||
|
||||
| 层级 | 技术 |
|
||||
|------|------|
|
||||
| **后端** | Go 1.26 · Gin · GORM · SQLite |
|
||||
| **前端** | React 18 · TipTap · Radix UI · Tailwind CSS · TanStack Virtual |
|
||||
| **构建** | Vite → `go:embed` 内嵌 SPA,单二进制发布 |
|
||||
| **后端** | Go 1.26 · Gin · GORM · SQLite(纯 API 服务) |
|
||||
| **前端** | React 19 · Vike SSR · react-router · TipTap · Radix UI · Tailwind CSS · TanStack Virtual |
|
||||
| **构建** | Vite 8(Rolldown)双构建:`dist/client` 静态资源 + `dist/server` SSR 入口 |
|
||||
| **渲染** | Node 24 · Express + Vike `renderPage`(:3000 对外,API 反代至 Go :3001) |
|
||||
| **认证** | bcrypt · JWT Cookie · 可选 OIDC Provider |
|
||||
|
||||
---
|
||||
|
||||
## 前端开发
|
||||
|
||||
日常改前端不需要重新完整构建,Vite 支持秒级热更新(HMR,热模块替换):
|
||||
日常改前端不需要重新完整构建,Vike dev 支持秒级热更新(HMR,热模块替换):
|
||||
|
||||
```bat
|
||||
build.bat -Target dev
|
||||
@@ -373,16 +385,17 @@ build.bat -Target dev
|
||||
make dev
|
||||
```
|
||||
|
||||
浏览器访问 `http://localhost:5173`,API 自动代理到 `http://localhost:3000`。
|
||||
浏览器访问 `http://localhost:5173`,API 自动代理到 `http://localhost:3000`。首页 / 板块 / 帖子详情在 dev 下同样走 SSR(`vike dev`),与生产行为一致;其余页面为 SPA 壳。
|
||||
|
||||
开发后端与 `dist/jiang13` 共用数据目录 `dist/data`(SQLite、上传、JWT 密钥等),避免 dev 与 dist 运行数据不一致。
|
||||
|
||||
**何时需要完整构建:**
|
||||
|
||||
- 修改 Go 代码或要发布单二进制 → `build.bat` / `make build`
|
||||
- 修改 Go 代码 → `build.bat` / `make build`(仅编译 Go API)
|
||||
- 验证生产 SSR / 发布部署 → `make serve`(构建前端 + 双进程起本地产)
|
||||
- 更新 README 界面截图 → 见下方「更新截图」
|
||||
|
||||
> 直接访问 `:3000` 看到的是上次 build 嵌入的前端;开发时请用 `:5173`。
|
||||
> 开发时请访问 `:5173`;`:3000` 只有在生产模式(Node 渲染服务器)下才有页面。
|
||||
|
||||
### 更新截图
|
||||
|
||||
@@ -412,17 +425,20 @@ jiang13-forum/
|
||||
├── cmd/jiang13/ # 程序入口(含系统服务注册)
|
||||
├── config/ # app.ini 与命令行配置
|
||||
├── app.ini.example # 配置文件示例
|
||||
├── Dockerfile # 多阶段 Docker 构建
|
||||
├── docker-compose.yml # 单容器 Compose 部署
|
||||
├── docker-entrypoint.sh # 容器启动脚本(修正 /data 卷权限)
|
||||
├── Dockerfile # 多阶段构建(前端 + Go API 共用镜像,双容器运行)
|
||||
├── docker-compose.yml # 双容器 Compose 部署(web :3000 + api :3001)
|
||||
├── docker-entrypoint.sh # api 容器启动脚本(修正 /data 卷权限)
|
||||
├── .dockerignore
|
||||
├── model/ # GORM 模型与数据库迁移
|
||||
├── service/ # 业务逻辑
|
||||
├── handler/ # HTTP 处理器(前台 + 后台)
|
||||
├── handler/ # HTTP 处理器(API + /api/home-boot SSR 聚合端点)
|
||||
├── middleware/ # JWT 鉴权等
|
||||
├── router/ # 路由注册
|
||||
├── embed_static/ # go:embed 内嵌的 SPA
|
||||
├── frontend/ # React 源码(Vite 构建)
|
||||
├── router/ # 路由注册(仅 API)
|
||||
├── frontend/
|
||||
│ ├── pages/ # Vike 页面(feed=SSR 白名单 / spa=catch-all 壳 / _error)
|
||||
│ ├── renderer/ # Vike 双端渲染入口(onRenderHtml / onRenderClient)
|
||||
│ ├── server/ # Node 渲染服务器(express + renderPage + API 反代)
|
||||
│ └── src/ # React 源码(含 src/ssr 服务端取数与作用域管理)
|
||||
├── docs/screenshots/ # README 界面截图
|
||||
├── ROADMAP.md # 路线图与已知问题
|
||||
└── scripts/ # 开发辅助脚本(含截图)
|
||||
|
||||
Reference in New Issue
Block a user