From aff334e1af2a56c160b1775666d33c2783d42ad9 Mon Sep 17 00:00:00 2001 From: Awuqing <3184394176@qq.com> Date: Tue, 17 Mar 2026 13:45:31 +0800 Subject: [PATCH] add some tips --- .github/ISSUE_TEMPLATE/bug_report.md | 43 ++ .github/ISSUE_TEMPLATE/config.yml | 5 + .github/ISSUE_TEMPLATE/feature_request.md | 23 ++ .github/PULL_REQUEST_TEMPLATE.md | 29 ++ .github/SECURITY.md | 34 ++ .github/workflows/ci.yml | 57 +++ .github/workflows/release.yml | 63 +++ README.md | 105 +++-- README_EN.md | 468 ++++++++++++++++++++++ 9 files changed, 790 insertions(+), 37 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/SECURITY.md create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100644 README_EN.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..34bd5d3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,43 @@ +--- +name: "\U0001F41B Bug 报告" +about: "报告一个 Bug,帮助我们改进 BackupX" +title: "[Bug] " +labels: ["bug"] +assignees: [] +--- + +## 描述 + + + +## 复现步骤 + +1. +2. +3. + +## 期望行为 + + + +## 实际行为 + + + +## 环境信息 + +- **OS**: +- **Go 版本**: +- **Node.js 版本**: +- **浏览器**: +- **BackupX 版本**: + +## 相关日志 + +``` + +``` + +## 截图 + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..f848beb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: 💬 讨论区 / Discussions + url: https://github.com/Awuqing/GoogleDriverBackupEveryDay/discussions + about: 提问、讨论功能想法或分享使用经验 diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..b329fc7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: "\U0001F680 功能请求" +about: "建议一个新功能或改进" +title: "[Feature] " +labels: ["enhancement"] +assignees: [] +--- + +## 需求描述 + + + +## 使用场景 + + + +## 建议的解决方案 + + + +## 补充信息 + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..df7d5e1 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,29 @@ +## Pull Request + +### 变更类型 / Type of Change + +- [ ] 🐛 Bug 修复 (非破坏性变更) +- [ ] ✨ 新功能 (非破坏性变更) +- [ ] 💥 破坏性变更 (修复或功能导致现有功能变更) +- [ ] 📝 文档更新 +- [ ] ♻️ 代码重构 (不影响功能) +- [ ] ⚡ 性能优化 + +### 描述 / Description + + + +### 相关 Issue / Related Issue + + + +### 测试 / Testing + +- [ ] 后端测试通过 (`go test ./...`) +- [ ] 前端测试通过 (`npm run test`) +- [ ] 前端构建成功 (`npm run build`) +- [ ] 已在本地环境手动测试 + +### 截图 / Screenshots + + diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..27ede9b --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,34 @@ +# 安全漏洞披露政策 / Security Policy + +## 支持的版本 / Supported Versions + +| Version | Supported | +|---------|--------------------| +| latest | ✅ | +| < latest | ❌ | + +## 报告安全漏洞 / Reporting a Vulnerability + +如果您发现了安全漏洞,**请不要通过公开 Issue 报告**。 + +请发送邮件至项目维护者,包含以下信息: + +1. 漏洞描述 +2. 复现步骤 +3. 受影响的版本 +4. 可能的影响范围 + +我们会在 48 小时内确认收到并开始处理。 + +--- + +If you discover a security vulnerability, **please do NOT open a public issue**. + +Instead, email the project maintainer with the following details: + +1. Description of the vulnerability +2. Steps to reproduce +3. Affected versions +4. Potential impact + +We will acknowledge receipt within 48 hours and begin working on a fix. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..32679fb --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,57 @@ +name: CI + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +jobs: + backend: + name: Go Build & Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.21' + cache-dependency-path: server/go.sum + + - name: Build + working-directory: server + run: go build ./... + + - name: Test + working-directory: server + run: go test ./... -v + + frontend: + name: React Build & Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'npm' + cache-dependency-path: web/package-lock.json + + - name: Install dependencies + working-directory: web + run: npm ci + + - name: Type Check + working-directory: web + run: npx tsc --noEmit -p tsconfig.json + + - name: Test + working-directory: web + run: npm run test + + - name: Build + working-directory: web + run: npm run build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4dc1d35 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,63 @@ +name: Release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + +jobs: + release: + name: Build & Release + runs-on: ubuntu-latest + strategy: + matrix: + goos: [linux] + goarch: [amd64, arm64] + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.21' + cache-dependency-path: server/go.sum + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'npm' + cache-dependency-path: web/package-lock.json + + - name: Build frontend + working-directory: web + run: | + npm ci + npm run build + + - name: Build backend + working-directory: server + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + CGO_ENABLED: 1 + run: | + go build -ldflags "-s -w -X main.version=${{ github.ref_name }}" -o ../backupx-${{ matrix.goos }}-${{ matrix.goarch }} ./cmd/backupx + + - name: Package release + run: | + mkdir -p release + cp backupx-${{ matrix.goos }}-${{ matrix.goarch }} release/ + cp -r web/dist release/web + cp server/config.example.yaml release/ + cp deploy/install.sh release/ 2>/dev/null || true + cd release && tar czf ../backupx-${{ github.ref_name }}-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz . + + - name: Upload Release Asset + uses: softprops/action-gh-release@v2 + with: + files: backupx-${{ github.ref_name }}-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz + generate_release_notes: true diff --git a/README.md b/README.md index b15bbb5..9bff021 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +

+ English | 中文 +

🛡️ BackupX

@@ -13,11 +16,14 @@ API

+ Stars + Release Go React TypeScript SQLite - License + License + Issues

@@ -86,8 +92,8 @@ BackupX 是一个面向 **Linux / macOS 服务器**的自托管备份管理平 ```bash # 克隆项目 -git clone https://github.com/yourname/backupx.git -cd backupx +git clone https://github.com/Awuqing/GoogleDriverBackupEveryDay.git +cd GoogleDriverBackupEveryDay # 一键构建前后端 make build @@ -211,42 +217,67 @@ Master 提供 `GET /api/nodes/:id/fs/list?path=/` 接口,可远程浏览节点 ## Project Structure ``` -backupx/ -├── server/ # Go 后端 -│ ├── cmd/backupx/ # 入口 +GoogleDriverBackupEveryDay/ +├── server/ # Go 后端 +│ ├── cmd/backupx/ # 程序入口 │ ├── internal/ -│ │ ├── app/ # 应用组装 (DI) -│ │ ├── backup/ # 备份引擎 (file/mysql/sqlite/pgsql) -│ │ ├── config/ # 配置加载 (viper) -│ │ ├── http/ # HTTP 处理器 + 路由 -│ │ ├── model/ # GORM 数据模型 -│ │ ├── notify/ # 通知 (email/webhook/telegram) -│ │ ├── repository/ # 数据访问层 -│ │ ├── scheduler/ # Cron 调度器 -│ │ ├── security/ # JWT + 限流 -│ │ ├── service/ # 业务逻辑层 -│ │ └── storage/ # 存储后端 (插件化) -│ │ ├── aliyun/ # 阿里云 OSS -│ │ ├── tencent/ # 腾讯云 COS -│ │ ├── qiniu/ # 七牛云 Kodo -│ │ ├── s3/ # S3 Compatible -│ │ ├── googledrive/ # Google Drive -│ │ ├── webdav/ # WebDAV -│ │ └── localdisk/ # 本地磁盘 -│ └── pkg/ # 工具包 (compress/crypto/response) -├── web/ # React 前端 +│ │ ├── app/ # 应用组装 (DI) +│ │ ├── apperror/ # 统一错误类型 +│ │ ├── backup/ # 备份引擎 (file/mysql/sqlite/pgsql) +│ │ │ └── retention/ # 保留策略 +│ │ ├── config/ # 配置加载 (viper) +│ │ ├── database/ # 数据库初始化 + 迁移 +│ │ ├── http/ # HTTP 处理器 + 路由 + 中间件 +│ │ ├── httpapi/ # HTTP API 辅助工具 +│ │ ├── logger/ # 日志初始化 (zap + lumberjack) +│ │ ├── model/ # GORM 数据模型 +│ │ ├── notify/ # 通知 (email/webhook/telegram) +│ │ ├── repository/ # 数据访问层 +│ │ ├── scheduler/ # Cron 调度器 +│ │ ├── security/ # JWT + 限流 +│ │ ├── service/ # 业务逻辑层 +│ │ └── storage/ # 存储后端 (插件化接口) +│ │ ├── aliyun/ # 阿里云 OSS +│ │ ├── tencent/ # 腾讯云 COS +│ │ ├── qiniu/ # 七牛云 Kodo +│ │ ├── s3/ # S3 Compatible 核心 +│ │ ├── s3provider/ # S3 Provider 辅助 +│ │ ├── googledrive/ # Google Drive +│ │ ├── webdav/ # WebDAV 核心 +│ │ ├── webdavprovider/ # WebDAV Provider 辅助 +│ │ ├── localdisk/ # 本地磁盘 +│ │ └── codec/ # 配置编解码 +│ └── pkg/ # 工具包 (compress/crypto/response) +├── web/ # React 前端 │ └── src/ -│ ├── components/ # 通用组件 (CronEditor/PathSelector/...) -│ ├── pages/ # 页面 (Dashboard/Tasks/Storage/Nodes/...) -│ ├── services/ # API 请求封装 -│ ├── stores/ # Zustand 状态管理 -│ ├── locales/ # i18n 语言包 (zh-CN/en-US) -│ └── router/ # 路由配置 -├── deploy/ # 部署配置 -│ ├── nginx.conf # Nginx 参考配置 -│ ├── backupx.service # systemd 服务单元 -│ └── install.sh # 一键安装脚本 -└── Makefile # 构建命令 +│ ├── components/ # 通用组件 (CronEditor/FormDrawer/...) +│ ├── hooks/ # 自定义 Hooks +│ ├── layouts/ # 布局组件 (AppLayout) +│ ├── pages/ # 页面模块 +│ │ ├── dashboard/ # 仪表盘 +│ │ ├── backup-tasks/ # 备份任务 +│ │ ├── backup-records/ # 备份记录 +│ │ ├── storage-targets/ # 存储目标 +│ │ ├── nodes/ # 节点管理 +│ │ ├── notifications/ # 通知配置 +│ │ ├── settings/ # 系统设置 +│ │ └── login/ # 登录页 +│ ├── services/ # API 请求封装 +│ ├── stores/ # Zustand 状态管理 +│ ├── styles/ # 全局样式 +│ ├── types/ # TypeScript 类型定义 +│ ├── utils/ # 工具函数 +│ ├── locales/ # i18n 语言包 (zh-CN / en-US) +│ └── router/ # 路由配置 +├── deploy/ # 部署配置 +│ ├── nginx.conf # Nginx 参考配置 +│ ├── backupx.service # systemd 服务单元 +│ └── install.sh # 一键安装脚本 +├── .github/ # GitHub 配置 +│ ├── workflows/ci.yml # CI 工作流 +│ ├── workflows/release.yml # Release 工作流 +│ └── ISSUE_TEMPLATE/ # Issue 模板 +└── Makefile # 构建命令 ``` ## Development diff --git a/README_EN.md b/README_EN.md new file mode 100644 index 0000000..232482b --- /dev/null +++ b/README_EN.md @@ -0,0 +1,468 @@ +

+ English | 中文 +

+

+

🛡️ BackupX

+

+ Self-hosted Server Backup Management Platform with Web UI +

+

+ Features • + Quick Start • + Configuration • + Architecture • + Cluster • + Development • + API +

+

+ Stars + Release + Go + React + TypeScript + SQLite + License + Issues +

+

+ +--- + +BackupX is a self-hosted backup management platform for **Linux / macOS servers**. Through an enterprise-grade Web console, you can easily configure directory backups, database backups, and securely store backup files to Alibaba Cloud OSS, Tencent Cloud COS, Qiniu Cloud Kodo, Google Drive, S3-compatible storage, WebDAV, or local disk. + +Supports **multi-node cluster management** for unified control of backup tasks across different servers. + +> **For**: Individual developers / small teams / DevOps with Linux servers + +## Features + +### 📦 Multiple Backup Types +- **Files / Directories** — Custom exclude rules (e.g. `node_modules`, `*.log`) +- **MySQL** — Via native `mysqldump` tool +- **SQLite** — Safe file copy +- **PostgreSQL** — Via native `pg_dump` tool + +### ☁️ Multi-Cloud Storage Backends +| Provider | Type | Description | +|----------|------|-------------| +| 🇨🇳 **Alibaba Cloud OSS** | `aliyun_oss` | Auto endpoint assembly, internal network support | +| 🇨🇳 **Tencent Cloud COS** | `tencent_cos` | Auto endpoint assembly | +| 🇨🇳 **Qiniu Cloud Kodo** | `qiniu_kodo` | 6 region precise mapping | +| 🌍 **S3 Compatible** | `s3` | AWS S3 / MinIO / Cloudflare R2, etc. | +| 🌍 **Google Drive** | `google_drive` | Full OAuth 2.0 flow | +| 🌍 **WebDAV** | `webdav` | Nextcloud / Nutstore, etc. | +| 💾 **Local Disk** | `local_disk` | Backup to local server directory | + +> Chinese cloud providers only require **Region** and **AccessKey** — the system auto-assembles the endpoint. Powered by the S3 engine under the hood with zero extra dependencies. + +### 🖥️ Cluster Management (Master-Agent) +- **Node Management** — Register remote server nodes with Token authentication +- **Local Node** — Auto-created, zero-friction upgrade for single-machine users +- **Directory Browser** — Visual file tree selector for backup source paths +- **Agent Heartbeat** — Real-time node online status monitoring +- **Task Tags** — Categorize and manage backup tasks by tags/nodes + +### ⏰ Automation & Scheduling +- Cron expression scheduling +- Visual Cron editor +- Auto-retention policy (by days / by count) +- Max concurrent backup limit + +### 🔐 Security +- JWT authentication + bcrypt password hashing +- AES-256-GCM encrypted sensitive config storage (DB passwords, OAuth tokens) +- Optional backup file encryption +- Login rate limiting (brute force protection) +- Node Token authentication (one-time display, secure transport) + +### 📊 Monitoring & Notifications +- Dashboard stats (success rate, storage usage, backup trend charts) +- Email / Webhook / Telegram notifications +- Real-time backup execution logs (SSE) + +### 🌐 Other +- Chinese & English i18n +- Zero external dependencies (embedded SQLite, single binary deployment) +- systemd service support + +## Quick Start + +### Build from Source + +```bash +# Clone the project +git clone https://github.com/Awuqing/GoogleDriverBackupEveryDay.git +cd GoogleDriverBackupEveryDay + +# Build frontend and backend +make build + +# Start the backend service (default port :8340) +cd server && ./bin/backupx +``` + +### Access Web UI + +Open `http://your-server:8340` in your browser. First-time use will guide you through creating an admin account. + +## Configuration + +The config file defaults to `./config.yaml`. Settings can also be overridden via `BACKUPX_` prefixed environment variables. + +```yaml +# config.yaml +server: + host: "0.0.0.0" + port: 8340 + mode: "release" # debug | release + +database: + path: "./data/backupx.db" # SQLite database path + +security: + jwt_secret: "" # Leave empty to auto-generate + jwt_expire: "24h" + encryption_key: "" # AES encryption key, auto-generated if empty + +backup: + temp_dir: "/tmp/backupx" # Backup temp directory + max_concurrent: 2 # Max concurrent backups + +log: + level: "info" # debug | info | warn | error + file: "./data/backupx.log" + max_size: 100 # Max log file size (MB) + max_backups: 3 # Number of old log files to retain + max_age: 30 # Log retention days +``` + +> 💡 `jwt_secret` and `encryption_key` are auto-generated on first startup and persisted to the database. + +## Architecture + +``` + ┌─────────────────────┐ + │ Nginx (Reverse │ + │ Proxy) │ + │ / → Static Files │ + │ /api → :8340 │ + └─────────┬───────────┘ + │ + ▼ +┌──────────────────────────────────────────────────────┐ +│ BackupX Master (Go API Server) │ +│ :8340 │ +│ │ +│ ┌──────┐ ┌────────────┐ ┌───────────────────────┐│ +│ │ Auth │ │Backup Engine│ │ Storage Registry ││ +│ └──────┘ └──────┬─────┘ │ ┌─────────────────┐ ││ +│ │ │ │ Alibaba Cloud │ ││ +│ ┌──────────┐ │ │ │ Tencent Cloud │ ││ +│ │ Cron │◄───┘ │ │ Qiniu Cloud │ ││ +│ │Scheduler │ │ │ S3 Compatible │ ││ +│ └──────────┘ │ │ Google Drive │ ││ +│ │ │ WebDAV │ ││ +│ ┌──────────┐ │ │ Local Disk │ ││ +│ │ Notify │ │ └─────────────────┘ ││ +│ │ Module │ └───────────────────────┘│ +│ └──────────┘ │ +│ │ +│ ┌──────────────┐ ┌────────────────────┐ │ +│ │ Node Manager │ │ SQLite (backupx.db)│ │ +│ └──────┬───────┘ └────────────────────┘ │ +└─────────┼────────────────────────────────────────────┘ + │ Heartbeat / Task Dispatch + ▼ +┌──────────────────┐ ┌──────────────────┐ +│ Agent Node A │ │ Agent Node B │ +│ (Remote Server)│ │ (Remote Server)│ +└──────────────────┘ └──────────────────┘ +``` + +### Tech Stack + +| Component | Technology | +|-----------|-----------| +| **Backend** | Go · Gin · GORM · SQLite · robfig/cron | +| **Frontend** | React 18 · TypeScript · ArcoDesign · Vite · Zustand · ECharts | +| **Storage** | AWS SDK v2 (S3/OSS/COS/Kodo) · Google Drive API v3 · gowebdav | +| **Security** | JWT · bcrypt · AES-256-GCM | +| **Logging** | zap + lumberjack (auto-rotation) | + +## Cluster Mode + +BackupX supports **Master-Agent** mode for managing backup tasks across multiple servers. + +### How It Works + +1. **Master** is the server running the BackupX Web console +2. **Agent** is deployed on remote servers that need to be backed up +3. Agents register with the Master using a Token and send periodic heartbeats +4. Master dispatches backup tasks to the corresponding Agent for execution + +### Adding Nodes + +```bash +# In Web Console → Node Management → Add Node +# The system generates a unique 64-character hex Token + +# Configure the Agent on the remote server +./backupx-agent --master http://master-server:8340 --token +``` + +### Directory Probe API + +Master provides `GET /api/nodes/:id/fs/list?path=/` to remotely browse a node's file system. The frontend uses a tree selector to browse the target machine's directory structure when creating backup tasks. + +## Project Structure + +``` +GoogleDriverBackupEveryDay/ +├── server/ # Go backend +│ ├── cmd/backupx/ # Entry point +│ ├── internal/ +│ │ ├── app/ # App assembly (DI) +│ │ ├── apperror/ # Unified error types +│ │ ├── backup/ # Backup engine (file/mysql/sqlite/pgsql) +│ │ │ └── retention/ # Retention policy +│ │ ├── config/ # Config loading (viper) +│ │ ├── database/ # Database init + migrations +│ │ ├── http/ # HTTP handlers + routes + middleware +│ │ ├── httpapi/ # HTTP API helpers +│ │ ├── logger/ # Logger init (zap + lumberjack) +│ │ ├── model/ # GORM data models +│ │ ├── notify/ # Notifications (email/webhook/telegram) +│ │ ├── repository/ # Data access layer +│ │ ├── scheduler/ # Cron scheduler +│ │ ├── security/ # JWT + rate limiting +│ │ ├── service/ # Business logic +│ │ └── storage/ # Storage backends (plugin interface) +│ │ ├── aliyun/ # Alibaba Cloud OSS +│ │ ├── tencent/ # Tencent Cloud COS +│ │ ├── qiniu/ # Qiniu Cloud Kodo +│ │ ├── s3/ # S3 Compatible core +│ │ ├── s3provider/ # S3 Provider helper +│ │ ├── googledrive/ # Google Drive +│ │ ├── webdav/ # WebDAV core +│ │ ├── webdavprovider/ # WebDAV Provider helper +│ │ ├── localdisk/ # Local disk +│ │ └── codec/ # Config codec +│ └── pkg/ # Utilities (compress/crypto/response) +├── web/ # React frontend +│ └── src/ +│ ├── components/ # Shared components (CronEditor/FormDrawer/...) +│ ├── hooks/ # Custom Hooks +│ ├── layouts/ # Layout components (AppLayout) +│ ├── pages/ # Page modules +│ │ ├── dashboard/ # Dashboard +│ │ ├── backup-tasks/ # Backup tasks +│ │ ├── backup-records/ # Backup records +│ │ ├── storage-targets/ # Storage targets +│ │ ├── nodes/ # Node management +│ │ ├── notifications/ # Notification settings +│ │ ├── settings/ # System settings +│ │ └── login/ # Login page +│ ├── services/ # API request wrappers +│ ├── stores/ # Zustand state management +│ ├── styles/ # Global styles +│ ├── types/ # TypeScript type definitions +│ ├── utils/ # Utility functions +│ ├── locales/ # i18n language packs (zh-CN / en-US) +│ └── router/ # Route configuration +├── deploy/ # Deployment configs +│ ├── nginx.conf # Nginx reference config +│ ├── backupx.service # systemd service unit +│ └── install.sh # One-click install script +├── .github/ # GitHub configuration +│ ├── workflows/ci.yml # CI workflow +│ ├── workflows/release.yml # Release workflow +│ └── ISSUE_TEMPLATE/ # Issue templates +└── Makefile # Build commands +``` + +## Development + +### Prerequisites + +- **Go** ≥ 1.21 +- **Node.js** ≥ 18 +- **npm** + +### Dev Mode + +```bash +# Terminal 1: Start backend (use air for hot-reload) +make dev-server + +# Terminal 2: Start frontend (Vite HMR) +make dev-web +``` + +### Run Tests + +```bash +# Run all tests +make test + +# Backend only +make test-server # go test ./... + +# Frontend only +make test-web # npm run test +``` + +### Build + +```bash +# Build frontend and backend +make build + +# Clean build artifacts +make clean +``` + +## Deployment + +### One-Click Install (Recommended) + +```bash +# Build first +make build + +# Run install script as root +sudo ./deploy/install.sh +``` + +The install script will automatically: +1. Create a `backupx` system user +2. Install the binary to `/opt/backupx/bin/` +3. Deploy the frontend to `/opt/backupx/web/` +4. Generate config at `/etc/backupx/config.yaml` +5. Register and start the systemd service +6. Configure Nginx reverse proxy (if installed) + +### Manual Deployment + +```bash +# 1. Build +cd server && go build -o backupx ./cmd/backupx +cd ../web && npm run build + +# 2. Deploy files +scp server/backupx your-server:/opt/backupx/bin/ +scp -r web/dist/ your-server:/opt/backupx/web/ +scp server/config.example.yaml your-server:/etc/backupx/config.yaml + +# 3. Start +ssh your-server '/opt/backupx/bin/backupx -config /etc/backupx/config.yaml' +``` + +### Nginx Config Example + +```nginx +server { + listen 80; + server_name backup.example.com; + + # Frontend static files + location / { + root /opt/backupx/web; + try_files $uri $uri/ /index.html; + } + + # API reverse proxy + location /api/ { + proxy_pass http://127.0.0.1:8340; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } +} +``` + +## API Reference + +All APIs are prefixed with `/api` and use JWT Bearer Token authentication (unless noted otherwise). + +| Module | Endpoint | Description | +|--------|----------|-------------| +| **Auth** | `POST /api/auth/setup` | Initialize admin (first time) | +| | `POST /api/auth/login` | Login to get Token | +| | `POST /api/auth/logout` | Logout | +| | `GET /api/auth/profile` | Current user info | +| | `PUT /api/auth/password` | Change password | +| **Backup Tasks** | `GET/POST /api/backup/tasks` | List / Create tasks | +| | `GET/PUT/DELETE /api/backup/tasks/:id` | Detail / Update / Delete | +| | `PUT /api/backup/tasks/:id/toggle` | Enable / Disable | +| | `POST /api/backup/tasks/:id/run` | Trigger manual execution | +| **Backup Records** | `GET /api/backup/records` | List records (with filter) | +| | `GET /api/backup/records/:id` | Record detail | +| | `GET /api/backup/records/:id/logs/stream` | Real-time execution logs (SSE) | +| | `GET /api/backup/records/:id/download` | Download backup file | +| | `POST /api/backup/records/:id/restore` | Restore backup | +| **Storage Targets** | `GET/POST /api/storage-targets` | List / Add targets | +| | `GET/PUT/DELETE /api/storage-targets/:id` | Detail / Update / Delete | +| | `POST /api/storage-targets/test` | Test connection | +| | `POST /api/storage-targets/:id/test` | Test saved connection | +| | `GET /api/storage-targets/:id/usage` | Query usage | +| **Nodes** | `GET/POST /api/nodes` | List / Add nodes | +| | `GET/DELETE /api/nodes/:id` | Detail / Delete | +| | `GET /api/nodes/:id/fs/list` | Directory browser | +| | `POST /api/agent/heartbeat` | Agent heartbeat ⚡ | +| **Notifications** | `GET/POST /api/notifications` | List / Add | +| | `POST /api/notifications/test` | Test notification | +| | `POST /api/notifications/:id/test` | Test saved notification | +| **Dashboard** | `GET /api/dashboard/stats` | Overview statistics | +| | `GET /api/dashboard/timeline` | Backup trend timeline | +| **System** | `GET /api/system/info` | System info (version/disk) | +| | `GET/PUT /api/settings` | System settings | + +> ⚡ `POST /api/agent/heartbeat` is a public endpoint authenticated via Node Token instead of JWT. + +## Cloud Storage Setup Guide + +### Alibaba Cloud OSS + +1. Log in to [Alibaba Cloud Console](https://oss.console.aliyun.com/), create a Bucket +2. Go to RAM Console to create an AccessKey +3. Select "Alibaba Cloud OSS" when adding a storage target in BackupX +4. Enter the Region (e.g. `cn-hangzhou`) and AccessKey — the system auto-assembles the endpoint + +### Tencent Cloud COS + +1. Log in to [Tencent Cloud Console](https://console.cloud.tencent.com/cos), create a bucket +2. Go to API Key Management to create SecretId/SecretKey +3. Bucket name format is `BucketName-APPID` (e.g. `backup-1250000000`) + +### Qiniu Cloud Kodo + +1. Log in to [Qiniu Cloud Console](https://portal.qiniu.com/), create a storage space +2. Supported regions: `z0` (East China) / `cn-east-2` (East China-Zhejiang 2) / `z1` (North China) / `z2` (South China) / `na0` (North America) / `as0` (Southeast Asia) + +### Google Drive + +1. Go to [Google Cloud Console](https://console.cloud.google.com/) and create a project +2. Enable the **Google Drive API** +3. Create an **OAuth 2.0 Client ID** (Web application type) +4. Add redirect URI: `http://your-server/api/storage-targets/google-drive/callback` +5. Enter the Client ID / Secret in BackupX storage management and click Authorize + +## Contributing + +Issues and Pull Requests are welcome! + +1. Fork this repository +2. Create a feature branch (`git checkout -b feature/amazing-feature`) +3. Commit your changes (`git commit -m 'Add amazing feature'`) +4. Push to the branch (`git push origin feature/amazing-feature`) +5. Open a Pull Request + +## License + +This project is licensed under the [Apache License 2.0](LICENSE). + +--- + +

+ Made with ❤️ for self-hosters +