[优化] go 引用调整

This commit is contained in:
ryan
2026-06-06 10:26:20 +08:00
parent ee1110b752
commit 3cfefb4367
552 changed files with 1642 additions and 2185 deletions
+1 -1
View File
@@ -75,7 +75,7 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
file: ./openflare_agent/Dockerfile
file: ./openflare-agent/Dockerfile
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
build-args: |
+1 -1
View File
@@ -75,7 +75,7 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
file: ./openflare_relay/Dockerfile
file: ./openflare-relay/Dockerfile
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
build-args: |
+2 -2
View File
@@ -74,8 +74,8 @@ jobs:
id: build
uses: docker/build-push-action@v7
with:
context: ./openflare_server
file: ./openflare_server/Dockerfile
context: .
file: ./openflare-server/Dockerfile
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
build-args: |
+30 -30
View File
@@ -1,30 +1,30 @@
name: Build GitHub Pages
on:
workflow_dispatch:
inputs:
name:
description: 'Reason'
required: false
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly.
with:
persist-credentials: false
- name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
env:
CI: ""
run: |
cd openflare_server/web
corepack enable
pnpm install --frozen-lockfile
pnpm build
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: openflare_server/web/build # The folder the action should deploy.
name: Build GitHub Pages
on:
workflow_dispatch:
inputs:
name:
description: 'Reason'
required: false
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly.
with:
persist-credentials: false
- name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
env:
CI: ""
run: |
cd openflare-server/web
corepack enable
pnpm install --frozen-lockfile
pnpm build
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: openflare-server/web/build # The folder the action should deploy.
+14 -14
View File
@@ -79,7 +79,7 @@ jobs:
CI: ""
VERSION: ${{ needs.prepare.outputs.version }}
run: |
cd openflare_server/web
cd openflare-server/web
corepack enable
pnpm install --frozen-lockfile
NEXT_PUBLIC_APP_VERSION="$VERSION" pnpm build
@@ -88,7 +88,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: frontend-build
path: openflare_server/web/build
path: openflare-server/web/build
retention-days: 1
build-binaries:
@@ -127,15 +127,15 @@ jobs:
uses: actions/download-artifact@v4
with:
name: frontend-build
path: openflare_server/web/build
path: openflare-server/web/build
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: openflare_server/go.mod
go-version-file: go.mod
- name: Build Server
working-directory: openflare_server
working-directory: openflare-server
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
@@ -145,7 +145,7 @@ jobs:
run: |
go mod download
mkdir -p ../dist
go build -trimpath -ldflags "-s -w -X 'openflare/common.Version=$VERSION'" -o "../dist/$ASSET_NAME" .
go build -trimpath -ldflags "-s -w -X 'github.com/rain-kl/openflare/openflare-server/common.Version=$VERSION'" -o "../dist/$ASSET_NAME" .
- name: Upload Binary Artifact
uses: actions/upload-artifact@v4
@@ -184,10 +184,10 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: openflare_agent/go.mod
go-version-file: go.mod
- name: Build Agent
working-directory: openflare_agent
working-directory: openflare-agent
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
@@ -197,7 +197,7 @@ jobs:
run: |
go mod download
mkdir -p ../dist
go build -trimpath -ldflags "-s -w -X 'openflare-agent/internal/config.Version=$VERSION'" -o "../dist/$ASSET_NAME" ./cmd/agent
go build -trimpath -ldflags "-s -w -X 'github.com/rain-kl/openflare/openflare-agent/internal/config.Version=$VERSION'" -o "../dist/$ASSET_NAME" ./cmd/agent
(cd ../dist && sha256sum "$ASSET_NAME" > "$ASSET_NAME.sha256")
- name: Upload Agent Artifact
@@ -239,10 +239,10 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: openflare_relay/go.mod
go-version-file: go.mod
- name: Build Relay
working-directory: openflare_relay
working-directory: openflare-relay
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
@@ -252,7 +252,7 @@ jobs:
run: |
go mod download
mkdir -p ../dist
go build -trimpath -ldflags "-s -w -X 'openflare-relay/internal/config.Version=$VERSION'" -o "../dist/$ASSET_NAME" ./cmd/relay
go build -trimpath -ldflags "-s -w -X 'github.com/rain-kl/openflare/openflare-relay/internal/config.Version=$VERSION'" -o "../dist/$ASSET_NAME" ./cmd/relay
(cd ../dist && sha256sum "$ASSET_NAME" > "$ASSET_NAME.sha256")
- name: Upload Relay Artifact
@@ -294,7 +294,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: openflared/go.mod
go-version-file: go.mod
- name: Build Flared
working-directory: openflared
@@ -307,7 +307,7 @@ jobs:
run: |
go mod download
mkdir -p ../dist
go build -trimpath -ldflags "-s -w -X 'openflare-flared/internal/config.Version=$VERSION'" -o "../dist/$ASSET_NAME" ./cmd/flared
go build -trimpath -ldflags "-s -w -X 'github.com/rain-kl/openflare/openflared/internal/config.Version=$VERSION'" -o "../dist/$ASSET_NAME" ./cmd/flared
(cd ../dist && sha256sum "$ASSET_NAME" > "$ASSET_NAME.sha256")
- name: Upload Flared Artifact
+3 -1
View File
@@ -50,4 +50,6 @@ go.work.sum
*-source
*-source.*
.codex*
.codex*
/bin/
+5 -3
View File
@@ -2,7 +2,7 @@ services:
agent:
build:
context: .
dockerfile: openflare_agent/Dockerfile
dockerfile: openflare-agent/Dockerfile
container_name: openflare-agent
restart: unless-stopped
@@ -12,7 +12,7 @@ services:
- "127.0.0.1:18081:18081"
volumes:
- ./openflare_agent/data/:/data
- ./openflare-agent/data/:/data
environment:
OPENFLARE_SERVER_URL: "http://host.docker.internal:3000"
@@ -25,10 +25,12 @@ services:
relay:
build:
context: .
dockerfile: openflare_relay/Dockerfile
dockerfile: openflare-relay/Dockerfile
container_name: openflare-relay
network_mode: host
restart: unless-stopped
volumes:
- ./openflare-relay/data/:/app/data
environment:
OPENFLARE_SERVER_URL: http://host.docker.internal:3000
OPENFLARE_DISCOVERY_TOKEN: 85464eeb72c49abc430569d6b9c77f78
+5
View File
@@ -26,6 +26,11 @@ sidebar: false
### 变更
- 重构 Go 包依赖结构为统一模块(Monorepo),模块命名为 `github.com/rain-kl/openflare`
- 移除各子目录下独立的 `go.mod`/`go.sum` 文件,统一由根目录 `go.mod` 进行全局依赖管理与依赖版本锁定
- 替换全仓库 Go 源文件中的内部引用路径,由本地相对路径迁移为标准 GitHub 绝对导入路径
- 适配 Docker 镜像构建,所有组件镜像的 Dockerfile 调整为基于根目录的上下文编译
- 更新 GitHub release 自动化发布流水线,适配全新 monorepo 包结构与符号信息注入路径
---
+2 -2
View File
@@ -126,7 +126,7 @@ journalctl -u openflare-agent -f
源码运行:
```bash
cd openflare_agent
cd openflare-agent
export LOG_LEVEL='info'
go run ./cmd/agent -config /path/to/agent.json
```
@@ -134,7 +134,7 @@ go run ./cmd/agent -config /path/to/agent.json
编译后二进制运行:
```bash
cd openflare_agent
cd openflare-agent
go build -o openflare-agent ./cmd/agent
export LOG_LEVEL='info'
./openflare-agent -config /path/to/agent.json
+4 -4
View File
@@ -134,7 +134,7 @@ docker compose logs -f openflare
先构建管理端前端:
```bash
cd openflare_server/web
cd openflare-server/web
corepack enable
pnpm install
pnpm build
@@ -143,7 +143,7 @@ pnpm build
再启动 Server:
```bash
cd openflare_server
cd openflare-server
export JWT_SECRET='replace-with-a-long-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
@@ -230,7 +230,7 @@ journalctl -u openflare-agent -f
源码运行:
```bash
cd openflare_agent
cd openflare-agent
export LOG_LEVEL='info'
go run ./cmd/agent -config /path/to/agent.json
```
@@ -238,7 +238,7 @@ go run ./cmd/agent -config /path/to/agent.json
编译后二进制运行:
```bash
cd openflare_agent
cd openflare-agent
go build -o openflare-agent ./cmd/agent
export LOG_LEVEL='info'
./openflare-agent -config /path/to/agent.json
+3 -3
View File
@@ -1,6 +1,6 @@
# 部署 Relay (Tunnel 中继)
你会学到:TunnelRelay 节点的职责、`openflare_relay` 的配置项与环境变量、使用 Docker 运行 Relay 的方法,以及如何通过源码手动构建并部署 Relay。
你会学到:TunnelRelay 节点的职责、`openflare-relay` 的配置项与环境变量、使用 Docker 运行 Relay 的方法,以及如何通过源码手动构建并部署 Relay。
在 OpenFlare 的内网穿透体系中,**TunnelRelay 节点** 扮演着关键的角色。它与普通的边缘节点(Edge Node)不同,除了运行传统的 Agent(托管 OpenResty 进行 HTTPS/WAF 处理)外,还同机运行了 **Relay (frps 隧道管理器)** 服务,负责监听内网客户端(OpenFlared)的隧道连接并进行流量中继。
@@ -21,7 +21,7 @@
## 配置文件与环境变量
`openflare_relay` 启动时默认会读取当前目录下的 `relay.json`。同时也完全支持通过环境变量进行覆盖。
`openflare-relay` 启动时默认会读取当前目录下的 `relay.json`。同时也完全支持通过环境变量进行覆盖。
### 配置字段详情
@@ -68,7 +68,7 @@ docker run -d --name openflare-relay --restart unless-stopped \
### 1. 编译二进制
```bash
cd openflare_relay
cd openflare-relay
go build -o openflare-relay ./cmd/relay
```
+4 -4
View File
@@ -17,10 +17,10 @@ OpenFlare Server 是 Gin + GORM 单体控制面,负责管理端 UI、管理 AP
## 构建管理端前端
Go Server 会托管 `openflare_server/web/build` 中的静态产物。源码启动前先构建前端:
Go Server 会托管 `openflare-server/web/build` 中的静态产物。源码启动前先构建前端:
```bash
cd openflare_server/web
cd openflare-server/web
corepack enable
pnpm install
pnpm build
@@ -37,7 +37,7 @@ pnpm test
## 使用 SQLite 启动
```bash
cd openflare_server
cd openflare-server
export JWT_SECRET='replace-with-a-long-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
@@ -53,7 +53,7 @@ http://localhost:3000
## 使用 PostgreSQL 启动
```bash
cd openflare_server
cd openflare-server
export JWT_SECRET='replace-with-a-long-random-string'
export DSN='postgres://openflare:secret@127.0.0.1:5432/openflare?sslmode=disable'
export LOG_LEVEL='info'
+3 -3
View File
@@ -77,7 +77,7 @@ OpenResty (Agent, TLS/WAF)
## 组件架构与分工
### 1. Server (控制面)
`openflare_server` 是 Go 编写的单体控制面:
`openflare-server` 是 Go 编写的单体控制面:
* 提供管理端 REST API,通过 `OPENFLARE_TOKEN` 请求头鉴权。
* 包含配置编译器(Compiler),将数据库中的规则、证书与全局参数统一编译为不可变的配置快照及 OpenResty 物理配置文件文本。
* 存储 Pages 部署 ZIP 包于本地 Artifacts 目录,并向 Agent 提供受控的下载接口。
@@ -85,7 +85,7 @@ OpenResty (Agent, TLS/WAF)
* *详细设计请参阅:[Agent 与发布模型设计](./agent-design.md) 以及 [Uptime Kuma 监控同步设计](./kuma-design.md)*
### 2. Agent (配置落地端)
`openflare_agent` 是运行在节点本地的守护进程:
`openflare-agent` 是运行在节点本地的守护进程:
* 启动后维持与控制面的周期性心跳,并通过可选的 WebSocket 接收实时的配置发布广播。
* 负责拉取最新激活版本的配置文件及证书,写入本地目录,并通过 `openresty -t` 执行安全校验后平滑重载 (`reload`)。
* 在本地处理 Pages 部署包的下载、SHA-256 校验与解压缩切换。
@@ -99,7 +99,7 @@ OpenResty (Agent, TLS/WAF)
### 4. Relay 与 OpenFlared (穿透组件)
扩展数据面反穿透能力:
* `openflare_relay` 守护本地 `frps`,接受 Server 的配置派发,自动更新中继端口。
* `openflare-relay` 守护本地 `frps`,接受 Server 的配置派发,自动更新中继端口。
* `openflared` 在内网守护一组 `frpc` 客户端进程,实现多中继就近建连与高可用容灾。
* *详细设计请参阅:[内网穿透隧道设计文档](./tunnel-design.md)*
+8 -8
View File
@@ -66,16 +66,16 @@ OpenFlare 适合需要统一管理多台 OpenResty 代理节点的团队,具
| 路径 | 职责 |
| ---------------------- | ---------------------------------------------------- |
| `openflare_server` | Gin + GORM + SQLite/PostgreSQL 单体控制面 |
| `openflare_server/web` | Next.js 15 App Router 管理端前端,由 Go Server 托管 |
| `openflare_agent` | Go 单体 Agent,运行在节点侧 |
| `openflare_relay` | Tunnel 中继代理,运行在公网边缘管理 frps 进程 |
| `openflare-server` | Gin + GORM + SQLite/PostgreSQL 单体控制面 |
| `openflare-server/web` | Next.js 15 App Router 管理端前端,由 Go Server 托管 |
| `openflare-agent` | Go 单体 Agent,运行在节点侧 |
| `openflare-relay` | Tunnel 中继代理,运行在公网边缘管理 frps 进程 |
| `openflared` | Tunnel 客户端,运行在内网服务器侧管理 frpc 进程 |
| `scripts` | 安装、自更新等系统辅助脚本 |
| `docs` | VitePress 文档站、设计基线、开发规范、部署与配置文档 |
| `docs/en` | 英文版文档 |
### 1. Server 分层 (`openflare_server/`)
### 1. Server 分层 (`openflare-server/`)
| 目录 | 职责 |
| ------------- | ------------------------------------------------ |
@@ -93,7 +93,7 @@ OpenFlare 适合需要统一管理多台 OpenResty 代理节点的团队,具
| `docs/` | API 文档(Swagger) |
| `data/` | 静态数据(如 GeoIP 数据库) |
### 2. Agent 模块 (`openflare_agent/`)
### 2. Agent 模块 (`openflare-agent/`)
| 目录/模块 | 职责 |
| ----------------------------- | -------------------------------------------- |
@@ -113,7 +113,7 @@ OpenFlare 适合需要统一管理多台 OpenResty 代理节点的团队,具
| `internal/geoipupdate/` | GeoIP 数据更新 |
| `internal/agent/` | 核心 Agent 逻辑与生命周期 |
### 3. Frontend 分层 (`openflare_server/web/`)
### 3. Frontend 分层 (`openflare-server/web/`)
| 目录 | 职责 |
| ------------- | -------------------------------------------- |
@@ -128,7 +128,7 @@ OpenFlare 适合需要统一管理多台 OpenResty 代理节点的团队,具
| `scripts/` | 构建和部署相关脚本 |
| `public/` | 静态资源 |
### 4. Relay 模块 (`openflare_relay/`)
### 4. Relay 模块 (`openflare-relay/`)
| 模块 | 职责 |
| ---------------- | ------------------------------------------------ |
+1 -1
View File
@@ -39,7 +39,7 @@ graph TD
OpenResty -->|2. 转发 API 代理| BackEnd[4. 后端 API 服务]
%% 控制流与心跳
Server[OpenFlare Server 控制面] <-->|Agent API / Heartbeat| Agent[openflare_agent 进程]
Server[OpenFlare Server 控制面] <-->|Agent API / Heartbeat| Agent[openflare-agent 进程]
Server -.->|5. 存储 ZIP 部署包| LocalStore[(Server 本地存储)]
Agent -->|1. 发现新版本| Server
+5 -5
View File
@@ -40,7 +40,7 @@ graph TD
FlaredFrpc -->|转发本地请求| LocalOrigin[5. 内网源站 192.168.x.x]
%% 控制流与心跳
Server[OpenFlare Server 控制面] <-->|Relay API / Heartbeat| RelayManager[openflare_relay 进程]
Server[OpenFlare Server 控制面] <-->|Relay API / Heartbeat| RelayManager[openflare-relay 进程]
Server <-->|Client API / Heartbeat| ClientManager[openflared 进程]
RelayManager -.->|管控进程及配置| RelayFrps
@@ -51,14 +51,14 @@ graph TD
style Server fill:#f96,stroke:#333,stroke-width:2px
```
* **控制面(Control Plane)**:Server 维护数据库状态;中继节点上的 `openflare_relay` 进程与内网服务器上的 `openflared` 进程通过 HTTP 心跳与 WebSocket 长通道同步隧道配置。
* **数据面(Data Plane)**:公网流量首先进入公网边缘的 Agent (OpenResty),在此完成 HTTPS 握手、TLS 终止和 WAF 过滤,接着通过 `proxy_pass` 转发到同机部署的 `openflare_relay (frps)`。`frps` 再将请求封包通过与内网 `openflared (frpc)` 建立的持久隧道传输过去,最后由 `frpc` 拆包并分发给内网实际的源站服务。
* **控制面(Control Plane)**:Server 维护数据库状态;中继节点上的 `openflare-relay` 进程与内网服务器上的 `openflared` 进程通过 HTTP 心跳与 WebSocket 长通道同步隧道配置。
* **数据面(Data Plane)**:公网流量首先进入公网边缘的 Agent (OpenResty),在此完成 HTTPS 握手、TLS 终止和 WAF 过滤,接着通过 `proxy_pass` 转发到同机部署的 `openflare-relay (frps)`。`frps` 再将请求封包通过与内网 `openflared (frpc)` 建立的持久隧道传输过去,最后由 `frpc` 拆包并分发给内网实际的源站服务。
---
## Relay (中继端) 设计
`openflare_relay` 是部署在公网边缘的中继管理器,运行在 `tunnel_relay` 类型的节点上。
`openflare-relay` 是部署在公网边缘的中继管理器,运行在 `tunnel_relay` 类型的节点上。
### 1. 核心架构与逻辑
* **进程守护**:Relay 进程内部持有 `frps` 二进制,通过 `exec.Command` 拉起 `frps -c frps.toml` 子进程,并启动 goroutine 异步监听其退出状态。如果发现 `frps` 异常退出,会结合退避机制自动拉起。
@@ -98,7 +98,7 @@ graph TD
+-------------------------------------------+-------------------------------------------+
| |
v (中继端) v (内网客户端)
openflare_relay 心跳检测到 frps 端口/Token 变化 openflared 心跳检测到 tunnel_version 发生变更
openflare-relay 心跳检测到 frps 端口/Token 变化 openflared 心跳检测到 tunnel_version 发生变更
重新渲染本地 frps.toml 请求拉取最新代理映射包
Kill 并重新拉起 frps 进程 重新渲染 frpc_<relay_id>.toml
上报健康状态为 healthy 对有变更的 Relay 进程执行重启与配置热重载
+2 -2
View File
@@ -127,7 +127,7 @@ Manual execution:
Running from source:
```bash
cd openflare_agent
cd openflare-agent
export LOG_LEVEL='info'
go run ./cmd/agent -config /path/to/agent.json
```
@@ -135,7 +135,7 @@ go run ./cmd/agent -config /path/to/agent.json
Running compiled binary:
```bash
cd openflare_agent
cd openflare-agent
go build -o openflare-agent ./cmd/agent
export LOG_LEVEL='info'
./openflare-agent -config /path/to/agent.json
+4 -4
View File
@@ -134,7 +134,7 @@ Access `http://localhost:3000` for the first time, using the default credentials
First, build the admin frontend:
```bash
cd openflare_server/web
cd openflare-server/web
corepack enable
pnpm install
pnpm build
@@ -143,7 +143,7 @@ pnpm build
Then, launch the Server:
```bash
cd openflare_server
cd openflare-server
export SESSION_SECRET='replace-with-a-long-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
@@ -230,7 +230,7 @@ journalctl -u openflare-agent -f
Running from source:
```bash
cd openflare_agent
cd openflare-agent
export LOG_LEVEL='info'
go run ./cmd/agent -config /path/to/agent.json
```
@@ -238,7 +238,7 @@ go run ./cmd/agent -config /path/to/agent.json
Running compiled binary:
```bash
cd openflare_agent
cd openflare-agent
go build -o openflare-agent ./cmd/agent
export LOG_LEVEL='info'
./openflare-agent -config /path/to/agent.json
+3 -3
View File
@@ -1,6 +1,6 @@
# Deploy Relay (Tunnel Relay)
You will learn: The responsibilities of a TunnelRelay node, `openflare_relay` configuration parameters and environment variables, how to run the Relay via Docker, and how to build and deploy the Relay from source manually.
You will learn: The responsibilities of a TunnelRelay node, `openflare-relay` configuration parameters and environment variables, how to run the Relay via Docker, and how to build and deploy the Relay from source manually.
In the OpenFlare intranet penetration architecture, the **TunnelRelay node** plays a key role. Unlike standard Edge Nodes, in addition to running the traditional Agent (managing OpenResty for HTTPS/WAF processing), it co-locates the **Relay (frps tunnel manager)** service, responsible for listening to intranet client (OpenFlared) tunnel connections and relaying traffic.
@@ -21,7 +21,7 @@ Before deploying a TunnelRelay node, ensure:
## Configuration & Environment Variables
`openflare_relay` reads `relay.json` in the working directory by default on startup. Overriding options via environment variables is fully supported.
`openflare-relay` reads `relay.json` in the working directory by default on startup. Overriding options via environment variables is fully supported.
### Configuration Fields Details
@@ -68,7 +68,7 @@ If you prefer to run the Relay directly on a physical host or VM:
### 1. Compile the Binary
```bash
cd openflare_relay
cd openflare-relay
go build -o openflare-relay ./cmd/relay
```
+4 -4
View File
@@ -17,10 +17,10 @@ In production environments, we highly recommend explicitly configuring `SESSION_
## Build the Admin Frontend
The Go Server hosts static assets located in `openflare_server/web/build`. Before starting the Server from source, build the frontend:
The Go Server hosts static assets located in `openflare-server/web/build`. Before starting the Server from source, build the frontend:
```bash
cd openflare_server/web
cd openflare-server/web
corepack enable
pnpm install
pnpm build
@@ -37,7 +37,7 @@ pnpm test
## Start with SQLite
```bash
cd openflare_server
cd openflare-server
export SESSION_SECRET='replace-with-a-long-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
@@ -53,7 +53,7 @@ http://localhost:3000
## Start with PostgreSQL
```bash
cd openflare_server
cd openflare-server
export SESSION_SECRET='replace-with-a-long-random-string'
export DSN='postgres://openflare:secret@127.0.0.1:5432/openflare?sslmode=disable'
export LOG_LEVEL='info'
+4 -4
View File
@@ -61,19 +61,19 @@ Internal Service (192.168.x.x)
## Server
`openflare_server` is the single-control-plane monolith:
`openflare-server` is the single-control-plane monolith:
* Gin provides the HTTP services.
* GORM accesses SQLite or PostgreSQL.
* The existing login system provides Admin Session management.
* Authentication sources support GitHub OAuth and standard OIDC logins with external account binding.
* The Go Server hosts the `openflare_server/web` static build assets.
* The Go Server hosts the `openflare-server/web` static build assets.
The Server does not directly SSH to nodes, nor does it modify node files online. It only stores control plane state, generates complete configuration versions, and lets nodes actively pull them via the Agent API.
## Agent
`openflare_agent` is a Go monolithic application:
`openflare-agent` is a Go monolithic application:
* Runs as a single binary on the node side.
* Reads or generates local node information on startup.
@@ -88,7 +88,7 @@ The node IP is maintained by default through Agent registration and heartbeat re
## Frontend
`openflare_server/web` is the official Next.js-based frontend:
`openflare-server/web` is the official Next.js-based frontend:
* Next.js 15 App Router.
* React 19.
+11 -11
View File
@@ -22,7 +22,7 @@ For details on the physical directory structure and responsibilities of each mod
## Initializing Frontend Dependencies
```bash
cd openflare_server/web
cd openflare-server/web
corepack enable
pnpm install
```
@@ -38,7 +38,7 @@ pnpm build
SQLite Mode:
```bash
cd openflare_server
cd openflare-server
export SESSION_SECRET='dev-session-secret'
export SQLITE_PATH='./openflare-dev.db'
export LOG_LEVEL='debug'
@@ -48,7 +48,7 @@ go run .
PostgreSQL Mode:
```bash
cd openflare_server
cd openflare-server
export SESSION_SECRET='dev-session-secret'
export DSN='postgres://openflare:secret@127.0.0.1:5432/openflare?sslmode=disable'
export LOG_LEVEL='debug'
@@ -68,7 +68,7 @@ The default credentials are `root` / `123456`.
The frontend dev server listens to port `3001` by default and proxies requests to the backend via `NEXT_DEV_BACKEND_URL`:
```bash
cd openflare_server/web
cd openflare-server/web
export NEXT_DEV_BACKEND_URL='http://127.0.0.1:3000'
pnpm dev
```
@@ -96,7 +96,7 @@ Create a local `agent.json`:
Run:
```bash
cd openflare_agent
cd openflare-agent
export LOG_LEVEL='debug'
go run ./cmd/agent -config ./agent.json
```
@@ -108,21 +108,21 @@ If `openresty_path` is not configured, the Agent calls `openresty` by default. F
Server:
```bash
cd openflare_server
cd openflare-server
GOCACHE=/tmp/openflare-go-cache go test ./...
```
Agent:
```bash
cd openflare_agent
cd openflare-agent
GOCACHE=/tmp/openflare-go-cache go test ./...
```
Frontend:
```bash
cd openflare_server/web
cd openflare-server/web
pnpm lint
pnpm typecheck
pnpm test
@@ -141,21 +141,21 @@ pnpm build
Admin static assets:
```bash
cd openflare_server/web
cd openflare-server/web
pnpm build
```
Server binary:
```bash
cd openflare_server
cd openflare-server
go build -o openflare-server .
```
Agent binary:
```bash
cd openflare_agent
cd openflare-agent
go build -o openflare-agent ./cmd/agent
```
+4 -4
View File
@@ -4,10 +4,10 @@ You will learn: The responsibilities of Server, Agent, Frontend, scripts, and do
| Path | Responsibility |
| --- | --- |
| `openflare_server` | Gin + GORM + SQLite/PostgreSQL single monolithic control plane |
| `openflare_server/web` | Next.js 15 App Router Admin Frontend, hosted by Go Server |
| `openflare_agent` | Go monolithic Agent running on the node side |
| `openflare_relay` | Tunnel relay daemon running on public edges, managing frps processes |
| `openflare-server` | Gin + GORM + SQLite/PostgreSQL single monolithic control plane |
| `openflare-server/web` | Next.js 15 App Router Admin Frontend, hosted by Go Server |
| `openflare-agent` | Go monolithic Agent running on the node side |
| `openflare-relay` | Tunnel relay daemon running on public edges, managing frps processes |
| `openflared` | Tunnel client running on intranet servers, managing frpc processes |
| `scripts` | System helper scripts for installation, self-updating, etc. |
| `docs` | VitePress documentation website, design baselines, specifications, and configurations |
+5 -5
View File
@@ -40,7 +40,7 @@ graph TD
FlaredFrpc -->|Forward Local Request| LocalOrigin[5. Intranet Origin 192.168.x.x]
%% Control Flow & Heartbeats
Server[OpenFlare Server Control Plane] <-->|Relay API / Heartbeat| RelayManager[openflare_relay process]
Server[OpenFlare Server Control Plane] <-->|Relay API / Heartbeat| RelayManager[openflare-relay process]
Server <-->|Client API / Heartbeat| ClientManager[openflared process]
RelayManager -.->|Control Process & Config| RelayFrps
@@ -51,14 +51,14 @@ graph TD
style Server fill:#f96,stroke:#333,stroke-width:2px
```
* **Control Plane**: The Server maintains the database state. The `openflare_relay` process on relay nodes and the `openflared` process on intranet servers synchronize tunnel configurations via HTTP heartbeats and long-lived WebSocket connections.
* **Data Plane**: Public traffic enters the public edge Agent (OpenResty), where the TLS handshake, HTTPS termination, and WAF filtering are executed. It is then forwarded via `proxy_pass` to the co-located `openflare_relay (frps)` on the loopback address. `frps` encapsulates the HTTP requests into the encrypted TCP tunnel and sends them down to the intranet `openflared (frpc)`. Finally, `frpc` unpacks the requests and forwards them to the actual intranet origin service.
* **Control Plane**: The Server maintains the database state. The `openflare-relay` process on relay nodes and the `openflared` process on intranet servers synchronize tunnel configurations via HTTP heartbeats and long-lived WebSocket connections.
* **Data Plane**: Public traffic enters the public edge Agent (OpenResty), where the TLS handshake, HTTPS termination, and WAF filtering are executed. It is then forwarded via `proxy_pass` to the co-located `openflare-relay (frps)` on the loopback address. `frps` encapsulates the HTTP requests into the encrypted TCP tunnel and sends them down to the intranet `openflared (frpc)`. Finally, `frpc` unpacks the requests and forwards them to the actual intranet origin service.
---
## Relay (Server-side) Design
`openflare_relay` is a relay manager deployed on the public edge, running on nodes of type `tunnel_relay`.
`openflare-relay` is a relay manager deployed on the public edge, running on nodes of type `tunnel_relay`.
### 1. Core Architecture & Logic
* **Process Daemon**: The Relay process embeds the `frps` binary, spawning the `frps -c frps.toml` subprocess via `exec.Command` and using goroutines to asynchronously listen to its exit status. If `frps` exits unexpectedly, it automatically restarts using an exponential backoff policy.
@@ -98,7 +98,7 @@ Admin modifies tunnel/intranet port mappings -> Click Publish -> Generate new Tu
+-----------------------------------------------------------------------+-----------------------------------------------------------------------+
| |
v (Relay Side) v (Client Side)
openflare_relay heartbeat detects frps port/Token change openflared heartbeat detects tunnel_version change
openflare-relay heartbeat detects frps port/Token change openflared heartbeat detects tunnel_version change
Re-render local frps.toml Request full proxy configuration details
Kill and restart the frps process Re-render frpc_<relay_id>.toml configs
Report health status as healthy Restart or hot-reload changed frpc processes
+3 -3
View File
@@ -64,7 +64,7 @@ curl -I http://127.0.0.1:3000
2. If running from source, verify that the frontend static assets have been built:
```bash
cd openflare_server/web
cd openflare-server/web
pnpm build
```
@@ -73,7 +73,7 @@ pnpm build
4. If accessing via the frontend dev server, verify the backend proxy configuration:
```bash
cd openflare_server/web
cd openflare-server/web
NEXT_DEV_BACKEND_URL=http://127.0.0.1:3000 pnpm dev
```
@@ -220,7 +220,7 @@ Domains without a bound certificate will not be added to the HTTPS configuration
Execute:
```bash
cd openflare_server/web
cd openflare-server/web
corepack enable
pnpm install
pnpm lint
+1 -1
View File
@@ -152,4 +152,4 @@ Once logged into the management console, the Swagger page is accessible at:
/swagger/index.html
```
The Swagger definition file is stored in `openflare_server/docs`, generated by `swag init`.
The Swagger definition file is stored in `openflare-server/docs`, generated by `swag init`.
+11 -11
View File
@@ -7,7 +7,7 @@ You will learn: Common commands for starting, building, testing, installing, and
Start from source:
```bash
cd openflare_server
cd openflare-server
export SESSION_SECRET='replace-with-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
@@ -23,7 +23,7 @@ go run . --port 3000 --log-dir ./logs
Run tests:
```bash
cd openflare_server
cd openflare-server
GOCACHE=/tmp/openflare-go-cache go test ./...
```
@@ -32,7 +32,7 @@ GOCACHE=/tmp/openflare-go-cache go test ./...
Development:
```bash
cd openflare_server/web
cd openflare-server/web
pnpm install
pnpm dev
```
@@ -40,14 +40,14 @@ pnpm dev
Build static assets:
```bash
cd openflare_server/web
cd openflare-server/web
pnpm build
```
Linting and testing checks:
```bash
cd openflare_server/web
cd openflare-server/web
pnpm lint
pnpm typecheck
pnpm test
@@ -58,21 +58,21 @@ pnpm test
Run from source:
```bash
cd openflare_agent
cd openflare-agent
go run ./cmd/agent -config /path/to/agent.json
```
Compile:
```bash
cd openflare_agent
cd openflare-agent
go build -o openflare-agent ./cmd/agent
```
Run tests:
```bash
cd openflare_agent
cd openflare-agent
GOCACHE=/tmp/openflare-go-cache go test ./...
```
@@ -81,14 +81,14 @@ GOCACHE=/tmp/openflare-go-cache go test ./...
Run from source:
```bash
cd openflare_relay
cd openflare-relay
go run ./cmd -config /path/to/relay.json
```
Compile:
```bash
cd openflare_relay
cd openflare-relay
go build -o openflare-relay ./cmd
```
@@ -128,7 +128,7 @@ Regenerate Swagger documentation:
```bash
go install github.com/swaggo/swag/cmd/swag@v1.16.4
cd openflare_server
cd openflare-server
swag init -g main.go -o docs
```
+1 -1
View File
@@ -46,7 +46,7 @@ The Client (Intranet Client) supports:
## Server CLI Arguments
```bash
cd openflare_server
cd openflare-server
go run . --port 3000 --log-dir ./logs
```
+3 -3
View File
@@ -64,7 +64,7 @@ curl -I http://127.0.0.1:3000
2. 如果是源码运行,确认已经构建前端静态产物:
```bash
cd openflare_server/web
cd openflare-server/web
pnpm build
```
@@ -73,7 +73,7 @@ pnpm build
4. 如果通过前端开发服务器访问,确认后端代理地址:
```bash
cd openflare_server/web
cd openflare-server/web
NEXT_DEV_BACKEND_URL=http://127.0.0.1:3000 pnpm dev
```
@@ -220,7 +220,7 @@ curl -Iv https://your-domain
执行:
```bash
cd openflare_server/web
cd openflare-server/web
corepack enable
pnpm install
pnpm lint
+5 -5
View File
@@ -76,20 +76,20 @@ Frontend:
任何涉及表结构、索引、列类型、分表规则或内部持久化元数据的修改,都必须同步提升数据库版本号。
数据库版本号定义在 `openflare_server/model`,不得只依赖 `AutoMigrate` 隐式升级存量数据库。
数据库版本号定义在 `openflare-server/model`,不得只依赖 `AutoMigrate` 隐式升级存量数据库。
每次提升数据库版本号时,必须补充从上一版本升级到新版本的显式迁移方法。迁移方法必须包含升级后的校验逻辑;只有校验通过,才能写入新的数据库版本记录。
数据库升级统一使用 goose。新的 goose provider、桥接逻辑、注册入口和具体迁移文件必须全部放在 `openflare_server/model/goose` 包下,`openflare_server/model` 根包只保留纯净实体类、旧框架兼容适配和必要的上下文注入。每次新增数据库升级都必须新建一个单独的 Go 文件,文件名使用 `openflare_server/model/goose/goose_<timestamp>_<description>.go`,例如 `openflare_server/model/goose/goose_202606020001_add_node_capabilities_json.go`。迁移文件必须同时包含该版本的 goose migration 构造函数、升级逻辑和校验逻辑;`model/goose/migrations.go` 只能作为注册入口和公共构造工具,禁止把具体迁移逻辑集中堆放在该文件中。
数据库升级统一使用 goose。新的 goose provider、桥接逻辑、注册入口和具体迁移文件必须全部放在 `openflare-server/model/goose` 包下,`openflare-server/model` 根包只保留纯净实体类、旧框架兼容适配和必要的上下文注入。每次新增数据库升级都必须新建一个单独的 Go 文件,文件名使用 `openflare-server/model/goose/goose_<timestamp>_<description>.go`,例如 `openflare-server/model/goose/goose_202606020001_add_node_capabilities_json.go`。迁移文件必须同时包含该版本的 goose migration 构造函数、升级逻辑和校验逻辑;`model/goose/migrations.go` 只能作为注册入口和公共构造工具,禁止把具体迁移逻辑集中堆放在该文件中。
执行数据库升级时必须按以下步骤完成:
1. 判断是否需要升级数据库版本:凡是新增/删除/重命名表、字段、索引、约束、列类型、分表规则,或改变持久化数据语义,都必须升级。
2. 新增 `openflare_server/model/goose/goose_<timestamp>_<description>.go`,其中 `<timestamp>` 为 goose 版本号。文件头部或迁移构造函数附近必须包含注释,说明本次升级了什么内容,以及为什么需要升级。
3. 在该文件中实现独立迁移构造函数,并返回通过 `newGORMMigration(...)` 创建的 migration;随后只在 `openflare_server/model/goose/migrations.go` 的 `registeredMigrations(...)` 中新增一条注册项。
2. 新增 `openflare-server/model/goose/goose_<timestamp>_<description>.go`,其中 `<timestamp>` 为 goose 版本号。文件头部或迁移构造函数附近必须包含注释,说明本次升级了什么内容,以及为什么需要升级。
3. 在该文件中实现独立迁移构造函数,并返回通过 `newGORMMigration(...)` 创建的 migration;随后只在 `openflare-server/model/goose/migrations.go` 的 `registeredMigrations(...)` 中新增一条注册项。
4. 在同一个单独迁移文件中写入升级逻辑。可通过 goose `Context` 调用 `ApplyCurrentSchema`、历史 backfill、默认数据初始化等公共能力;复杂数据修复必须显式处理,不得只依赖 `AutoMigrate`。
5. 在同一个单独迁移文件中写入升级后的校验逻辑。校验至少要覆盖新增表/字段/索引是否存在、关键默认数据是否存在、必要的数据回填是否成功。
6. 如果新迁移需要新的公共 backfill 或校验辅助函数,优先放在该迁移文件中;只有多个迁移共同复用时,才放到 `openflare_server/model/goose` 包内的公共文件中。不要把新 goose 框架代码放回 `openflare_server/model` 根包。
6. 如果新迁移需要新的公共 backfill 或校验辅助函数,优先放在该迁移文件中;只有多个迁移共同复用时,才放到 `openflare-server/model/goose` 包内的公共文件中。不要把新 goose 框架代码放回 `openflare-server/model` 根包。
7. 补充迁移测试:至少覆盖从旧框架终点或上一 goose 版本升级后 schema version、字段/表结构、关键数据回填和校验结果。还应保留旧库从 v15/v17 桥接到 goose 的回归覆盖。
新包启动后必须先检查数据库当前版本,再按顺序逐步升级到目标版本;禁止跳过中间升级步骤直接写目标版本。
@@ -0,0 +1,147 @@
# OpenFlare 引用替换为 GitHub 路径方案评估计划
## 1. 目标与背景 (Goal & Context)
* **需求背景**:当前 OpenFlare 内部组件(Server、Agent、Relay、Flared)之间采用本地包名引用(例如 `openflare`、`openflare-agent`),并使用 Go `replace` 相对路径指向本地目录。这导致代码无法直接以标准的 GitHub 路径(如 `github.com/rain-kl/openflare`)进行分发、远程安装或被外部引用(例如 `go install` 远程二进制会因为 replace 指令失效而报错)。
* **评估目标**:评估将本地引用替换为 `github.com/rain-kl/openflare` 格式的两种可行方案(单模块 Monorepo 方案 vs 多模块 Multi-Module 方案),分析各自的优缺点、工作量及对现有 CI/CD、Docker 镜像构建的影响,给出推荐方案。
## 2. 设计与决策 (Design & Decisions)
### 方案 A:标准 Go 多模块方案 (Multi-Module with Sub-paths)
保留当前 4 个独立的 Go 模块结构,在各自的 `go.mod` 中将模块名改写为符合 GitHub 结构的子路径:
- `openflare-server/go.mod` -> `module github.com/rain-kl/openflare/openflare-server`
- `openflare-relay/go.mod` -> `module github.com/rain-kl/openflare/openflare-relay`
- `openflare-agent/go.mod` -> `module github.com/rain-kl/openflare/openflare-agent`
- `openflared/go.mod` -> `module github.com/rain-kl/openflare/openflared`
同时,其他模块(Relay, Agent, Flared)的 `go.mod` 中的 `replace` 修改为:
`replace github.com/rain-kl/openflare/openflare-server => ../openflare-server`
#### 优缺点分析:
* **优点**:
- **模块边界清晰**:各二进制模块依赖独立。例如 `openflare-agent` 不会引入 Server 依赖的 GORM、Gin、Swagger 等库,保持各自模块的 `go.sum` 纯净。
- **改动小**:对 Dockerfile 和 GitHub Workflows 影响极小,构建上下文仍可保持原样。
* **缺点**:
- **远程安装不可用**:仍然需要在 `go.mod` 中保留 `replace` 指令。由于 Go 不允许在远程 `go install` 或 `go get` 时解析本地相对路径的 `replace` 指令,用户依然无法直接通过 `go install github.com/rain-kl/openflare/openflared/cmd/flared@latest` 安装,必须先克隆整个仓库到本地再构建。
---
### 方案 B:统一单模块方案 (Unified Single Module Monorepo - 推荐)
将整个仓库合并为一个 Go 模块。在仓库根目录下创建 `go.mod`,模块名为 `github.com/rain-kl/openflare`,并删除子目录中的所有 `go.mod` 和 `go.sum`。
所有内部包导入路径统一改写为:
- `"github.com/rain-kl/openflare/openflare-server/..."`
- `"github.com/rain-kl/openflare/openflare-relay/..."`
- `"github.com/rain-kl/openflare/openflare-agent/..."`
- `"github.com/rain-kl/openflare/openflared/..."`
#### 优缺点分析:
* **优点**:
- **彻底摆脱 replace**:完全不需要在 `go.mod` 中写 `replace` 指令,代码清爽、易于维持。
- **支持远程 Go 工具链**:用户和开发者可以直接使用 `go install github.com/rain-kl/openflare/openflared/cmd/flared@latest` 或 `go install github.com/rain-kl/openflare/openflare-agent/cmd/agent@latest` 远程下载并安装最新二进制。
- **版本依赖统一**:所有组件共享相同的依赖版本,避免了组件间因第三方库版本不一致导致潜在的运行时兼容问题。
* **缺点**:
- **依赖库大一统**:根目录的 `go.mod` 会包含 Server、Agent、Relay 等所有组件的依赖,但这只影响开发时的依赖下载,对最终编译出的二进制大小和运行效率**没有任何影响**(Go 编译器会自动进行死代码消除/树摇)。
- **构建配置变动**:Dockerfile 以及 GitHub Actions 需要修改构建上下文,从原本 COPY 子目录改为从根目录统一进行 COPY 和 `go build`。
---
## 3. 具体修改文件清单 (Proposed Changes)
如果采用**方案 B(推荐)**,需要修改的文件清单和逻辑如下:
### 根目录与配置文件
* #### [NEW] [go.mod](file:///Users/ryan/DEV/Go/OpenFlare/go.mod)
- 职责:全局单一 Go 模块定义,模块名:`github.com/rain-kl/openflare`。
* #### [DELETE] `openflare-server/go.mod` / `go.sum`
* #### [DELETE] `openflare-relay/go.mod` / `go.sum`
* #### [DELETE] `openflare-agent/go.mod` / `go.sum`
* #### [DELETE] `openflared/go.mod` / `go.sum`
### 源代码文件 (约 252 个 Go 文件)
* #### [MODIFY] `openflare-server/**/*.go`
- 职责:将 `import "openflare/..."` 替换为 `import "github.com/rain-kl/openflare/openflare-server/..."`。
* #### [MODIFY] `openflare-relay/**/*.go`
- 职责:将 `import "openflare-relay/..."` 替换为 `import "github.com/rain-kl/openflare/openflare-relay/..."`,将 `import "openflare/..."` 替换为 `import "github.com/rain-kl/openflare/openflare-server/..."`。
* #### [MODIFY] `openflare-agent/**/*.go`
- 职责:将 `import "openflare-agent/..."` 替换为 `import "github.com/rain-kl/openflare/openflare-agent/..."`,将 `import "openflare/..."` 替换为 `import "github.com/rain-kl/openflare/openflare-server/..."`。
* #### [MODIFY] `openflared/**/*.go`
- 职责:将 `import "openflare-flared/..."` 替换为 `import "github.com/rain-kl/openflare/openflared/..."`,将 `import "openflare/..."` 替换为 `import "github.com/rain-kl/openflare/openflare-server/..."`。
### Dockerfile & Workflows
如果采用**方案 B(推荐)**,我们将继续保持每个组件(Server、Agent、Relay、Flared)编译并产生自己独立的 Docker 镜像(共 4 个镜像),但其 Dockerfile 的构建上下文(Build Context)统一提升至仓库根目录。具体调整细节如下:
* #### [MODIFY] [openflare-server/Dockerfile](file:///Users/ryan/DEV/Go/OpenFlare/openflare-server/Dockerfile)
- 职责:由于 `openflare-server` 中没有独立的 `go.mod`,构建上下文必须在**仓库根目录**执行。
- 修改内容:
```dockerfile
# 更改 go-builder 阶段的 COPY 方式:
COPY go.mod go.sum ./
RUN go mod download
COPY openflare-server/ ./openflare-server/
# go build 指定编译子包:
RUN go build -trimpath -ldflags "-s -w -X 'github.com/rain-kl/openflare/openflare-server/common.Version=$VERSION'" -o openflare ./openflare-server
```
* #### [MODIFY] [openflare-relay/Dockerfile](file:///Users/ryan/DEV/Go/OpenFlare/openflare-relay/Dockerfile)
- 职责:适配单 go.mod 构建上下文。
- 修改内容:
```dockerfile
# 更改 builder 阶段的 COPY 方式:
COPY go.mod go.sum ./
RUN go mod download
COPY openflare-server/ ./openflare-server/
COPY openflare-relay/ ./openflare-relay/
# go build 指定编译子包:
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags "-s -w -X 'github.com/rain-kl/openflare/openflare-relay/internal/config.Version=$VERSION'" -o openflare-relay ./openflare-relay/cmd/relay
```
* #### [MODIFY] [openflare-agent/Dockerfile](file:///Users/ryan/DEV/Go/OpenFlare/openflare-agent/Dockerfile)
- 职责:适配单 go.mod 构建上下文。
- 修改内容:
```dockerfile
# 更改 builder 阶段的 COPY 方式:
COPY go.mod go.sum ./
RUN go mod download
COPY openflare-server/ ./openflare-server/
COPY openflare-agent/ ./openflare-agent/
# go build 指定编译子包:
RUN go build -trimpath -ldflags "-s -w -X 'github.com/rain-kl/openflare/openflare-agent/internal/config.Version=$VERSION'" -o /build/openflare-agent ./openflare-agent/cmd/agent
```
* #### [MODIFY] [openflared/Dockerfile](file:///Users/ryan/DEV/Go/OpenFlare/openflared/Dockerfile)
- 职责:适配单 go.mod 构建上下文。
- 修改内容:
```dockerfile
# 更改 builder 阶段的 COPY 方式:
COPY go.mod go.sum ./
RUN go mod download
COPY openflare-server/ ./openflare-server/
COPY openflared/ ./openflared/
# go build 指定编译子包:
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags "-s -w -X 'github.com/rain-kl/openflare/openflared/internal/config.Version=$VERSION'" -o flared ./openflared/cmd/flared
```
* #### [MODIFY] [.github/workflows/release.yml](file:///Users/ryan/DEV/Go/OpenFlare/.github/workflows/release.yml)
- 职责:更新 go build 构建命令及 ldflags 版本注入参数(例如将 `-ldflags "-X 'openflare/common.Version=$VERSION'"` 替换为 `-ldflags "-X 'github.com/rain-kl/openflare/openflare-server/common.Version=$VERSION'"`,同时编译命令需要指向正确的子包目录,如 `./openflare-server`)。
---
## 4. 验证计划 (Verification Plan)
### 编译与运行测试
* 运行单测以确保各包逻辑正常:
`go test ./...`(在根目录执行)
* 本地编译各个二进制:
`go build -o bin/openflare-server ./openflare-server`
`go build -o bin/openflare-agent ./openflare-agent/cmd/agent`
`go build -o bin/openflare-relay ./openflare-relay/cmd/relay`
`go build -o bin/openflared ./openflared/cmd/flared`
* 启动服务并检查版本输出:
`./bin/openflare-server --version`
### Docker 构建验证
* 验证镜像构建命令:
`docker build -t openflare-server -f openflare-server/Dockerfile .`
`docker build -t openflare-agent -f openflare-agent/Dockerfile .`
`docker build -t openflare-relay -f openflare-relay/Dockerfile .`
`docker build -t openflared -f openflared/Dockerfile .`
+1 -1
View File
@@ -28,5 +28,5 @@
## 4. 下一步行动指南 (Next Steps)
新接手 AI 进来后应当立即执行的前 3 步命令或编辑操作:
1. **第一步**:执行 `go test ./controller/...` 确认环境并复现 Fail 异常。
2. **第二步**:修改 `openflare_server/controller/xxx.go` 中的逻辑以修复该 Fail。
2. **第二步**:修改 `openflare-server/controller/xxx.go` 中的逻辑以修复该 Fail。
3. **第三步**:在管理端前端页面调试 xxx 表单的提交是否正常。
+4 -4
View File
@@ -22,17 +22,17 @@
按模块或组件列出需要修改的物理文件路径及修改点:
### 后端 Server
* #### [NEW] `openflare_server/model/entity.go`
* #### [NEW] `openflare-server/model/entity.go`
* 职责:...
* #### [MODIFY] `openflare_server/service/feature.go`
* #### [MODIFY] `openflare-server/service/feature.go`
* 职责:...
### 边缘 Agent 与 OpenResty
* #### [MODIFY] `openflare_agent/sync/sync.go`
* #### [MODIFY] `openflare-agent/sync/sync.go`
* 职责:...
### 前端 Web
* #### [NEW] `openflare_server/web/features/feature-view.tsx`
* #### [NEW] `openflare-server/web/features/feature-view.tsx`
* 职责:...
---
+11 -11
View File
@@ -7,7 +7,7 @@
源码启动:
```bash
cd openflare_server
cd openflare-server
export JWT_SECRET='replace-with-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
@@ -23,7 +23,7 @@ go run . --port 3000 --log-dir ./logs
测试:
```bash
cd openflare_server
cd openflare-server
GOCACHE=/tmp/openflare-go-cache go test ./...
```
@@ -32,7 +32,7 @@ GOCACHE=/tmp/openflare-go-cache go test ./...
开发:
```bash
cd openflare_server/web
cd openflare-server/web
pnpm install
pnpm dev
```
@@ -40,14 +40,14 @@ pnpm dev
构建静态产物:
```bash
cd openflare_server/web
cd openflare-server/web
pnpm build
```
检查:
```bash
cd openflare_server/web
cd openflare-server/web
pnpm lint
pnpm typecheck
pnpm test
@@ -58,21 +58,21 @@ pnpm test
源码运行:
```bash
cd openflare_agent
cd openflare-agent
go run ./cmd/agent -config /path/to/agent.json
```
编译:
```bash
cd openflare_agent
cd openflare-agent
go build -o openflare-agent ./cmd/agent
```
测试:
```bash
cd openflare_agent
cd openflare-agent
GOCACHE=/tmp/openflare-go-cache go test ./...
```
@@ -81,14 +81,14 @@ GOCACHE=/tmp/openflare-go-cache go test ./...
源码运行:
```bash
cd openflare_relay
cd openflare-relay
go run ./cmd -config /path/to/relay.json
```
编译:
```bash
cd openflare_relay
cd openflare-relay
go build -o openflare-relay ./cmd
```
@@ -129,7 +129,7 @@ curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/unin
```bash
go install github.com/swaggo/swag/cmd/swag@v1.16.4
cd openflare_server
cd openflare-server
swag init -g main.go -o docs
```
+1 -1
View File
@@ -46,7 +46,7 @@ Client (内网客户端) 支持:
## Server 命令行参数
```bash
cd openflare_server
cd openflare-server
go run . --port 3000 --log-dir ./logs
```
+1 -1
View File
@@ -8,4 +8,4 @@
| --- | --- |
| [配置项](./configuration.md) | Server 环境变量、命令行参数、运行时 Option 与 Agent 配置字段 |
| [命令与脚本](./cli.md) | 常用启动、构建、测试、安装和卸载命令 |
| [仓库结构](../design/index.md#仓库结构) | `openflare_server`、`openflare_agent`、`openflare_relay`、`openflared` 模块的职责与分层目录说明 |
| [仓库结构](../design/index.md#仓库结构) | `openflare-server`、`openflare-agent`、`openflare-relay`、`openflared` 模块的职责与分层目录说明 |
+2 -4
View File
@@ -1,8 +1,9 @@
module openflare
module github.com/rain-kl/openflare
go 1.25.7
require (
github.com/appleboy/gin-jwt/v2 v2.10.3
github.com/bwmarrin/snowflake v0.3.0
github.com/dgraph-io/ristretto/v2 v2.2.0
github.com/expr-lang/expr v1.17.8
@@ -32,14 +33,11 @@ require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/appleboy/gin-jwt/v2 v2.10.3 // indirect
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect
github.com/bytedance/sonic v1.12.9 // indirect
github.com/bytedance/sonic/loader v0.2.3 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
+8 -26
View File
@@ -8,14 +8,12 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/appleboy/gin-jwt/v2 v2.10.3 h1:KNcPC+XPRNpuoBh+j+rgs5bQxN+SwG/0tHbIqpRoBGc=
github.com/appleboy/gin-jwt/v2 v2.10.3/go.mod h1:LDUaQ8mF2W6LyXIbd5wqlV2SFebuyYs4RDwqMNgpsp8=
github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4=
github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw=
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff h1:RmdPFa+slIr4SCBg4st/l/vZWVe9QJKMXGO60Bxbe04=
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff/go.mod h1:+RTT1BOk5P97fT2CiHkbFQwkK3mjsFAP6zCYV2aXtjw=
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
github.com/bytedance/sonic v1.11.2 h1:ywfwo0a/3j9HR8wsYGWsIWl2mvRsI950HyoxiBERw5A=
github.com/bytedance/sonic v1.11.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/bytedance/sonic v1.12.9 h1:Od1BvK55NnewtGaJsTDeAOSnLVO2BTSLOe0+ooKokmQ=
github.com/bytedance/sonic v1.12.9/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
@@ -25,13 +23,6 @@ github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1x
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
@@ -60,15 +51,12 @@ github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE=
github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E=
github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0=
github.com/gin-contrib/static v0.0.1 h1:JVxuvHPuUfkoul12N7dtQw7KRn/pSMq7Ue1Va9Swm1U=
github.com/gin-contrib/static v0.0.1/go.mod h1:CSxeF+wep05e0kCOsqWdAWbSszmc31zTIbD8TvWl7Hs=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
@@ -99,8 +87,6 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8=
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
@@ -109,8 +95,6 @@ github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
@@ -152,8 +136,6 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/Kgo2/7xNSUuC5G28VR8ljfrLKU2G4IjU=
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12/go.mod h1:TBzl5BIHNXfS9+C35ZyJaklL7mLDbgUkcgXzSLa8Tk0=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
@@ -200,8 +182,6 @@ github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8=
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -238,6 +218,12 @@ github.com/swaggo/gin-swagger v1.6.1 h1:Ri06G4gc9N4t4k8hekMigJ9zKTFSlqj/9paAQCQs
github.com/swaggo/gin-swagger v1.6.1/go.mod h1:LQ+hJStHakCWRiK/YNYtJOu4mR2FP+pxLnILT/qNiTw=
github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A=
github.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg=
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
@@ -249,9 +235,6 @@ github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfS
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4=
golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -359,4 +342,3 @@ modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
@@ -12,19 +12,15 @@ ENV CGO_ENABLED=0 \
GOARCH=${TARGETARCH}
WORKDIR /build
COPY openflare_server/go.mod openflare_server/go.sum ./openflare_server/
COPY openflare_agent/go.mod openflare_agent/go.sum ./openflare_agent/
WORKDIR /build/openflare_agent
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
WORKDIR /build
COPY openflare_server ./openflare_server
COPY openflare_agent ./openflare_agent
WORKDIR /build/openflare_agent
COPY openflare-server ./openflare-server
COPY openflare-agent ./openflare-agent
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build -trimpath -ldflags "-s -w -X 'openflare-agent/internal/config.Version=$VERSION'" -o /build/openflare-agent ./cmd/agent
go build -trimpath -ldflags "-s -w -X 'github.com/rain-kl/openflare/openflare-agent/internal/config.Version=$VERSION'" -o /build/bin/openflare-agent ./openflare-agent/cmd/agent
FROM openresty/openresty:alpine
@@ -36,7 +32,7 @@ RUN apk add --no-cache ca-certificates tzdata perl libmaxminddb \
ENV OPENFLARE_OPENRESTY_PATH=openresty \
OPENFLARE_DATA_DIR=/data
COPY --from=builder /build/openflare-agent /usr/local/bin/openflare-agent
COPY --from=builder /build/bin/openflare-agent /usr/local/bin/openflare-agent
EXPOSE 80 443 18081
ENTRYPOINT ["/usr/local/bin/openflare-agent"]
@@ -8,17 +8,17 @@ import (
"os/signal"
"syscall"
"openflare-agent/internal/agent"
"openflare-agent/internal/config"
"openflare-agent/internal/geoipupdate"
"openflare-agent/internal/heartbeat"
"openflare-agent/internal/httpclient"
"openflare-agent/internal/logging"
"openflare-agent/internal/nginx"
"openflare-agent/internal/state"
syncservice "openflare-agent/internal/sync"
"openflare-agent/internal/updater"
"openflare-agent/internal/wsclient"
"github.com/rain-kl/openflare/openflare-agent/internal/agent"
"github.com/rain-kl/openflare/openflare-agent/internal/config"
"github.com/rain-kl/openflare/openflare-agent/internal/geoipupdate"
"github.com/rain-kl/openflare/openflare-agent/internal/heartbeat"
"github.com/rain-kl/openflare/openflare-agent/internal/httpclient"
"github.com/rain-kl/openflare/openflare-agent/internal/logging"
"github.com/rain-kl/openflare/openflare-agent/internal/nginx"
"github.com/rain-kl/openflare/openflare-agent/internal/state"
syncservice "github.com/rain-kl/openflare/openflare-agent/internal/sync"
"github.com/rain-kl/openflare/openflare-agent/internal/updater"
"github.com/rain-kl/openflare/openflare-agent/internal/wsclient"
)
func main() {
@@ -8,11 +8,11 @@ import (
"strings"
"time"
"openflare-agent/internal/config"
"openflare-agent/internal/observability"
"openflare-agent/internal/protocol"
"openflare-agent/internal/state"
"openflare-agent/internal/wsclient"
"github.com/rain-kl/openflare/openflare-agent/internal/config"
"github.com/rain-kl/openflare/openflare-agent/internal/observability"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/state"
"github.com/rain-kl/openflare/openflare-agent/internal/wsclient"
)
type HeartbeatService interface {
@@ -10,9 +10,9 @@ import (
"testing"
"time"
"openflare-agent/internal/config"
"openflare-agent/internal/protocol"
"openflare-agent/internal/state"
"github.com/rain-kl/openflare/openflare-agent/internal/config"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/state"
)
type fakeHeartbeatService struct {
@@ -6,15 +6,16 @@ import (
"errors"
"fmt"
"net"
"openflare/utils"
"openflare/utils/geoip"
"openflare/utils/geoip/iputil"
"os"
pathpkg "path"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/rain-kl/openflare/openflare-server/utils"
"github.com/rain-kl/openflare/openflare-server/utils/geoip"
"github.com/rain-kl/openflare/openflare-server/utils/geoip/iputil"
)
const (
@@ -5,11 +5,12 @@ import (
"encoding/json"
"errors"
"net"
"openflare/utils/geoip"
"os"
"path/filepath"
"testing"
"time"
"github.com/rain-kl/openflare/openflare-server/utils/geoip"
)
func TestLoadDefaultsToManagedBinaryPaths(t *testing.T) {
@@ -9,8 +9,8 @@ import (
"path/filepath"
"time"
"openflare-agent/internal/geoipdata"
"openflare/utils/geoip"
"github.com/rain-kl/openflare/openflare-agent/internal/geoipdata"
"github.com/rain-kl/openflare/openflare-server/utils/geoip"
)
type Updater struct {
@@ -3,7 +3,7 @@ package heartbeat
import (
"context"
"openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
)
type Client interface {
@@ -12,7 +12,7 @@ import (
"strings"
"time"
"openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
)
type Client struct {
@@ -20,10 +20,10 @@ import (
"strings"
"time"
"openflare/utils"
openrestyrender "openflare/utils/render/openresty"
"github.com/rain-kl/openflare/openflare-server/utils"
openrestyrender "github.com/rain-kl/openflare/openflare-server/utils/render/openresty"
"openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
)
const RuntimeConfigDirPlaceholder = "__OPENFLARE_RUNTIME_CONFIG_DIR__"
@@ -12,7 +12,7 @@ import (
"strings"
"testing"
"openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
)
type runCall struct {
@@ -1,6 +1,6 @@
package nginx
import "openflare-agent/internal/protocol"
import "github.com/rain-kl/openflare/openflare-agent/internal/protocol"
const (
openRestyObservabilityWindowTTL = "7200"
@@ -2,9 +2,10 @@ package nginx
import (
"embed"
"openflare-agent/internal/protocol"
"path/filepath"
"strings"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
)
//go:embed pow_static

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

@@ -1,6 +1,6 @@
package nginx
import "openflare-agent/internal/protocol"
import "github.com/rain-kl/openflare/openflare-agent/internal/protocol"
const openRestyWAFRuntimeLua = `local _M = {}
@@ -5,9 +5,6 @@ import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"openflare-agent/internal/config"
"openflare-agent/internal/protocol"
"openflare-agent/internal/state"
"os"
"path/filepath"
"runtime"
@@ -15,6 +12,10 @@ import (
"strings"
"syscall"
"time"
"github.com/rain-kl/openflare/openflare-agent/internal/config"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/state"
)
func BuildProfile(cfg *config.Config, stateStore *state.Store) *protocol.NodeSystemProfile {
@@ -5,12 +5,13 @@ import (
"fmt"
"io"
"net/http"
"openflare-agent/internal/config"
"openflare-agent/internal/protocol"
"regexp"
"strconv"
"strings"
"time"
"github.com/rain-kl/openflare/openflare-agent/internal/config"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
)
const openRestyObservabilityPath = "/openflare/observability"
@@ -7,7 +7,7 @@ import (
"strings"
"testing"
"openflare-agent/internal/config"
"github.com/rain-kl/openflare/openflare-agent/internal/config"
)
func TestCollectManagedOpenRestyMetrics(t *testing.T) {
@@ -6,15 +6,16 @@ import (
"errors"
"io"
"log/slog"
"openflare-agent/internal/config"
"openflare-agent/internal/protocol"
"openflare-agent/internal/state"
"os"
"regexp"
"sort"
"strconv"
"strings"
"time"
"github.com/rain-kl/openflare/openflare-agent/internal/config"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/state"
)
type accessLogRecord struct {
@@ -6,9 +6,9 @@ import (
"strings"
"testing"
"openflare-agent/internal/config"
"openflare-agent/internal/protocol"
"openflare-agent/internal/state"
"github.com/rain-kl/openflare/openflare-agent/internal/config"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/state"
)
func TestBuildTrafficReportAggregatesManagedAccessLog(t *testing.T) {
@@ -8,7 +8,7 @@ import (
"strconv"
"sync"
"openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
)
const observabilityBufferWindowSeconds = 60
@@ -4,7 +4,7 @@ import (
"path/filepath"
"testing"
"openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
)
func TestObservabilityBufferStoreUpsertReplayAndAck(t *testing.T) {
@@ -15,7 +15,7 @@ import (
"path/filepath"
"strings"
"openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
)
type pagesSourceDocument struct {
@@ -8,13 +8,14 @@ import (
"errors"
"fmt"
"log/slog"
openrestyrender "openflare/utils/render/openresty"
"sort"
"strings"
"openflare-agent/internal/nginx"
"openflare-agent/internal/protocol"
"openflare-agent/internal/state"
openrestyrender "github.com/rain-kl/openflare/openflare-server/utils/render/openresty"
"github.com/rain-kl/openflare/openflare-agent/internal/nginx"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/state"
)
const (
@@ -13,9 +13,9 @@ import (
"testing"
"time"
"openflare-agent/internal/nginx"
"openflare-agent/internal/protocol"
"openflare-agent/internal/state"
"github.com/rain-kl/openflare/openflare-agent/internal/nginx"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
"github.com/rain-kl/openflare/openflare-agent/internal/state"
)
type fakeExecutor struct {
@@ -9,14 +9,15 @@ import (
"io"
"log/slog"
"net/http"
"openflare/utils"
"os"
"runtime"
"strings"
"time"
"openflare-agent/internal/agent"
"openflare-agent/internal/config"
"github.com/rain-kl/openflare/openflare-server/utils"
"github.com/rain-kl/openflare/openflare-agent/internal/agent"
"github.com/rain-kl/openflare/openflare-agent/internal/config"
)
const maxChecksumAssetSize = 64 * 1024
@@ -6,13 +6,14 @@ import (
"encoding/hex"
"io"
"net/http"
"openflare-agent/internal/agent"
"openflare-agent/internal/config"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/rain-kl/openflare/openflare-agent/internal/agent"
"github.com/rain-kl/openflare/openflare-agent/internal/config"
)
type roundTripFunc func(req *http.Request) (*http.Response, error)
@@ -4,8 +4,8 @@ import (
"context"
"time"
"openflare-agent/internal/protocol"
shared "openflare/utils/wsclient"
"github.com/rain-kl/openflare/openflare-agent/internal/protocol"
shared "github.com/rain-kl/openflare/openflare-server/utils/wsclient"
)
type WSMessage = shared.WSMessage
+1
View File
@@ -0,0 +1 @@
/data/
+33
View File
@@ -0,0 +1,33 @@
# syntax=docker/dockerfile:1.7
ARG VERSION=dev
FROM golang:1.25-alpine AS builder
ARG VERSION
WORKDIR /build
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
COPY openflare-server ./openflare-server
COPY openflare-relay ./openflare-relay
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags "-s -w -X 'github.com/rain-kl/openflare/openflare-relay/internal/config.Version=$VERSION'" -o /build/bin/openflare-relay ./openflare-relay/cmd/relay
# Final runtime image
FROM fatedier/frps:v0.69.0
WORKDIR /app
# Copy openflare-relay binary
COPY --from=builder /build/bin/openflare-relay ./openflare-relay
VOLUME ["/app/data"]
ENV OPENFLARE_FRPS_PATH=/usr/bin/frps
ENV OPENFLARE_DATA_DIR=/app/data
ENTRYPOINT ["/app/openflare-relay"]
@@ -9,13 +9,13 @@ import (
"strings"
"syscall"
"openflare-relay/internal/config"
"openflare-relay/internal/frps"
"openflare-relay/internal/heartbeat"
"openflare-relay/internal/httpclient"
"openflare-relay/internal/relay"
"openflare-relay/internal/state"
"openflare-relay/internal/wsclient"
"github.com/rain-kl/openflare/openflare-relay/internal/config"
"github.com/rain-kl/openflare/openflare-relay/internal/frps"
"github.com/rain-kl/openflare/openflare-relay/internal/heartbeat"
"github.com/rain-kl/openflare/openflare-relay/internal/httpclient"
"github.com/rain-kl/openflare/openflare-relay/internal/relay"
"github.com/rain-kl/openflare/openflare-relay/internal/state"
"github.com/rain-kl/openflare/openflare-relay/internal/wsclient"
)
func main() {
@@ -5,12 +5,13 @@ import (
"encoding/json"
"errors"
"net"
"openflare/utils/geoip"
"openflare/utils/geoip/iputil"
"os"
"path/filepath"
"strings"
"time"
"github.com/rain-kl/openflare/openflare-server/utils/geoip"
"github.com/rain-kl/openflare/openflare-server/utils/geoip/iputil"
)
type MillisecondDuration time.Duration
@@ -12,7 +12,7 @@ import (
"sync"
"time"
"openflare/service"
"github.com/rain-kl/openflare/openflare-server/service"
)
type Manager struct {

Some files were not shown because too many files have changed in this diff Show More