vite-press init

This commit is contained in:
ryan
2026-05-09 16:26:45 +08:00
parent 8730f99fef
commit 797a15ae70
42 changed files with 4760 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
/coverage
/src/client/shared.ts
/src/node/shared.ts
*.log
*.tgz
.DS_Store
.idea
.temp
.vite_opt_cache
.vscode
dist
cache
temp
examples-temp
node_modules
pnpm-global
TODOs.md
*.timestamp-*.mjs
+8
View File
@@ -0,0 +1,8 @@
{
"plugins": {
"postcss-rtlcss": {
"ltrPrefix": ":where([dir=\"ltr\"])",
"rtlPrefix": ":where([dir=\"rtl\"])"
}
}
}
+81
View File
@@ -0,0 +1,81 @@
import { defineConfig, type HeadConfig, resolveSiteDataByRoute } from 'vitepress'
import llmstxt from 'vitepress-plugin-llms'
const prod = !!process.env.NETLIFY
export default defineConfig({
title: 'OpenFlare',
lastUpdated: true,
cleanUrls: true,
metaChunk: true,
srcExclude: [
'zh/**',
'components/**',
'snippets/**',
'design.md',
'website-configuration-redesign.md',
'development-plan.md',
'development-guidelines.md',
'frontend-development-guidelines.md',
'deployment.md',
'app-config.md'
],
markdown: {
math: true
},
sitemap: {
hostname: 'https://openflare.io'
},
head: [
['meta', { name: 'theme-color', content: '#10b981' }],
['meta', { property: 'og:type', content: 'website' }],
['meta', { property: 'og:site_name', content: 'OpenFlare' }],
['meta', { property: 'og:url', content: 'https://openflare.io/' }]
],
themeConfig: {
socialLinks: [
{ icon: 'github', link: 'https://github.com/Rain-kl/OpenFlare' }
],
search: {
provider: 'local'
}
},
locales: {
root: { label: '简体中文', lang: 'zh-Hans', dir: 'ltr' },
en: { label: 'English', lang: 'en-US', dir: 'ltr' }
},
vite: {
plugins: [
prod &&
llmstxt({
workDir: '.',
ignoreFiles: ['index.md']
})
],
experimental: {
enableNativePlugin: true
}
},
transformPageData: prod
? (pageData, ctx) => {
const site = resolveSiteDataByRoute(
ctx.siteConfig.site,
pageData.relativePath
)
const title = `${pageData.title || site.title} | ${
pageData.description || site.description
}`
;((pageData.frontmatter.head ??= []) as HeadConfig[]).push(
['meta', { property: 'og:locale', content: site.lang }],
['meta', { property: 'og:title', content: title }]
)
}
: undefined
})
+4
View File
@@ -0,0 +1,4 @@
import Theme from 'vitepress/theme'
import './styles.css'
export default Theme
+20
View File
@@ -0,0 +1,20 @@
:root {
--vp-c-brand-1: #059669;
--vp-c-brand-2: #10b981;
--vp-c-brand-3: #34d399;
--vp-c-brand-soft: rgba(16, 185, 129, 0.16);
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: linear-gradient(120deg, #059669, #2563eb);
--vp-font-family-base:
Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
'Segoe UI', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
}
.VPHomeHero .text,
.VPHomeHero .tagline {
max-width: 760px;
}
.VPFeature {
border-radius: 8px;
}
+107
View File
@@ -0,0 +1,107 @@
import { defineAdditionalConfig, type DefaultTheme } from 'vitepress'
export default defineAdditionalConfig({
description:
'OpenFlare 是轻量、自托管的 OpenResty 控制面,用于管理反向代理、配置发布、节点同步、TLS 证书与基础观测。',
themeConfig: {
nav: nav(),
sidebar: {
'/guide/': { base: '/guide/', items: sidebarGuide() },
'/reference/': { base: '/reference/', items: sidebarReference() },
'/design/': { base: '/design/', items: sidebarDesign() }
},
editLink: {
pattern: 'https://github.com/Rain-kl/OpenFlare/edit/main/docs/:path',
text: '在 GitHub 上编辑此页面'
},
footer: {
message: '基于 Apache License 2.0 发布',
copyright: 'Copyright © OpenFlare contributors'
},
docFooter: {
prev: '上一页',
next: '下一页'
},
outline: {
label: '页面导航'
},
lastUpdated: {
text: '最后更新于'
},
notFound: {
title: '页面未找到',
quote: '这份文档还没有对应页面。',
linkLabel: '前往首页',
linkText: '回到 OpenFlare 文档'
},
langMenuLabel: '语言',
returnToTopLabel: '回到顶部',
sidebarMenuLabel: '菜单',
darkModeSwitchLabel: '主题',
lightModeSwitchTitle: '切换到浅色模式',
darkModeSwitchTitle: '切换到深色模式',
skipToContentLabel: '跳转到内容'
}
})
function nav(): DefaultTheme.NavItem[] {
return [
{ text: '指南', link: '/guide/', activeMatch: '/guide/' },
{ text: '参考', link: '/reference/', activeMatch: '/reference/' },
{ text: '设计', link: '/design/', activeMatch: '/design/' }
]
}
function sidebarGuide(): DefaultTheme.SidebarItem[] {
return [
{
text: '指南',
items: [
{ text: '概览', link: '' },
{ text: '快速开始', link: 'quick-start' },
{ text: '启动 Server', link: 'server' },
{ text: '接入 Agent', link: 'agent' },
{ text: '发布第一份配置', link: 'first-site' },
{ text: '升级与维护', link: 'upgrade' }
]
}
]
}
function sidebarReference(): DefaultTheme.SidebarItem[] {
return [
{
text: '参考',
items: [
{ text: '概览', link: '' },
{ text: '配置项', link: 'configuration' },
{ text: '命令与脚本', link: 'cli' },
{ text: 'API 约定', link: 'api' },
{ text: '仓库结构', link: 'repository' }
]
}
]
}
function sidebarDesign(): DefaultTheme.SidebarItem[] {
return [
{
text: '设计',
items: [
{ text: '产品边界', link: '' },
{ text: '系统架构', link: 'architecture' },
{ text: '发布模型', link: 'release-model' },
{ text: '开发约束', link: 'development' }
]
}
]
}
+54
View File
@@ -0,0 +1,54 @@
# 系统架构
OpenFlare 由 Server、Agent 与节点本地 OpenResty 组成。
```text
OpenFlare Server (Gin + SQLite/PostgreSQL + Web UI)
|
| HTTP API / Config Pull
v
OpenFlare Agent (register / heartbeat / sync / apply / update)
|
v
Local OpenResty or Docker OpenResty
|
v
Origin
```
## Server
`openflare_server` 是单体控制面:
* Gin
* GORM
* SQLite / PostgreSQL
* 现有登录与 Session 体系
* 托管 `openflare_server/web` 静态构建产物
Server 负责管理端 UI 与 API、Agent API、配置渲染、版本发布、数据存储与聚合查询。
## Agent
`openflare_agent` 是 Go 单体程序:
* 单二进制
* 节点本地执行
* 优先使用 `openresty_path`
* 未配置 `openresty_path` 时默认使用 Docker OpenResty
Agent 负责首次注册、周期性心跳、配置同步、文件写入、`openresty -t`、reload、失败回滚、自更新与轻量采集。
## Frontend
`openflare_server/web` 是正式管理端前端:
* Next.js App Router
* React 19
* TypeScript
* Tailwind CSS
* 静态导出后由 Go Server 托管
## 核心对象
当前有效实体包括 `proxy_routes`、`origins`、`config_versions`、`nodes`、`apply_logs`、`tls_certificates`、`managed_domains`、`node_request_reports`、`node_access_logs`、`node_metric_snapshots`、`traffic_analytics_rollups` 与 `node_health_events`。
+35
View File
@@ -0,0 +1,35 @@
# 开发约束
OpenFlare `1.0.0` 之后的开发优先关注稳定性、升级与回滚链路可靠性、文档准确性、测试覆盖补强,以及既有边界内的小步迭代。
## 变更准入
新需求进入实现前,按以下顺序判断:
1. 是否符合产品边界。
2. 是否符合后端、Agent 与前端开发规范。
3. 是否会破坏发布、同步、回滚或升级主链路。
4. 是否需要同步更新部署、配置或 README 文档。
如果需求超出边界或引入新基础设施,应先更新设计文档,再开始实现。
## 数据库迁移
任何涉及表结构、索引、列类型、分表规则或内部持久化元数据的修改,都必须同步提升数据库版本号,并补充从上一版本升级到新版本的显式迁移方法。
迁移必须包含升级后的校验逻辑。迁移失败或校验失败时,启动流程必须中止,且不得提升数据库版本记录。
## 前端约束
前端以 `openflare_server/web` 为准:
* 页面路由与布局放在 `app/`。
* API 请求统一收敛到 `lib/api/`。
* 业务逻辑优先放在 `features/`。
* 服务端状态使用 TanStack Query。
* 表单使用 React Hook Form 与 Zod。
* 主题必须支持 `light`、`dark`、`system`。
## 测试与交付
关键业务逻辑必须有单元测试或等效回归测试。任何正式基线改动至少应保证不破坏 Agent 心跳、同步、发布与回滚主链路。
+21
View File
@@ -0,0 +1,21 @@
# 产品边界
OpenFlare 是一套自托管的 OpenResty 控制面,面向单团队或单组织内部运维场景,解决反向代理配置、节点同步、证书托管与基础观测的统一管理问题。
当前稳定能力包括:
| 能力 | 说明 |
| --- | --- |
| 反代规则管理 | 以网站配置为聚合边界,支持多域名与源站配置 |
| 配置版本 | 支持预览、发布、激活、历史回滚 |
| Agent 同步 | 支持注册、心跳、同步、应用结果上报 |
| OpenResty 托管 | 管理主配置模板、性能参数、缓存参数与 Lua 资源 |
| HTTPS/TLS | 托管证书与域名资产,并按域名绑定证书 |
| 基础观测 | 聚合节点请求、资源快照、健康事件和访问分析 |
| 节点管理 | 节点状态、令牌体系、部署与更新链路 |
默认工作方式:
* 所有节点消费同一份全局激活版本。
* Server 保存配置与状态,不直接 SSH 管理节点。
* Agent 是节点侧唯一受控落地入口。
+37
View File
@@ -0,0 +1,37 @@
# 发布模型
OpenFlare 的发布模型以完整配置版本为中心,而不是在线修改节点配置。
标准链路:
```text
修改规则 -> 预览/查看 diff -> 发布 -> 生成完整配置版本 -> 激活版本 -> Agent 拉取 -> 本地应用 -> 上报结果
```
## 发布规则
Server 发布时必须:
1. 读取全部启用的 `proxy_routes`。
2. 读取 Server 侧 OpenResty 主配置与结构化参数。
3. 渲染完整 OpenResty 配置。
4. 计算 `checksum`。
5. 写入 `config_versions`。
6. 切换激活版本。
7. 让 Agent 在后续 heartbeat 中发现并应用。
版本号格式固定为 `YYYYMMDD-NNN`。
## 不可变历史
历史版本不可变。回滚不是修改旧版本,而是重新激活旧版本。
全局同时只能有一个激活版本,当前不做按节点分组的差异化版本。
## Agent 应用策略
Agent 发现新版本后会备份旧文件,写入主配置、路由配置、证书与必要 Lua 资源,再执行配置校验和 reload。
如果新配置激活失败,Agent 必须尝试恢复运行;回滚成功时上报警告,回滚后仍无法恢复运行时上报失败。
某个目标 `version + checksum` 一旦应用失败并回退,Agent 会在本地状态中阻断该目标重复应用。只有远端激活版本或 checksum 发生变化,才允许再次尝试。
+79
View File
@@ -0,0 +1,79 @@
import { defineAdditionalConfig, type DefaultTheme } from 'vitepress'
export default defineAdditionalConfig({
description:
'OpenFlare is a lightweight, self-hosted OpenResty control plane for reverse proxy rules, releases, node sync, TLS certificates, and basic observability.',
themeConfig: {
nav: nav(),
sidebar: {
'/en/guide/': { base: '/en/guide/', items: sidebarGuide() },
'/en/reference/': { base: '/en/reference/', items: sidebarReference() },
'/en/design/': { base: '/en/design/', items: sidebarDesign() }
},
editLink: {
pattern: 'https://github.com/Rain-kl/OpenFlare/edit/main/docs/:path',
text: 'Edit this page on GitHub'
},
footer: {
message: 'Released under the Apache License 2.0.',
copyright: 'Copyright © OpenFlare contributors'
}
}
})
function nav(): DefaultTheme.NavItem[] {
return [
{ text: 'Guide', link: '/en/guide/', activeMatch: '/en/guide/' },
{ text: 'Reference', link: '/en/reference/', activeMatch: '/en/reference/' },
{ text: 'Design', link: '/en/design/', activeMatch: '/en/design/' }
]
}
function sidebarGuide(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Guide',
items: [
{ text: 'Overview', link: '' },
{ text: 'Quick Start', link: 'quick-start' },
{ text: 'Run Server', link: 'server' },
{ text: 'Connect Agent', link: 'agent' },
{ text: 'Publish First Site', link: 'first-site' },
{ text: 'Upgrade and Maintenance', link: 'upgrade' }
]
}
]
}
function sidebarReference(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Reference',
items: [
{ text: 'Overview', link: '' },
{ text: 'Configuration', link: 'configuration' },
{ text: 'Commands and Scripts', link: 'cli' },
{ text: 'API Conventions', link: 'api' },
{ text: 'Repository Layout', link: 'repository' }
]
}
]
}
function sidebarDesign(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Design',
items: [
{ text: 'Product Boundary', link: '' },
{ text: 'Architecture', link: 'architecture' },
{ text: 'Release Model', link: 'release-model' },
{ text: 'Development Constraints', link: 'development' }
]
}
]
}
+33
View File
@@ -0,0 +1,33 @@
# Architecture
OpenFlare consists of Server, Agent, and local OpenResty on each node.
```text
OpenFlare Server (Gin + SQLite/PostgreSQL + Web UI)
|
| HTTP API / Config Pull
v
OpenFlare Agent (register / heartbeat / sync / apply / update)
|
v
Local OpenResty or Docker OpenResty
|
v
Origin
```
## Server
`openflare_server` is a monolithic control plane based on Gin, GORM, SQLite/PostgreSQL, the existing login/session system, and the static frontend build.
It owns the admin UI and API, Agent API, configuration rendering, version publishing, storage, and aggregate queries.
## Agent
`openflare_agent` is a single Go binary that runs locally on each node. It prefers `openresty_path` when configured and uses Docker OpenResty by default otherwise.
It handles registration, heartbeat, sync, file writes, `openresty -t`, reload, rollback, self-update, and lightweight collection.
## Frontend
`openflare_server/web` is the production frontend baseline: Next.js App Router, React 19, TypeScript, and Tailwind CSS.
+31
View File
@@ -0,0 +1,31 @@
# Development Constraints
After `1.0.0`, OpenFlare development prioritizes stability, upgrade and rollback reliability, documentation accuracy, test coverage, and small iterations inside the existing boundary.
## Change Admission
Before implementing a requirement, check:
1. Whether it fits the product boundary.
2. Whether it follows Server, Agent, and frontend development rules.
3. Whether it risks the publish, sync, rollback, or upgrade flow.
4. Whether deployment, configuration, or README docs need updates.
If a requirement expands the boundary or introduces new infrastructure, update design documentation first.
## Database Migrations
Any table, index, column type, sharding, or internal persistence metadata change must bump the database version and include an explicit migration from the previous version.
Migrations must validate the upgraded schema. Startup must stop if migration or validation fails.
## Frontend Rules
`openflare_server/web` is the frontend baseline:
* Routes and layouts live in `app/`.
* API calls are centralized under `lib/api/`.
* Business logic belongs in `features/`.
* Server state uses TanStack Query.
* Forms use React Hook Form and Zod.
* Theme supports `light`, `dark`, and `system`.
+21
View File
@@ -0,0 +1,21 @@
# Product Boundary
OpenFlare is a self-hosted OpenResty control plane for single-team or single-organization operations. It unifies reverse proxy configuration, node synchronization, certificate management, and basic observability.
Stable capabilities:
| Capability | Description |
| --- | --- |
| Reverse proxy management | Site-level configuration with multiple domains and origins |
| Configuration versions | Preview, publish, activate, and rollback |
| Agent sync | Registration, heartbeat, sync, and apply result reporting |
| OpenResty management | Main template, performance options, cache options, and Lua assets |
| HTTPS/TLS | Certificate storage and per-domain binding |
| Basic observability | Request rollups, resource snapshots, health events, and access analytics |
| Node management | Node state, tokens, deployment, and update flow |
Default operating model:
* All nodes consume the same globally active version.
* Server stores configuration and state, but does not SSH into nodes.
* Agent is the only controlled entry point on each node.
+33
View File
@@ -0,0 +1,33 @@
# Release Model
OpenFlare publishes complete configuration versions instead of modifying node configuration online.
```text
Edit rules -> Preview / diff -> Publish -> Create full version -> Activate -> Agent pulls -> Agent applies -> Agent reports
```
## Publish Rules
Server must:
1. Read all enabled `proxy_routes`.
2. Read the OpenResty main template and structured options.
3. Render the full OpenResty configuration.
4. Compute `checksum`.
5. Write `config_versions`.
6. Switch the active version.
7. Let Agents discover and apply it in later heartbeats.
Version numbers use `YYYYMMDD-NNN`.
## Immutable History
Historical versions are immutable. Rollback reactivates an old version.
Only one global active version exists at a time. Node-specific version groups are not part of the current model.
## Agent Apply Strategy
Agent backs up old files, writes the new main config, route config, certificates, and Lua assets, then validates and reloads.
If activation fails, Agent attempts to recover. A failed `version + checksum` is blocked locally until the remote active version or checksum changes.
+60
View File
@@ -0,0 +1,60 @@
# Connect Agent
OpenFlare Agent runs on proxy nodes. It handles registration, heartbeat, configuration sync, OpenResty file writes, validation, reload, rollback, and self-update.
## Authentication
| Method | Use case |
| --- | --- |
| `agent_token` | The node already exists or has a dedicated credential |
| `discovery_token` | First-time auto-registration; Server exchanges it for a node token |
At least one of them is required.
## Install Script
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
Or with discovery:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--discovery-token YOUR_DISCOVERY_TOKEN
```
## Configuration Example
```json
{
"server_url": "http://127.0.0.1:3000",
"agent_token": "replace-with-node-auth-token",
"data_dir": "./data",
"openresty_container_name": "openflare-openresty",
"openresty_docker_image": "openresty/openresty:alpine",
"openresty_observability_port": 18081,
"observability_replay_minutes": 15,
"heartbeat_interval": 10000,
"request_timeout": 10000
}
```
Without `openresty_path`, Agent uses Docker OpenResty by default.
## Run from Source
```bash
cd openflare_agent
export LOG_LEVEL='info'
go run ./cmd/agent -config /path/to/agent.json
```
## Uninstall
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/uninstall-agent.sh | bash
```
+32
View File
@@ -0,0 +1,32 @@
# Publish First Site
OpenFlare publishes complete configuration versions. After editing a site, publish and activate a new version before Agents apply it.
## Create Site Configuration
Required fields:
| Field | Description |
| --- | --- |
| Site name | Business-unique identifier; defaults to the primary domain when omitted |
| Domains | At least one domain; the first one is the primary domain |
| Origin URL | Valid `http://` or `https://` upstream URL |
| Enabled | Only enabled sites are rendered into releases |
A domain can belong to only one site.
## Bind Certificates
HTTPS certificates are bound per domain. Domains without certificates are not automatically rendered into `443 ssl` server blocks.
## Publish and Activate
```text
Edit rules -> Preview / diff -> Publish -> Create full version -> Activate -> Agent pulls -> Agent applies -> Agent reports
```
Server reads enabled sites, OpenResty template, performance options, and cache options, renders a full configuration, computes `checksum`, writes `config_versions`, then switches the active version.
## Verify
Check that the node is online, the node version matches the active version, the latest apply log succeeded, and the version page marks the new version as active.
+11
View File
@@ -0,0 +1,11 @@
# Guide
This section helps operators take OpenFlare from first boot to the first working reverse proxy configuration.
Suggested order:
1. [Quick Start](./quick-start.md): run Server with Docker Compose and complete the first login.
2. [Run Server](./server.md): learn source startup, frontend build, and Swagger access.
3. [Connect Agent](./agent.md): use `agent_token` or `discovery_token` to bring a node online.
4. [Publish First Site](./first-site.md): create a site configuration, publish it, and verify node application.
5. [Upgrade and Maintenance](./upgrade.md): understand upgrade, uninstall, validation, and maintenance entry points.
+77
View File
@@ -0,0 +1,77 @@
# Quick Start
The minimal OpenFlare setup contains one Server and at least one Agent. Server owns the web console, release versions, and node state. Agent runs on proxy nodes and applies OpenResty configuration.
## Run Server
Docker Compose with PostgreSQL is recommended:
```yaml
services:
postgres:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_DB: openflare
POSTGRES_USER: openflare
POSTGRES_PASSWORD: replace-with-strong-password
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U openflare -d openflare"]
interval: 10s
timeout: 5s
retries: 5
openflare:
image: ghcr.io/rain-kl/openflare:latest
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
ports:
- "3000:3000"
environment:
SESSION_SECRET: replace-with-random-string
DSN: postgres://openflare:replace-with-strong-password@postgres:5432/openflare?sslmode=disable
GIN_MODE: release
LOG_LEVEL: info
volumes:
postgres-data:
```
```bash
docker compose up -d
```
Open `http://localhost:3000`.
Default credentials:
| Username | Password |
| --- | --- |
| `root` | `123456` |
Change the default password immediately after first login.
## Connect a Node
Prepare a `discovery_token` or node-specific `agent_token` in the console, then run the install script on the node.
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
The script installs Agent under `/opt/openflare-agent`, creates `openflare-agent.service`, and uses Docker OpenResty unless a local `openresty_path` is configured.
## Publish the First Configuration
1. Create a site configuration with a domain and origin URL.
2. Preview the release or check the diff before publishing.
3. Activate the new version.
4. Wait for Agent to discover and apply it through heartbeat.
Version numbers use `YYYYMMDD-NNN`. Historical versions are immutable; rollback reactivates an old version.
+52
View File
@@ -0,0 +1,52 @@
# Run Server
OpenFlare Server is the Gin + GORM control plane. It owns the web console, management API, Agent API, configuration rendering, release publishing, and state storage.
## Requirements
| Item | Requirement |
| --- | --- |
| Go | `1.24+` |
| Node.js | `18+` |
| Database | Writable SQLite path or reachable PostgreSQL instance |
Set `SESSION_SECRET` explicitly in production and prefer PostgreSQL.
## Build Frontend
```bash
cd openflare_server/web
corepack enable
pnpm install
pnpm build
```
## Run from Source
```bash
cd openflare_server
export SESSION_SECRET='replace-with-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
# Optional PostgreSQL:
# export DSN='postgres://openflare:secret@127.0.0.1:5432/openflare?sslmode=disable'
go run .
```
The default port is `3000`.
## Swagger
After logging in, open:
```text
http://localhost:3000/swagger/index.html
```
Regenerate Swagger files locally:
```bash
go install github.com/swaggo/swag/cmd/swag@v1.16.4
cd openflare_server
swag init -g main.go -o docs
```
+47
View File
@@ -0,0 +1,47 @@
# Upgrade and Maintenance
## Server Upgrade
Root users can check and upgrade stable Server releases from the console header. Manual binary upload is also supported.
Preview releases require manual selection. Stable releases are recommended for production.
## Agent Upgrade
Agents follow stable releases by default. Preview upgrades must be triggered manually.
The install script can be re-run for reinstall or upgrade:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
## Data Maintenance
The settings page controls observability cleanup:
| Option | Description |
| --- | --- |
| `DatabaseAutoCleanupEnabled` | Enable daily cleanup |
| `DatabaseAutoCleanupRetentionDays` | Retention days, minimum 1 |
When enabled, Server cleans access logs, metric snapshots, and request reports at 03:00 every day.
## Validation Commands
```bash
cd openflare_server
GOCACHE=/tmp/openflare-go-cache go test ./...
```
```bash
cd openflare_agent
GOCACHE=/tmp/openflare-go-cache go test ./...
```
```bash
cd openflare_server/web
pnpm build
```
+32
View File
@@ -0,0 +1,32 @@
---
layout: home
hero:
name: OpenFlare
text: Self-hosted OpenResty control plane
tagline: Manage reverse proxy rules, configuration releases, node sync, TLS certificates, and basic observability.
actions:
- theme: brand
text: Quick Start
link: /en/guide/quick-start
- theme: alt
text: Design Boundary
link: /en/design/
- theme: alt
text: GitHub
link: https://github.com/Rain-kl/OpenFlare
features:
- icon: 🧭
title: Unified Control Plane
details: Manage sites, domains, origins, certificates, nodes, and release state in one console.
- icon: 🚀
title: Immutable Releases
details: Each publish creates a full OpenResty configuration snapshot that can be previewed, activated, and rolled back.
- icon: 🔁
title: Agent Automation
details: Nodes pull, validate, reload, and roll back to the last runnable configuration on failure.
- icon: 📊
title: Basic Observability
details: Includes request rollups, access analytics, resource snapshots, health events, and node details.
---
+44
View File
@@ -0,0 +1,44 @@
# API Conventions
Management API and Agent API both use JSON.
## Response Shape
Success and failure responses should include a clear `message`:
```json
{
"success": true,
"message": "",
"data": {}
}
```
## Paths
| Type | Convention |
| --- | --- |
| Management API | Authenticated by management Session |
| Agent API | Fixed under `/api/agent/*` |
| Read-only endpoints | `GET` |
| Mutating endpoints | `POST` |
## Authentication
Management endpoints reuse the existing login, role, and Session system.
Agent requests use the node-specific `agent_token`. First-time registration can use a global `discovery_token`. The header is:
```http
X-Agent-Token: <token>
```
Do not log full tokens.
## Swagger
After logging in:
```text
/swagger/index.html
```
+64
View File
@@ -0,0 +1,64 @@
# Commands and Scripts
## Server
```bash
cd openflare_server
export SESSION_SECRET='replace-with-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
go run .
```
```bash
go run . --port 3000 --log-dir ./logs
```
```bash
cd openflare_server
GOCACHE=/tmp/openflare-go-cache go test ./...
```
## Frontend
```bash
cd openflare_server/web
pnpm install
pnpm dev
```
```bash
cd openflare_server/web
pnpm build
```
## Agent
```bash
cd openflare_agent
go run ./cmd/agent -config /path/to/agent.json
```
```bash
cd openflare_agent
go build -o openflare-agent ./cmd/agent
```
```bash
cd openflare_agent
GOCACHE=/tmp/openflare-go-cache go test ./...
```
## Install Agent
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
## Uninstall Agent
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/uninstall-agent.sh | bash
```
+74
View File
@@ -0,0 +1,74 @@
# Configuration
## Server CLI Flags
| Flag | Purpose | Default |
| --- | --- | --- |
| `--port` | Server listen port | `3000` |
| `--log-dir` | Log directory | empty |
| `--version` | Print version and exit | `false` |
| `--help` | Print help and exit | `false` |
## Server Environment Variables
| Variable | Purpose | Default |
| --- | --- | --- |
| `PORT` | Server listen port | `3000` |
| `GIN_MODE` | Gin mode | release unless `debug` |
| `LOG_LEVEL` | Log level | `info` |
| `SESSION_SECRET` | Session signing secret | random on startup |
| `SQLITE_PATH` | SQLite database path | `openflare.db` |
| `DSN` | PostgreSQL DSN, preferred over SQLite | empty |
| `SQL_DSN` | Legacy PostgreSQL DSN, lower priority than `DSN` | empty |
| `REDIS_CONN_STRING` | Redis connection string | empty |
| `UPLOAD_PATH` | Upload directory | `upload` |
| `AGENT_TOKEN` | Legacy global Agent token | empty |
When `DSN` and `SQL_DSN` both exist, `DSN` wins. PostgreSQL is preferred when configured. If PostgreSQL is empty and a local SQLite file exists, Server migrates SQLite data at startup.
## Frontend Build Variables
| Variable | Purpose | Default |
| --- | --- | --- |
| `NEXT_PUBLIC_API_BASE_URL` | Frontend API base path | `/api` |
| `NEXT_PUBLIC_APP_VERSION` | Displayed frontend version | `dev` |
| `NEXT_DEV_BACKEND_URL` | Local dev backend proxy target | `http://127.0.0.1:3000` |
## Runtime Options
The settings page maintains these hot-updatable options:
| Option | Purpose | Default |
| --- | --- | --- |
| `AgentHeartbeatInterval` | Agent heartbeat interval in milliseconds | `10000` |
| `NodeOfflineThreshold` | Node offline threshold in milliseconds | `120000` |
| `AgentUpdateRepo` | Agent update repository | `Rain-kl/OpenFlare` |
| `GeoIPProvider` | Node/IP region provider | `ipinfo` |
| `RegisterEnabled` | Allow new user registration | `false` |
| `PasswordRegisterEnabled` | Allow password registration | `true` |
| `DatabaseAutoCleanupEnabled` | Enable daily observability cleanup | `false` |
| `DatabaseAutoCleanupRetentionDays` | Retention days | `30` |
OpenResty performance and cache options are also stored in the Option table, including `OpenRestyWorkerProcesses`, `OpenRestyWorkerConnections`, `OpenRestyProxyConnectTimeout`, `OpenRestyProxyReadTimeout`, `OpenRestyCacheEnabled`, `OpenRestyCachePath`, and `OpenRestyCacheMaxSize`.
## Agent Configuration
Agent supports the `-config` CLI flag, an `agent.json` file, and the `LOG_LEVEL` environment variable.
| Field | Purpose | Required | Default / behavior |
| --- | --- | --- | --- |
| `server_url` | Control plane URL | yes | none |
| `agent_token` | Node-specific auth token | one of `agent_token` / `discovery_token` | empty |
| `discovery_token` | Global token for first registration | one of `agent_token` / `discovery_token` | empty |
| `node_name` | Node name | no | host name |
| `node_ip` | Node IP | no | auto-detected |
| `openresty_path` | Local OpenResty path | no | empty; Docker mode |
| `openresty_container_name` | Docker container name | no | `openflare-openresty` |
| `openresty_docker_image` | Docker image | no | `openresty/openresty:alpine` |
| `openresty_observability_port` | Local observability port | no | `18081` |
| `docker_binary` | Docker binary name or path | no | `docker` |
| `data_dir` | Agent data directory | no | `data` under config directory |
| `heartbeat_interval` | Heartbeat interval | no | `10000` ms |
| `request_timeout` | HTTP timeout | no | `10000` ms |
`heartbeat_interval` and `request_timeout` accept milliseconds or Go duration strings.
+10
View File
@@ -0,0 +1,10 @@
# Reference
This section collects stable runtime, API, and repository information for deployment, integration, and troubleshooting.
| Page | Content |
| --- | --- |
| [Configuration](./configuration.md) | Server environment variables, CLI flags, runtime options, and Agent config fields |
| [Commands and Scripts](./cli.md) | Startup, build, test, install, and uninstall commands |
| [API Conventions](./api.md) | Management API and Agent API response, auth, and path conventions |
| [Repository Layout](./repository.md) | Responsibilities of `openflare_server`, `openflare_agent`, `openflare_server/web`, and `docs` |
+32
View File
@@ -0,0 +1,32 @@
# Repository Layout
| Path | Responsibility |
| --- | --- |
| `openflare_server` | Gin + GORM + SQLite/PostgreSQL control plane |
| `openflare_server/web` | Next.js 15 App Router admin frontend, statically exported and served by Go Server |
| `openflare_agent` | Go Agent running on nodes |
| `scripts` | Agent install, uninstall, and helper scripts |
| `docs` | VitePress docs site, design baseline, development rules, deployment and configuration docs |
## Server Layers
| Directory | Responsibility |
| --- | --- |
| `controller/` | Parse input, call service, return response |
| `service/` | Business logic, validation, transactions, rendering |
| `model/` | Models, database versioning, migrations |
| `router/` | Route registration |
| `middleware/` | Auth, authorization, rate limiting, cross-cutting logic |
| `common/` | Configuration, global state, initialization |
| `utils/` | Pure helpers |
## Frontend Layers
| Directory | Responsibility |
| --- | --- |
| `app/` | Routes, layouts, page composition |
| `features/` | Business-domain modules |
| `components/` | Cross-feature reusable components |
| `lib/` | API client, env, utilities, constants |
| `store/` | Small cross-page UI state |
| `types/` | Shared types |
+79
View File
@@ -0,0 +1,79 @@
# 接入 Agent
OpenFlare Agent 运行在节点侧,负责注册、心跳、同步配置、写入 OpenResty 文件、校验、reload、失败回滚与自更新。
## 接入方式
Agent 支持两种认证入口:
| 方式 | 适用场景 |
| --- | --- |
| `agent_token` | 已在管理端创建或分配节点,使用节点专属凭证接入 |
| `discovery_token` | 首次自动注册节点,由 Server 置换为节点专属凭证 |
二者至少填写一个。
## 安装脚本
使用 `discovery_token`:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--discovery-token YOUR_DISCOVERY_TOKEN
```
使用节点专属 `agent_token`:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
安装脚本会写入 `/opt/openflare-agent`,创建 `openflare-agent.service`,并可重复执行以重装或升级 Agent。
## 配置文件示例
```json
{
"server_url": "http://127.0.0.1:3000",
"agent_token": "replace-with-node-auth-token",
"data_dir": "./data",
"openresty_container_name": "openflare-openresty",
"openresty_docker_image": "openresty/openresty:alpine",
"openresty_observability_port": 18081,
"observability_replay_minutes": 15,
"heartbeat_interval": 10000,
"request_timeout": 10000
}
```
未配置 `openresty_path` 时,Agent 默认使用 Docker OpenResty。裸 OpenResty 模式需要显式配置本机路径和必要的配置写入目录。
## 源码运行
```bash
cd openflare_agent
export LOG_LEVEL='info'
go run ./cmd/agent -config /path/to/agent.json
```
## 编译后二进制运行
```bash
cd openflare_agent
go build -o openflare-agent ./cmd/agent
export LOG_LEVEL='info'
./openflare-agent -config /path/to/agent.json
```
## 卸载
如需彻底卸载 Agent 并清空本地数据:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/uninstall-agent.sh | bash
```
卸载脚本会停止并移除 `openflare-agent.service`,删除 `/opt/openflare-agent`,并根据配置尝试清理 Docker OpenResty 容器。
+45
View File
@@ -0,0 +1,45 @@
# 发布第一份配置
OpenFlare 的发布链路以完整配置版本为中心。你修改网站配置后,需要生成新版本并激活,Agent 才会在后续 heartbeat 中拉取并应用。
## 创建网站配置
在管理端新增网站配置时至少需要:
| 字段 | 说明 |
| --- | --- |
| 网站名称 | 业务唯一标识;未显式填写时默认使用主域名 |
| 域名 | 至少一个域名,第一项视为主域名 |
| 源站地址 | 合法的 `http://` 或 `https://` 上游地址 |
| 启用状态 | 只有启用的网站配置会参与发布渲染 |
同一个域名只能属于一个网站配置。同一网站内的流量限制、反向代理和缓存配置按站点共享。
## 绑定证书
HTTPS 证书按域名绑定。没有绑定证书的域名不会被自动放入 `443 ssl` server 块。
如果一个网站包含多个域名,发布渲染会按证书分组生成 HTTPS 配置,并确保所有域名仍属于同一站点快照。
## 发布与激活
标准链路:
```text
修改规则 -> 预览/查看 diff -> 发布 -> 生成完整配置版本 -> 激活版本 -> Agent 拉取 -> 本地应用 -> 上报结果
```
发布时 Server 会读取全部启用的网站配置、OpenResty 主配置模板、性能参数与缓存参数,渲染完整 OpenResty 配置,计算 `checksum`,写入 `config_versions`,再切换激活版本。
## 验证结果
发布后在管理端确认:
| 位置 | 期望结果 |
| --- | --- |
| 节点列表 | 节点在线 |
| 节点详情 | 当前版本与激活版本一致 |
| 应用记录 | 最近一次应用成功 |
| 版本页面 | 新版本处于激活状态 |
如果目标版本应用失败并回滚,Agent 会在本地阻断同一 `version + checksum` 的重复应用,直到控制面激活版本或 checksum 发生变化。
+13
View File
@@ -0,0 +1,13 @@
# 指南
本部分面向使用者和部署者,帮助你把 OpenFlare 从首次启动推进到第一份可运行的代理配置。
推荐阅读顺序:
1. [快速开始](./quick-start.md):用 Docker Compose 启动 Server,并完成首次登录。
2. [启动 Server](./server.md):了解源码启动、前端构建和 Swagger 入口。
3. [接入 Agent](./agent.md):选择 `agent_token` 或 `discovery_token`,让节点上线。
4. [发布第一份配置](./first-site.md):创建网站配置,发布并确认节点应用。
5. [升级与维护](./upgrade.md):了解升级、卸载、验证和日常维护入口。
如果你要参与开发,先阅读 [设计](../design/) 与 [开发约束](../design/development.md),再进入代码修改。
+87
View File
@@ -0,0 +1,87 @@
# 快速开始
OpenFlare 的最小运行单元包含一个 Server 和至少一个 Agent。Server 负责管理端、配置版本与节点状态,Agent 运行在代理节点上,负责写入 OpenResty 配置并 reload。
## 启动 Server
推荐使用 PostgreSQL 与 Docker Compose:
```yaml
services:
postgres:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_DB: openflare
POSTGRES_USER: openflare
POSTGRES_PASSWORD: replace-with-strong-password
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U openflare -d openflare"]
interval: 10s
timeout: 5s
retries: 5
openflare:
image: ghcr.io/rain-kl/openflare:latest
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
ports:
- "3000:3000"
environment:
SESSION_SECRET: replace-with-random-string
DSN: postgres://openflare:replace-with-strong-password@postgres:5432/openflare?sslmode=disable
GIN_MODE: release
LOG_LEVEL: info
volumes:
postgres-data:
```
```bash
docker compose up -d
```
访问 `http://localhost:3000`。
默认账号:
| 用户名 | 密码 |
| --- | --- |
| `root` | `123456` |
首次登录后请立即修改默认密码,并按需关闭新用户注册。
## 接入第一个节点
在管理端准备 `discovery_token` 或节点专属 `agent_token`,然后在节点上执行安装脚本。
使用 `discovery_token`:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--discovery-token YOUR_DISCOVERY_TOKEN
```
使用节点专属 `agent_token`:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
安装脚本默认把 Agent 放在 `/opt/openflare-agent`,创建 `openflare-agent.service`,并在未显式配置本机 OpenResty 时使用 Docker OpenResty。
## 发布第一份配置
1. 在管理端新增网站配置,填写域名与源站地址。
2. 发布前查看预览或变更摘要。
3. 激活新版本。
4. 等待 Agent 通过 heartbeat 发现版本变更并应用。
版本号格式为 `YYYYMMDD-NNN`。历史版本不可变,回滚通过重新激活旧版本完成。
+66
View File
@@ -0,0 +1,66 @@
# 启动 Server
OpenFlare Server 是 Gin + GORM 单体控制面,负责管理端 UI、管理 API、Agent API、配置渲染、版本发布与状态存储。
## 前置条件
| 项目 | 要求 |
| --- | --- |
| Go | `1.24+` |
| Node.js | `18+` |
| 数据库 | SQLite 文件目录可写,或可访问的 PostgreSQL 实例 |
生产环境建议显式配置 `SESSION_SECRET`,并优先使用 PostgreSQL。
## 构建管理端前端
```bash
cd openflare_server/web
corepack enable
pnpm install
pnpm build
```
`pnpm build` 会生成供 Go Server 托管的静态产物。
## 源码启动
```bash
cd openflare_server
export SESSION_SECRET='replace-with-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
# 可选:设置后优先使用 PostgreSQL。
# export DSN='postgres://openflare:secret@127.0.0.1:5432/openflare?sslmode=disable'
go run .
```
默认监听 `3000` 端口。也可以通过命令行指定:
```bash
go run . --port 3000 --log-dir ./logs
```
## 首次登录
访问 `http://localhost:3000`。
| 用户名 | 密码 |
| --- | --- |
| `root` | `123456` |
## Swagger
登录管理端后访问:
```text
http://localhost:3000/swagger/index.html
```
如需在本地重新生成 Swagger 文档:
```bash
go install github.com/swaggo/swag/cmd/swag@v1.16.4
cd openflare_server
swag init -g main.go -o docs
```
+53
View File
@@ -0,0 +1,53 @@
# 升级与维护
## Server 升级
Root 用户可以在管理端顶栏检查并升级 Server 正式版。也可以通过上传 Server 二进制的方式执行确认升级。
如需尝试 preview 版本,可手动检查对应发布。生产环境建议优先使用正式版。
## Agent 升级
节点 Agent 默认只跟随正式版自动更新。preview 升级需要手动触发。
安装脚本可重复执行,用于重装或升级 Agent:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
## 数据维护
管理端设置页可以维护观测数据自动清理策略:
| 配置项 | 说明 |
| --- | --- |
| `DatabaseAutoCleanupEnabled` | 是否启用每日自动清理 |
| `DatabaseAutoCleanupRetentionDays` | 自动清理保留天数,至少 1 天 |
开启后,Server 会在每天凌晨 3 点清理访问日志、指标快照与请求报告。
## 常用验证命令
Server:
```bash
cd openflare_server
GOCACHE=/tmp/openflare-go-cache go test ./...
```
Agent:
```bash
cd openflare_agent
GOCACHE=/tmp/openflare-go-cache go test ./...
```
Frontend:
```bash
cd openflare_server/web
pnpm build
```
+32
View File
@@ -0,0 +1,32 @@
---
layout: home
hero:
name: OpenFlare
text: 自托管 OpenResty 控制面
tagline: 管理反向代理规则、配置发布、节点同步、TLS 证书与基础观测。
actions:
- theme: brand
text: 快速开始
link: /guide/quick-start
- theme: alt
text: 设计边界
link: /design/
- theme: alt
text: GitHub
link: https://github.com/Rain-kl/OpenFlare
features:
- icon: 🧭
title: 统一控制面
details: 在一个管理端维护网站、域名、源站、证书、节点与版本状态。
- icon: 🚀
title: 不可变发布
details: 每次发布生成完整 OpenResty 配置快照,可预览、激活和回滚。
- icon: 🔁
title: Agent 自动应用
details: 节点侧自动拉取、校验、reload,并在失败时回滚到可运行配置。
- icon: 📊
title: 基础观测
details: 提供请求聚合、访问分析、资源快照、健康事件与节点详情。
---
+31
View File
@@ -0,0 +1,31 @@
{
"$schema": "./node_modules/@lunariajs/core/config.schema.json",
"repository": {
"name": "Rain-kl/OpenFlare",
"rootDir": "docs"
},
"files": [
{
"location": "**/config.ts",
"pattern": "@lang/@path",
"type": "universal"
},
{
"location": "**/*.md",
"pattern": "@lang/@path",
"type": "universal"
}
],
"defaultLocale": {
"label": "简体中文",
"lang": "zh"
},
"locales": [
{
"label": "English",
"lang": "en"
}
],
"outDir": ".vitepress/dist/_translations",
"ignoreKeywords": ["lunaria-ignore"]
}
+20
View File
@@ -0,0 +1,20 @@
{
"name": "openflare-docs",
"private": true,
"type": "module",
"scripts": {
"dev": "vitepress dev",
"build": "vitepress build",
"preview": "vitepress preview",
"lunaria:build": "lunaria build",
"lunaria:open": "open-cli .vitepress/dist/_translations/index.html"
},
"devDependencies": {
"@lunariajs/core": "^0.1.1",
"markdown-it-mathjax3": "^4.3.2",
"open-cli": "^8.0.0",
"postcss-rtlcss": "^5.7.1",
"vitepress": "2.0.0-alpha.17",
"vitepress-plugin-llms": "^1.11.0"
}
}
+2940
View File
File diff suppressed because it is too large Load Diff
+46
View File
@@ -0,0 +1,46 @@
# API 约定
OpenFlare 的管理端 API 与 Agent API 都使用 JSON。
## 响应结构
成功与失败都应返回清晰的 `message`:
```json
{
"success": true,
"message": "",
"data": {}
}
```
## 路径约定
| 类型 | 约定 |
| --- | --- |
| 管理端 API | 由管理端 Session 鉴权 |
| Agent API | 固定放在 `/api/agent/*` |
| 只读接口 | 使用 `GET` |
| 变更类接口 | 使用 `POST` |
## 鉴权
管理端继续复用现有登录、角色与 Session。
Agent 正式请求统一使用节点专属 `agent_token`,首次接入可使用全局 `discovery_token`。Agent 请求头固定为:
```http
X-Agent-Token: <token>
```
日志中不得打印完整 Token。
## Swagger
登录管理端后可访问:
```text
/swagger/index.html
```
Swagger 文件位于 `openflare_server/docs`,由 `swag init` 生成。
+90
View File
@@ -0,0 +1,90 @@
# 命令与脚本
## Server
源码启动:
```bash
cd openflare_server
export SESSION_SECRET='replace-with-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
go run .
```
指定监听端口与日志目录:
```bash
go run . --port 3000 --log-dir ./logs
```
测试:
```bash
cd openflare_server
GOCACHE=/tmp/openflare-go-cache go test ./...
```
## Frontend
开发:
```bash
cd openflare_server/web
pnpm install
pnpm dev
```
构建静态产物:
```bash
cd openflare_server/web
pnpm build
```
## Agent
源码运行:
```bash
cd openflare_agent
go run ./cmd/agent -config /path/to/agent.json
```
编译:
```bash
cd openflare_agent
go build -o openflare-agent ./cmd/agent
```
测试:
```bash
cd openflare_agent
GOCACHE=/tmp/openflare-go-cache go test ./...
```
## 安装 Agent
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
## 卸载 Agent
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/uninstall-agent.sh | bash
```
## Swagger
重新生成 Swagger 文档:
```bash
go install github.com/swaggo/swag/cmd/swag@v1.16.4
cd openflare_server
swag init -g main.go -o docs
```
+86
View File
@@ -0,0 +1,86 @@
# 配置项
## Server 命令行参数
| 参数 | 作用 | 默认值 |
| --- | --- | --- |
| `--port` | 指定 Server 监听端口 | `3000` |
| `--log-dir` | 指定日志目录 | 空 |
| `--version` | 输出当前版本后退出 | `false` |
| `--help` | 输出帮助信息后退出 | `false` |
## Server 环境变量
| 环境变量 | 作用 | 默认值 |
| --- | --- | --- |
| `PORT` | Server 监听端口 | `3000` |
| `GIN_MODE` | Gin 运行模式 | 非 `debug` 时按 release |
| `LOG_LEVEL` | 日志等级 | `info` |
| `SESSION_SECRET` | Session 签名密钥 | 启动时随机生成 |
| `SQLITE_PATH` | SQLite 数据库文件路径 | `openflare.db` |
| `DSN` | PostgreSQL DSN,设置后优先于 SQLite | 空 |
| `SQL_DSN` | 兼容旧命名的 PostgreSQL DSN,优先级低于 `DSN` | 空 |
| `REDIS_CONN_STRING` | Redis 连接串 | 空 |
| `UPLOAD_PATH` | 上传目录 | `upload` |
| `AGENT_TOKEN` | 兼容旧部署的全局 Agent Token | 空 |
`DSN` 与 `SQL_DSN` 同时存在时优先使用 `DSN`。配置 PostgreSQL 后,Server 优先使用 PostgreSQL;当目标 PostgreSQL 为空且本地 SQLite 文件存在时,启动阶段会自动迁移 SQLite 数据。
## 前端构建环境变量
| 环境变量 | 作用 | 默认值 |
| --- | --- | --- |
| `NEXT_PUBLIC_API_BASE_URL` | 前端请求 API 的基础路径 | `/api` |
| `NEXT_PUBLIC_APP_VERSION` | 前端展示版本号 | `dev` |
| `NEXT_DEV_BACKEND_URL` | 本地开发服务器代理的后端地址 | `http://127.0.0.1:3000` |
## 运行时 Option
以下配置由管理端设置页维护,可热更新:
| 配置项 | 作用 | 默认值 |
| --- | --- | --- |
| `AgentHeartbeatInterval` | Agent 心跳间隔,毫秒 | `10000` |
| `NodeOfflineThreshold` | 节点离线阈值,毫秒 | `120000` |
| `AgentUpdateRepo` | Agent 自更新仓库 | `Rain-kl/OpenFlare` |
| `GeoIPProvider` | 节点/IP 归属解析方式 | `ipinfo` |
| `RegisterEnabled` | 是否允许新用户注册 | `false` |
| `PasswordRegisterEnabled` | 是否允许通过密码方式注册 | `true` |
| `DatabaseAutoCleanupEnabled` | 是否启用每日自动清理观测数据 | `false` |
| `DatabaseAutoCleanupRetentionDays` | 自动清理保留天数 | `30` |
| `GlobalApiRateLimitNum` / `GlobalApiRateLimitDuration` | 全局 API 限流次数 / 时间窗口 | `300` / `180` |
| `GlobalWebRateLimitNum` / `GlobalWebRateLimitDuration` | 全局 Web 限流次数 / 时间窗口 | `300` / `180` |
| `UploadRateLimitNum` / `UploadRateLimitDuration` | 上传接口限流次数 / 时间窗口 | `50` / `60` |
| `DownloadRateLimitNum` / `DownloadRateLimitDuration` | 下载接口限流次数 / 时间窗口 | `50` / `60` |
| `CriticalRateLimitNum` / `CriticalRateLimitDuration` | 敏感接口限流次数 / 时间窗口 | `100` / `1200` |
OpenResty 性能参数与缓存参数也保存在 Option 表,常用项包括 `OpenRestyWorkerProcesses`、`OpenRestyWorkerConnections`、`OpenRestyProxyConnectTimeout`、`OpenRestyProxyReadTimeout`、`OpenRestyCacheEnabled`、`OpenRestyCachePath` 与 `OpenRestyCacheMaxSize`。
## Agent 配置
Agent 支持 `-config` 命令行参数、`agent.json` 配置文件和 `LOG_LEVEL` 环境变量。
| 字段 | 作用 | 是否必填 | 默认值/行为 |
| --- | --- | --- | --- |
| `server_url` | 控制面地址 | 是 | 无 |
| `agent_token` | 节点专属认证 Token | 与 `discovery_token` 二选一 | 空 |
| `discovery_token` | 首次自动注册使用的全局 Token | 与 `agent_token` 二选一 | 空 |
| `node_name` | 节点名称 | 否 | 自动使用主机名 |
| `node_ip` | 节点 IP | 否 | 自动探测 |
| `openresty_path` | 本机 OpenResty 路径 | 否 | 空,未设置时走 Docker 模式 |
| `openresty_container_name` | Docker 模式下的容器名 | 否 | `openflare-openresty` |
| `openresty_docker_image` | Docker 模式下的镜像 | 否 | `openresty/openresty:alpine` |
| `openresty_observability_port` | 本地观测端口 | 否 | `18081` |
| `docker_binary` | Docker 可执行文件名或路径 | 否 | `docker` |
| `data_dir` | Agent 数据目录 | 否 | 配置文件所在目录下的 `data` |
| `main_config_path` | OpenResty 主配置写入路径 | 否 | 本机模式建议显式配置 |
| `route_config_path` | 路由配置写入路径 | 否 | `data_dir/etc/nginx/conf.d/openflare_routes.conf` |
| `cert_dir` | 本机证书写入目录 | 否 | `data_dir/etc/nginx/certs` |
| `lua_dir` | 本机 Lua 脚本写入目录 | 否 | `data_dir/etc/nginx/lua` |
| `observability_buffer_path` | 观测补报缓冲文件路径 | 否 | `data_dir/var/lib/openflare/observability-buffer.json` |
| `observability_replay_minutes` | 自动补传最近观测窗口分钟数 | 否 | `15` |
| `state_path` | Agent 本地状态文件路径 | 否 | `data_dir/var/lib/openflare/agent-state.json` |
| `heartbeat_interval` | 心跳间隔 | 否 | `10000` 毫秒 |
| `request_timeout` | HTTP 请求超时 | 否 | `10000` 毫秒 |
`heartbeat_interval` 与 `request_timeout` 支持毫秒整数或 Go duration 字符串。
+10
View File
@@ -0,0 +1,10 @@
# 参考
本部分收敛运行、接口与仓库层面的稳定信息,适合部署、联调和排查时快速查阅。
| 页面 | 内容 |
| --- | --- |
| [配置项](./configuration.md) | Server 环境变量、命令行参数、运行时 Option 与 Agent 配置字段 |
| [命令与脚本](./cli.md) | 常用启动、构建、测试、安装和卸载命令 |
| [API 约定](./api.md) | 管理端 API 与 Agent API 的响应结构、鉴权和路径约定 |
| [仓库结构](./repository.md) | `openflare_server`、`openflare_agent`、`openflare_server/web` 与 `docs` 的职责 |
+45
View File
@@ -0,0 +1,45 @@
# 仓库结构
| 路径 | 职责 |
| --- | --- |
| `openflare_server` | Gin + GORM + SQLite/PostgreSQL 单体控制面 |
| `openflare_server/web` | Next.js 15 App Router 管理端前端,静态导出后由 Go Server 托管 |
| `openflare_agent` | Go 单体 Agent,运行在节点侧 |
| `scripts` | Agent 安装、卸载等辅助脚本 |
| `docs` | VitePress 文档站、设计基线、开发规范、部署与配置文档 |
## Server 分层
| 目录 | 职责 |
| --- | --- |
| `controller/` | 参数解析、调用 service、返回响应 |
| `service/` | 业务逻辑、校验、事务编排、配置渲染 |
| `model/` | 模型定义、数据库版本与迁移 |
| `router/` | 路由注册 |
| `middleware/` | 认证、鉴权、限流等横切逻辑 |
| `common/` | 配置、全局状态与初始化入口 |
| `utils/` | 纯工具函数与通用 helper |
## Agent 模块
| 模块 | 职责 |
| --- | --- |
| `config` | 配置读取与默认值 |
| `heartbeat` | 心跳与版本摘要判断 |
| `sync` | 配置拉取与应用编排 |
| `nginx` / `openresty` | OpenResty 文件写入、校验、reload 与 Docker 模式管理 |
| `state` | 本地状态与观测补报缓冲 |
| `httpclient` | Server 通信 |
| `protocol` | Agent API 协议类型 |
| `internal/updater` | Agent 自更新 |
## Frontend 分层
| 目录 | 职责 |
| --- | --- |
| `app/` | 路由、布局、页面组装 |
| `features/` | 按业务域组织模块 |
| `components/` | 跨 feature 复用组件 |
| `lib/` | 请求客户端、环境变量、工具函数、常量 |
| `store/` | 少量跨页面 UI 状态 |
| `types/` | 共享类型定义 |