diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml
index b0d7c773..15c0b0f1 100644
--- a/.github/workflows/docker-image.yml
+++ b/.github/workflows/docker-image.yml
@@ -1,63 +1,133 @@
-name: Docker image builds
-
-on:
- workflow_dispatch:
- push:
- tags: ["v*"]
-
-permissions:
- contents: read
- packages: write
- attestations: write
- id-token: write
-
-jobs:
- build:
- runs-on: ubuntu-24.04
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
- with:
- fetch-tags: true
- fetch-depth: 0
- persist-credentials: false
-
- - name: Set lowercase image name
- id: meta
- shell: bash
- run: |
- echo "image=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT"
- echo "version=$(git describe --tags)" >> "$GITHUB_OUTPUT"
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Log into registry
+name: Docker image builds
+
+on:
+ workflow_dispatch:
+ push:
+ tags: ["v*"]
+
+permissions:
+ contents: read
+ packages: write
+ attestations: write
+ id-token: write
+
+jobs:
+ build:
+ name: Build (${{ matrix.arch }})
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - arch: amd64
+ platform: linux/amd64
+ runner: ubuntu-24.04
+ - arch: arm64
+ platform: linux/arm64
+ runner: ubuntu-24.04-arm
+ runs-on: ${{ matrix.runner }}
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ fetch-tags: true
+ fetch-depth: 0
+ persist-credentials: false
+
+ - name: Set image metadata
+ shell: bash
+ run: |
+ echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV"
+ echo "VERSION=$(git describe --tags)" >> "$GITHUB_ENV"
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log into registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- - name: Build and push
- id: build
- uses: docker/build-push-action@v6
- with:
- context: ./atsf_server
- file: ./atsf_server/Dockerfile
- push: true
- tags: |
- ${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.version }}
- ${{ steps.meta.outputs.image }}:latest
- build-args: |
- VERSION=${{ steps.meta.outputs.version }}
- cache-from: type=gha
- cache-to: type=gha,mode=max
- platforms: linux/amd64,linux/arm64
-
- - name: Generate artifact attestation
- uses: actions/attest-build-provenance@v3
- with:
- subject-name: ${{ steps.meta.outputs.image }}
- subject-digest: ${{ steps.build.outputs.digest }}
- push-to-registry: true
+ - name: Build and push
+ id: build
+ uses: docker/build-push-action@v6
+ with:
+ context: ./atsf_server
+ file: ./atsf_server/Dockerfile
+ platforms: ${{ matrix.platform }}
+ outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
+ build-args: |
+ VERSION=${{ env.VERSION }}
+ cache-from: type=gha,scope=docker-${{ matrix.arch }}
+ cache-to: type=gha,mode=max,scope=docker-${{ matrix.arch }}
+
+ - name: Export digest
+ shell: bash
+ run: |
+ mkdir -p /tmp/digests
+ touch "/tmp/digests/${DIGEST#sha256:}"
+ env:
+ DIGEST: ${{ steps.build.outputs.digest }}
+
+ - name: Upload digest
+ uses: actions/upload-artifact@v4
+ with:
+ name: digests-${{ matrix.arch }}
+ path: /tmp/digests/*
+ if-no-files-found: error
+ retention-days: 1
+
+ - name: Generate artifact attestation
+ uses: actions/attest-build-provenance@v3
+ with:
+ subject-name: ${{ env.IMAGE }}
+ subject-digest: ${{ steps.build.outputs.digest }}
+ push-to-registry: true
+
+ merge:
+ name: Merge multi-arch manifest
+ runs-on: ubuntu-24.04
+ needs: build
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ fetch-tags: true
+ fetch-depth: 0
+ persist-credentials: false
+
+ - name: Set image metadata
+ shell: bash
+ run: |
+ echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV"
+ echo "VERSION=$(git describe --tags)" >> "$GITHUB_ENV"
+
+ - name: Download digests
+ uses: actions/download-artifact@v4
+ with:
+ path: /tmp/digests
+ pattern: digests-*
+ merge-multiple: true
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log into registry
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.repository_owner }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Create and push manifest list
+ working-directory: /tmp/digests
+ shell: bash
+ run: |
+ docker buildx imagetools create \
+ -t "${IMAGE}:${VERSION}" \
+ -t "${IMAGE}:latest" \
+ $(printf '%s@sha256:%s ' "${IMAGE}" *)
+
+ - name: Inspect image
+ run: docker buildx imagetools inspect "${IMAGE}:${VERSION}"
diff --git a/README.md b/README.md
index 8dddd465..aed2013d 100644
--- a/README.md
+++ b/README.md
@@ -1,146 +1,301 @@
-
- 中文 | English
-
-
-[//]: # ()
-
-[//]: # (
)
-
-[//]: # (
)
-
-
-
-# ATSFlare
-
-_✨ control plane for reverse proxy management ✨_
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-[//]: # ()
-
-[//]: # ( Download)
-
-[//]: # ( ·)
-
-[//]: # ( Tutorial)
-
-[//]: # ( ·)
-
-[//]: # ( Feedback)
-
-[//]: # (
)
-
-
-
-## 仓库结构
-
-- `atsf_server`: Gin + GORM + SQLite 的控制中心,包含管理端 API、Agent API 和 Web 管理台
-- `atsf_agent`: Go 单体 Agent,负责注册、心跳、同步配置、写入 Nginx 路由文件并 reload
-- `docs`: 设计、开发规范、开发计划和部署联调文档
-
-
-## 快速开始
-
-### 1. 启动 Server
-
-可直接使用 GHCR 镜像通过 Docker Compose 启动控制面:
-
-```yaml
-services:
- atsflare:
- image: ghcr.io/rain-kl/atsflare:latest
- container_name: atsflare
- restart: unless-stopped
- ports:
- - "3000:3000"
- environment:
- SESSION_SECRET: replace-with-random-string
- SQLITE_PATH: /data/atsflare.db
- GIN_MODE: release
- volumes:
- - atsflare-data:/data
-
-volumes:
- atsflare-data:
-```
-
-```bash
-docker compose up -d
-```
-
-默认访问地址:`http://localhost:3000`。
-
-- [docs/deployment.md](./docs/deployment.md)
-
-
-### 2. 使用 Discovery Token 一键部署 Agent
-
-适用于新节点首次接入,Agent 会使用全局 `discovery_token` 自动注册并换取节点专属 `agent_token`。
-
-```bash
-curl -fsSL https://raw.githubusercontent.com/Rain-kl/ATSFlare/main/scripts/install-agent.sh | bash -s -- \
- --server-url http://your-server:3000 \
- --discovery-token YOUR_DISCOVERY_TOKEN
-```
-
-### 3. 使用 Agent Token 一键部署 Agent
-
-适用于已经在管理端预创建节点、并拿到节点专属 `agent_token` 的场景。
-
-```bash
-curl -fsSL https://raw.githubusercontent.com/Rain-kl/ATSFlare/main/scripts/install-agent.sh | bash -s -- \
- --server-url http://your-server:3000 \
- --agent-token YOUR_AGENT_TOKEN
-```
-
+
+ 中文 | English
+
+
+
+

+
+# ATSFlare
+
+轻量、自托管的反向代理控制面,用于管理 Nginx 配置发布、节点同步、TLS 证书与版本回滚。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## 项目定位
+
+ATSFlare 当前定位为内部自用的反向代理控制面,不面向外部租户提供 CDN SaaS 能力。
+
+它解决的是一套更直接的运维问题:
+
+* 在管理端维护域名到源站的反代规则
+* 生成完整 Nginx 配置并发布激活版本
+* 让节点侧 Agent 自动拉取、校验、reload 与失败回滚
+* 托管 TLS 证书、管理节点与版本状态
+* 用更统一的 Web UI 完成日常运维操作
+
+当前明确不做多租户、复杂缓存平台、对象存储依赖、灰度分组发布等平台化扩展。详细边界见 [docs/design.md](./docs/design.md)。
+
+## 核心能力
+
+* 反向代理规则管理:一个域名对应一个源站地址,统一维护、统一发布
+* 配置版本化:支持预览、发布、激活、历史回滚,版本不可变
+* 节点接入:支持全局 `discovery_token` 首次接入,也支持节点专属 `agent_token`
+* Agent 自动应用:周期性同步、落盘、`nginx -t`、`nginx -s reload`、失败自动回滚
+* TLS 与域名管理:支持证书托管、域名资产维护、精确匹配与通配符匹配
+* 运维能力:配置变更摘要、Agent 运行参数下发、Agent 自更新、Server 自升级
+* 管理端 UI:基于 Next.js App Router + React 19 + Tailwind CSS 4 的新版前端
+
+## 界面预览
+
+以下图片当前为占位文件,后续你可以直接替换同名文件:
+
+* `docs/assets/readme/dashboard-overview.svg`
+* `docs/assets/readme/node-detail.svg`
+* `docs/assets/readme/version-release.svg`
+
+### 仪表盘总览
+
+
+
+### 节点详情与安装命令
+
+
+
+### 配置发布与版本管理
+
+
+
+## 系统架构
+
+```text
+ATSFlare Server (Gin + GORM + SQLite + Web UI)
+ |
+ | HTTP API / Config Pull
+ v
+ATSFlare Agent (register / heartbeat / sync / apply / update)
+ |
+ v
+Local Nginx or Docker Nginx
+ |
+ v
+Origin
+```
+
+职责划分:
+
+* `atsf_server`:管理端 UI、管理 API、Agent API、配置渲染、发布与激活、状态存储
+* `atsf_agent`:节点注册、心跳、同步、本地文件写入、Nginx 校验、reload、回滚、自更新
+* `atsf_server/web`:新版管理端前端,静态导出后由 Go Server 托管
+
+## 仓库结构
+
+* `atsf_server`:Gin + GORM + SQLite 单体控制面
+* `atsf_server/web`:Next.js 15 App Router 管理端前端
+* `atsf_agent`:Go 单体 Agent
+* `scripts`:安装脚本与辅助脚本
+* `docs`:设计、开发规范、部署、配置项等文档
+
+## 快速开始
+
+### 1. 通过 Docker Compose 启动 Server
+
+```yaml
+services:
+ atsflare:
+ image: ghcr.io/rain-kl/atsflare:latest
+ container_name: atsflare
+ restart: unless-stopped
+ ports:
+ - "3000:3000"
+ environment:
+ SESSION_SECRET: replace-with-random-string
+ SQLITE_PATH: /data/atsflare.db
+ GIN_MODE: release
+ PORT: "3000"
+ volumes:
+ - atsflare-data:/data
+
+volumes:
+ atsflare-data:
+```
+
+```bash
+docker compose up -d
+```
+
+访问地址:`http://localhost:3000`
+
+默认账号:
+
+* 用户名:`root`
+* 密码:`123456`
+
+### 2. 使用 Discovery Token 一键接入 Agent
+
+适用于新节点首次接入,Agent 会自动注册并换取节点专属 `agent_token`。
+
+```bash
+curl -fsSL https://raw.githubusercontent.com/Rain-kl/ATSFlare/main/scripts/install-agent.sh | bash -s -- \
+ --server-url http://your-server:3000 \
+ --discovery-token YOUR_DISCOVERY_TOKEN
+```
+
+### 3. 使用 Agent Token 一键接入 Agent
+
+适用于已经在管理端预创建节点、并拿到节点专属 `agent_token` 的场景。
+
+```bash
+curl -fsSL https://raw.githubusercontent.com/Rain-kl/ATSFlare/main/scripts/install-agent.sh | bash -s -- \
+ --server-url http://your-server:3000 \
+ --agent-token YOUR_AGENT_TOKEN
+```
+
说明:
* `--server-url` 替换为实际控制面地址,例如 `http://192.168.1.10:3000`
-* Linux 默认安装到 `/opt/atsflare-agent`,并创建 `atsflare-agent` systemd 服务
-* 重复执行相同命令可用于升级 Agent 到最新 Release
-* Root 用户可在管理端顶栏点击“版本”检查最新 Release,并在 Release 二进制部署场景下直接触发 Server 自升级
-
-
-## 部署说明
-
-当前仓库的交付形式:
-
-* Server 二进制发布到 GitHub Releases
-* Server Docker 镜像发布到 GitHub Container Registry:`ghcr.io/rain-kl/atsflare`
-* Agent 二进制发布到 GitHub Releases
-
-详细文档:
-
-* [docs/deployment.md](./docs/deployment.md)
-* [docs/design.md](./docs/design.md)
-
-
-## 贡献
-
-参与开发请先阅读:
-
-1. [docs/design.md](./docs/design.md)
-2. [docs/development-guidelines.md](./docs/development-guidelines.md)
-3. [docs/development-plan.md](./docs/development-plan.md)
-
-前端开发补充:
-
-* 新版管理端位于 `atsf_server/web`
-* 前端包管理器统一使用 `pnpm`
-* 构建命令为 `pnpm build`,产物输出到 `atsf_server/web/build`
-
+* 默认安装目录为 `/opt/atsflare-agent`
+* 脚本会创建 `atsflare-agent.service` 并启动 systemd 服务
+* 重复执行安装命令可用于升级 Agent 到最新 Release
+
+## 典型使用流程
+
+1. 启动 Server 并登录管理端
+2. 新增或编辑反代规则
+3. 预览配置或查看变更摘要
+4. 发布并激活新的配置版本
+5. Agent 在后续同步中拉取激活版本
+6. Agent 本地执行 `nginx -t`
+7. 校验成功后执行 `nginx -s reload`
+8. 若失败则自动回滚并上报最终结果
+
+版本号格式固定为 `YYYYMMDD-NNN`,历史版本不可变,回滚通过重新激活旧版本实现。
+
+## 部署与交付
+
+当前仓库的交付形式:
+
+* Server 二进制发布到 GitHub Releases
+* Server Docker 镜像发布到 GitHub Container Registry:`ghcr.io/rain-kl/atsflare`
+* Agent 二进制发布到 GitHub Releases
+
+Docker 镜像工作流仅构建 `atsf_server`,并产出 `linux/amd64` 与 `linux/arm64` 多架构镜像。
+
+## 常用配置
+
+### Server 环境变量
+
+| 环境变量 | 作用 | 默认值 |
+| --- | --- | --- |
+| `PORT` | Server 监听端口 | `3000` |
+| `GIN_MODE` | Gin 运行模式 | 非 `debug` 时按 release |
+| `SESSION_SECRET` | Session 签名密钥 | 启动时随机生成 |
+| `SQLITE_PATH` | SQLite 数据库文件路径 | `atsflare.db` |
+| `SQL_DSN` | MySQL DSN,设置后优先于 SQLite | 空 |
+| `UPLOAD_PATH` | 上传目录 | `upload` |
+
+### 前端构建变量
+
+| 环境变量 | 作用 | 默认值 |
+| --- | --- | --- |
+| `NEXT_PUBLIC_API_BASE_URL` | 前端请求 API 的基础路径 | `/api` |
+| `NEXT_PUBLIC_APP_VERSION` | 前端展示版本号 | `dev` |
+
+### Agent 核心配置
+
+| 字段 | 作用 |
+| --- | --- |
+| `server_url` | 控制面地址 |
+| `agent_token` | 节点专属认证 Token |
+| `discovery_token` | 首次自动注册使用的全局 Token |
+| `data_dir` | Agent 托管数据目录 |
+| `nginx_path` | 本机 Nginx 路径,设置后走本机模式 |
+| `nginx_container_name` | Docker 模式下的 Nginx 容器名 |
+
+完整配置项说明见 [docs/app-config.md](./docs/app-config.md)。
+
+## 本地开发
+
+### Server
+
+```bash
+cd atsf_server
+export SESSION_SECRET='replace-with-random-string'
+export SQLITE_PATH='./atsflare.db'
+go run .
+```
+
+### Frontend
+
+```bash
+cd atsf_server/web
+corepack enable
+pnpm install
+pnpm build
+```
+
+### Agent
+
+```bash
+cd atsf_agent
+go run ./cmd/agent -config /path/to/agent.json
+```
+
+### 常用验证命令
+
+```bash
+cd atsf_server
+GOCACHE=/tmp/atsflare-go-cache go test ./...
+```
+
+```bash
+cd atsf_agent
+GOCACHE=/tmp/atsflare-go-cache go test ./...
+```
+
+## 文档导航
+
+建议按以下顺序阅读:
+
+1. [docs/design.md](./docs/design.md)
+2. [docs/development-guidelines.md](./docs/development-guidelines.md)
+3. [docs/development-plan.md](./docs/development-plan.md)
+4. [docs/frontend-revamp-plan.md](./docs/frontend-revamp-plan.md)
+5. [docs/frontend-development-guidelines.md](./docs/frontend-development-guidelines.md)
+6. [docs/deployment.md](./docs/deployment.md)
+7. [docs/app-config.md](./docs/app-config.md)
+
+## 管理端与接口
+
+管理端当前覆盖:
+
+* 反代规则
+* 配置版本
+* 节点管理
+* 应用记录
+* TLS 证书
+* 域名管理
+* 用户管理
+* 设置
+* 版本更新
+
+登录管理端后,可访问 Swagger UI:`/swagger/index.html`
+
+## 贡献开发
+
+参与开发前请先阅读:
+
+* [docs/design.md](./docs/design.md)
+* [docs/development-guidelines.md](./docs/development-guidelines.md)
+* [docs/frontend-development-guidelines.md](./docs/frontend-development-guidelines.md)
+
+约束摘要:
+
+* 超出设计边界的改动,先更新设计文档再编码
+* Server 继续保持单体结构,不为简单需求引入额外基础设施
+* 前端统一位于 `atsf_server/web`,请求层统一收敛到 `lib/api/`
+* 新代码默认遵循当前正式基线,不回退到旧版 CRA / Semantic UI 结构
diff --git a/docs/assets/readme/dashboard-overview.png b/docs/assets/readme/dashboard-overview.png
new file mode 100644
index 00000000..100eebd1
Binary files /dev/null and b/docs/assets/readme/dashboard-overview.png differ
diff --git a/docs/assets/readme/node-detail.png b/docs/assets/readme/node-detail.png
new file mode 100644
index 00000000..fc75500f
Binary files /dev/null and b/docs/assets/readme/node-detail.png differ
diff --git a/docs/assets/readme/version-release.png b/docs/assets/readme/version-release.png
new file mode 100644
index 00000000..8cb3d4e4
Binary files /dev/null and b/docs/assets/readme/version-release.png differ
diff --git a/docs/deployment.md b/docs/deployment.md
index 15f05f6b..68f5aa4e 100644
--- a/docs/deployment.md
+++ b/docs/deployment.md
@@ -276,11 +276,11 @@ pnpm build
* GitHub 使用 [.github/workflows/release.yml](.github/workflows/release.yml),保留制品上传/下载分阶段流程
* Gitea 使用 [.gitea/workflows/release.yml](.gitea/workflows/release.yml),在单个 Job 内完成前端构建、服务端/Agent 多平台编译与 Release 发布,避免依赖 Gitea 目前不兼容的 `upload-artifact@v4`、`download-artifact@v4`
-Docker 镜像发布使用 [.github/workflows/docker-image.yml](.github/workflows/docker-image.yml):
-
-* 仅构建 `atsf_server` 服务端镜像
-* 发布到 GitHub Container Registry(`ghcr.io//:`)
-* 单个工作流同时产出 `linux/amd64` 与 `linux/arm64` 多架构镜像
+Docker 镜像发布使用 [.github/workflows/docker-image.yml](.github/workflows/docker-image.yml):
+
+* 仅构建 `atsf_server` 服务端镜像
+* 发布到 GitHub Container Registry(`ghcr.io//:`)
+* 单个工作流通过分架构原生构建再合并 manifest 的方式产出 `linux/amd64` 与 `linux/arm64` 多架构镜像,避免 `arm64` 长时间模拟编译
---