# chen-dynasty
**Repository Path**: chenzhanxu/chen-dynasty
## Basic Information
- **Project Name**: chen-dynasty
- **Description**: 晨之博客(Chen Blog):Go + Vue 3 全栈个人博客系统(前后端分离)。Markdown 文章编写与阅读统计、多级分类标签、全文搜索、用户中心(头像/登录日志)、公告、数据可视化、系统监控、亮暗双主题;管理后台 8 大模块(仪表盘/用户/分类/标签/媒体分类管理/站点设置/公告/数据库)。SQLite 零配置开箱即用,内置演示数据,支持 Docker 一键部署。
- **Primary Language**: Go
- **License**: MulanPSL-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2026-04-17
- **Last Updated**: 2026-09-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: 个人博客
## README
# 🌸 Chen Blog
**A clean & elegant personal blog system · Go + Vue 3 · Frontend/Backend separated · Zero-config ready**










[中文文档](README.md) · [🚀 Live Demo](https://blog.chenzhanxu.top/) · [HTTP Entry](http://blog.chenzhanxu.top/) · [Gitee Repository](https://gitee.com/chenzhanxu/chen-dynasty) · [Report Issue](https://gitee.com/chenzhanxu/chen-dynasty/issues)
---
## 📑 Quick Navigation
| 📂 Section | 📄 Content |
|---|---|
| [✨ Features](#-features) | Complete frontend & admin feature list |
| [🛠️ Tech Stack](#️-tech-stack) | Backend & frontend technology tables |
| [🏗️ Architecture](#️-architecture) | System architecture diagram & data flow |
| [🚀 Quick Start](#-quick-start) | Three ways to run (Script / Docker / Local) |
| [📁 Project Structure](#-project-structure) | Directory tree & key file descriptions |
| [⚙️ Configuration](#️-configuration) | Core config items & env var overrides |
| [📖 API Documentation](#-api-documentation) | Swagger online & offline docs |
| [🧑💻 Development Guide](#-development-guide) | Demo data, utility scripts, DB switching |
| [🔨 Build & Deploy](#-build--deploy) | Local build, Docker, 1Panel deployment |
| [❓ FAQ](#-faq) | 5 high-frequency questions |
---
## ✨ Features
### 🌍 Frontend
| Module | Core Capabilities | Highlights |
|---|---|---|
| 📝 **Articles** | Markdown edit/render · Auto-save drafts · Pinning · Soft delete · Related posts | Code highlight, TOC, reading progress |
| 📊 **Reading Stats** | PV / UV · Reading time estimate · Auto default cover for missing images | ECharts real-time visualization |
| 🏷️ **Categories & Tags** | Multi-level category tree · Tag aggregation pages · Multi-dimension filtering | Drag-drop tree sorting |
| 🔍 **Full-Text Search** | Keyword search · Suggestions · Hot keywords · Search history | Local index, millisecond response |
| 👤 **User Center** | Register/Login (remember me, 7-day session, fail-lock) · Profile · Login history · My articles | JWT + bcrypt, secure |
| 📢 **Announcements** | Sidebar announcement card, published from admin panel | Markdown rendering |
| 🖥️ **System Monitor** | Server resources · Go runtime (GC/Goroutines) · DB pool · QPS real-time metrics | Auto-refresh + history trends |
| 📈 **Data Visualization** | Visit trends · Hot articles · Category/tag distribution | ECharts 6 interactive charts |
| 📱 **Responsive Design** | Desktop/Tablet/Mobile breakpoints | Mobile-first |
| 🌙 **Dark Mode** | Instant light/dark toggle, all components themed for both | localStorage persistence |
> 📦 **Built-in Demo Data**: The repo ships with a SQLite demo database (`backend/blog.db`) containing **12 real tech articles, 7 categories, 12 tags, 9 comments, 4 friend links, 4 users** — clone and go, ready for public deployment.
---
### 🔐 Admin Panel (`/admin`)
| Module | Core Capabilities | Highlights |
|---|---|---|
| 📊 **Dashboard** | Time-based greeting · Stat cards (articles/users/PV/UV/comments) · Category pie chart · Hot articles TOP5 · Quick actions | Real-time data refresh |
| 👥 **User Management** | Stat bar · Avatar rendering · Search · Ban/Unban · Role change · Delete | Batch operations |
| 🗂️ **Category Management** | Tree view · Search & filter · Multi-level CRUD | Drag-drop sorting |
| 🏷️ **Tag Management** | Colorful tag cloud · Stat bar · Search & filter · CRUD (with color picker) | Live color preview |
| 🖼️ **Media Management** | Card grid preview · **Category upload/filter** (avatar/wallpaper/article/screenshot/other) · Batch delete · Inline preview | Auto thumbnail generation |
| ⚙️ **Site Settings** | ICP/Police record · Site start date · Custom key-values · Footer live preview (same source as frontend) | WYSIWYG |
| 📢 **Announcement Management** | Publish frontend announcements (title + Markdown) · Live preview · Stat bar | Instant effect |
| 🗄️ **Database Management** | DB overview · Table data distribution · TOP10 tables · Table list · Driver switching | One-click SQLite/MySQL switch |
> 💡 The backend still provides APIs for **friend links, custom pages, notifications, reports** (see [API Documentation](#-api-documentation)). Since the frontend has no consuming scenarios yet, the corresponding admin pages have been removed.
---
## 🛠️ Tech Stack
### Backend
| Technology | Description | Version | Purpose |
|---|---|---|---|
| **Go** | Server language | 1.21+ | High performance, strong typing, simple deployment |
| **Gin** | HTTP web framework | v1.9+ | Blazing fast routing, middleware ecosystem |
| **GORM** | ORM library | v2 | Eager loading, migrations, hooks |
| **SQLite** | Default DB (zero-config) | 3.x | Out-of-the-box, single-file deployment |
| **MySQL** | Production database | 8.0+ | High concurrency, replication |
| **JWT** | Authentication (custom expiry) | go-jwt | Stateless auth |
| **bcrypt** | Password hashing | - | Adaptive cost factor |
| **gin-swagger** | API documentation | - | Auto-generate OpenAPI 3.0 |
### Frontend
| Technology | Description | Version | Purpose |
|---|---|---|---|
| **Vue 3** | Frontend framework | 3.4+ | Composition API, composables |
| **TypeScript** | Type system | 5.4+ | Type safety, refactor-friendly |
| **Vite** | Build tool | 5.2+ | Instant cold start, on-demand compilation |
| **Naive UI** | UI library (light/dark theme) | 2.38+ | TypeScript-first, tree-shaking |
| **md-editor-v3** | Markdown editor | 6.4+ | Toolbar, live preview, image upload |
| **marked + DOMPurify** | Markdown rendering + XSS protection | - | Secure rendering |
| **ECharts** | Data visualization | 6.0+ | Interactive charts, theme adaptation |
| **Vue Router** | Routing | 4.3+ | Nested routes, guards, lazy loading |
| **Axios** | HTTP client | 1.6+ | Unified auth, 401 auto-redirect, request cancellation |
---
## 🏗️ Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ Client (Browser) │
└─────────────────────────────┬───────────────────────────────────┘
│ HTTPS / HTTP
▼
┌─────────────────────────────────────────────────────────────────┐
│ Nginx (Frontend Container) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Static │ │ /api → │ │ /uploads → │ │
│ │ Assets │ │ Backend │ │ Backend │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────┬───────────────────────────────────┘
│ Internal Network
▼
┌─────────────────────────────────────────────────────────────────┐
│ Backend (Gin + GORM) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Article │ │ User │ │ Media │ │ Monitor │ ... │
│ │ Module │ │ Module │ │ Module │ │ Module │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │ │
│ └──────────┴──────────┴──────────┘ │
│ │ │
│ ┌─────────┴─────────┐ │
│ │ Database Layer │ │
│ │ SQLite / MySQL │ │
│ └───────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
> 📌 **Key Design Decisions**:
> - **Full frontend/backend separation**: Static assets served by Nginx, API requests reverse-proxied to backend
> - **Dual database mode**: Default SQLite for zero-config; production MySQL with **auto-fallback to SQLite** on connection failure, ensuring availability
> - **Auth flow**: JWT Access Token (default 24h) + bcrypt password hash + login failure lockout (per username+IP, 5 min)
---
## 🚀 Quick Start
> 🖥️ **Live Demo** (accessible via HTTPS or HTTP):
> - **HTTPS**:
> - **HTTP**:
>
> Frontend & admin included — see "Default Account" below for login
### Option 1: One-Click Start in Container (Recommended ⭐)
```bash
# Clone the repo
git clone https://gitee.com/chenzhanxu/chen-dynasty.git
cd chen-dynasty
# One-click start (readiness checks, logs, process guard)
bash start_blog.sh
```
| Service | URL | Description |
|---|---|---|
| Frontend | http://localhost:5173 | Vite Dev Server (HMR) |
| Backend API | http://localhost:8080 | Gin Server |
| Swagger Docs | http://localhost:8080/swagger/index.html | Interactive API testing |
---
### Option 2: Docker Compose (Production Recommended 🐳)
```bash
# 1. Copy env template and customize
cp .env.example .env
# 2. Start (frontend Nginx includes /api /uploads /swagger reverse proxy)
docker-compose up -d
```
| Service | Port | Description |
|---|---|---|
| Frontend | 80 (container) → host configurable | Nginx static + reverse proxy |
| Backend | 8080 (container) → host configurable | API service |
| Volume | `blog-data` | SQLite persistence (`blog.db`) |
> 💡 `docker-compose.yml` frontend Nginx already configures `/api`, `/uploads`, `/swagger` locations proxying to backend container — **single port access, no extra CORS config needed**.
---
### Option 3: Local Development (Dev/Debug 🛠️)
```bash
# Terminal 1: Backend
cd backend
export PATH=$PATH:/usr/local/go/bin # If Go not in PATH
go mod download
go run main.go # http://localhost:8080
# Terminal 2: Frontend
cd frontend
npm install
npm run dev # http://localhost:5173
```
---
### Default Account
| Item | Value | Note |
|---|---|---|
| Username | `admin` | Admin role |
| Password | `Admin123` | Case-sensitive, **must change before production!** |
> 💡 Repo includes demo database `backend/blog.db` (tracked in Git) with admin account and 12 real articles — clone and log in.
>
> Docker deployments can set initial admin password via `ADMIN_INITIAL_PASSWORD` env var (defaults to `Admin123`).
---
## 📁 Project Structure
```
chen-dynasty/
├── backend/ # 🐹 Go Backend
│ ├── main.go # Entry point
│ ├── config.example.yaml # Config template (copy to config.yaml)
│ ├── cmd/ # CLI entry
│ ├── config/ # Config loading (config.yaml + env overrides)
│ ├── database/ # DB init, auto-migration, default admin
│ ├── handlers/ # HTTP handlers (incl. login_guard)
│ ├── middleware/ # Middleware (JWT auth, CORS, logging, recovery)
│ ├── models/ # GORM data models
│ ├── router/ # Route registration (article/user/media/statistics/monitor…)
│ ├── services/ # Business logic layer
│ ├── tools/ # Demo data / migration / utility scripts (standalone main)
│ ├── utils/ # Utilities (JWT, password, response, logging)
│ ├── docs/ # Swagger generated docs
│ └── uploads/ # Upload directory
├── frontend/ # 🖖 Vue 3 Frontend
│ ├── nginx.conf # Nginx config (with reverse proxy)
│ └── src/
│ ├── api/ # Axios API wrappers (unified error handling)
│ ├── components/ # Shared components (NavBar, Footer, Layout, etc.)
│ ├── router/ # Route config (lazy loading, auth guards)
│ ├── views/ # Frontend pages
│ │ ├── Home.vue
│ │ ├── Article.vue
│ │ ├── Search.vue
│ │ ├── Profile.vue
│ │ └── MyArticles.vue
│ └── views/admin/ # Admin pages (8 modules)
│ ├── Dashboard.vue
│ ├── UserManage.vue
│ ├── CategoryManage.vue
│ ├── TagManage.vue
│ ├── MediaManage.vue
│ ├── SiteSettings.vue
│ ├── AnnouncementManage.vue
│ └── DatabaseManage.vue
├── start_blog.sh # One-click startup script
├── docker-compose.yml # Docker orchestration
├── .env.example # Docker env template
├── README.md # Chinese documentation
└── README.en.md # English documentation
```
---
## ⚙️ Configuration
### Dual Database Modes
| Driver | Use Case | Key Config |
|---|---|---|
| `sqlite` (default) | Dev, test, lightweight deploy | `database.sqlite.path` → local file |
| `mysql` | Production, high concurrency | `database.mysql.*` connection info, **auto-fallback to SQLite on failure** |
### Config File
Config lives in `backend/config.yaml` (copy from `config.example.yaml`). **Every option can be overridden by an environment variable** (UPPER_SNAKE_CASE):
```bash
# Common env vars
JWT_SECRET=your-super-secret-key # JWT secret (MUST change in production!)
DATABASE_DRIVER=sqlite # Database driver: sqlite / mysql
ADMIN_INITIAL_PASSWORD=your-password # Admin initial password
APP_PORT=8080 # Backend port
```
Core config example:
```yaml
app:
port: "8080"
mode: debug # debug / release
database:
driver: sqlite # sqlite / mysql
sqlite:
path: ./blog.db
jwt:
secret: "" # Production: strong random string (≥32 chars)
expire_hour: 24
log:
level: info
filename: ./logs/blog.log
max_size: 100 # Per-file size (MB), auto rotation & compression
cors:
allow_origins:
- "http://localhost:5173"
- "https://your-domain.com"
media:
upload_path: ./uploads
max_file_size: 10 # MB
thumbnail:
enabled: true # Auto-generate thumbnails
```
---
## 📖 API Documentation
| Format | URL | Description |
|---|---|---|
| 🌐 **Online Swagger UI** | `http://localhost:8080/swagger/index.html` | Interactive testing, auth, export OpenAPI JSON |
| 📄 **Offline Markdown** | [backend/API_DOC.md](backend/API_DOC.md) | Full endpoint list, request/response examples |
> 💡 Swagger docs auto-generated via `swag init` from code annotations (`// @Summary`, `@Param`, etc.).
---
## 🧑💻 Development Guide
### Demo Data
Repo includes a real demo database `backend/blog.db` (tracked in Git — **no manual init needed**):
| Data | Count | Description |
|---|---|---|
| Articles | 12 | 3 pinned; covering Go / Vue / Docker / K8s / MySQL / Redis / writing, etc. |
| Categories | 7 | Tech / Life / Project Experience / DevOps / Database / Dev Tools / Career |
| Tags | 12 | Go, Docker, Kubernetes, MySQL, Redis, Vue.js, Git, CI/CD, etc. |
| Comments | 9 | Real comment content |
| Friend Links | 4 | Go 语言中文网, Vue.js official, Gitee, 阮一峰的网络日志 |
| Users | 4 | `admin` + 3 demo users |
To regenerate demo data or inspect row counts, use standalone tools under `backend/tools/` (**each is an independent `main` program** — compile & run individually):
```bash
cd backend
# Generate article demo data
go run tools/seed_data.go
# Generate tags + article associations
go run tools/seed_tags.go
# Generate categories + article mapping fixes
go run tools/seed_categories.go
# Inspect DB row counts
go run tools/check_sqlite_data.go
```
> ⚠️ Tools under `tools/` are independent `main` programs — **do not run `go build ./...`** for the whole directory; run each with `go run` separately.
---
### Utility Scripts
```bash
# Generate default cover placeholder images (101~104.png)
python3 backend/tools/gen_covers.py
# Precisely stop blog-server process (avoids accidental kills)
python3 backend/tools/stop_backend.py
```
---
### Database Switching (SQLite ↔ MySQL)
1. Change `database.driver` to `mysql` in `backend/config.yaml` and fill in connection info
2. Restart backend (migration runs automatically via GORM AutoMigrate)
3. Detailed guides:
- [DATABASE_SWITCH_GUIDE.md](backend/DATABASE_SWITCH_GUIDE.md) — Driver switching
- [DATA_MIGRATION_GUIDE.md](backend/DATA_MIGRATION_GUIDE.md) — Data migration
---
### Logging
Level-based logging with size rotation, auto-compression, structured output. See [LOG_USAGE.md](backend/LOG_USAGE.md).
---
## 🔨 Build & Deploy
### Local Build
```bash
# Backend
cd backend
go build -o blog-server main.go
./blog-server
# Frontend (output in dist/, served by Nginx)
cd frontend
npm run build
```
---
### Docker Compose Deploy
```bash
docker-compose up -d
```
**Frontend Nginx (`frontend/nginx.conf`) includes three reverse-proxy locations**:
| Location | Proxy Target | Purpose |
|---|---|---|
| `/api/` | `http://backend:8080` | All API requests |
| `/uploads/` | `http://backend:8080` | Static file access |
| `/swagger/` | `http://backend:8080` | API documentation |
> Single-port access, no extra CORS config needed.
---
### 1Panel Deployment (Chinese Ops Panel 🇨🇳)
#### Option A: Compose Deployment (Recommended ⭐)
1. **Upload code**
```bash
git clone https://gitee.com/chenzhanxu/chen-dynasty.git
# or upload & extract archive to server directory
```
2. **(Optional) Adjust port mappings**
Edit `docker-compose.yml` — **only change the host port (left of `:`)**, never the container ports (`8080` / `80`).
3. **Create Compose**
1Panel → **Containers → Compose → Create Compose**
- Name: `chen-blog`
- Source: "Server local"
- Select project root (where `docker-compose.yml` lives)
- Confirm (first pull + build ~5–15 min)
4. **Verify**
Containers `chen-blog-backend` and `chen-blog-frontend` appear with `healthy` status; visit `http://SERVER_IP:port`
5. **(Production, Optional) Domain + HTTPS**
1Panel → **Websites → Create Website → Reverse Proxy** → bind domain to frontend port → issue SSL cert for HTTPS
---
#### Option B: Static Deployment (No Docker)
| Step | Action |
|---|---|
| 1. Build backend | `cd backend && go build -o blog-server main.go` → upload, run via 1Panel **Process Guard** or systemd (on :8080) |
| 2. Build frontend | `cd frontend && npm run build` → upload `dist/` |
| 3. Create static site | 1Panel → **Websites → Create Website → Static Website** → point to `dist/` |
| 4. Add reverse proxy | Add `/api`, `/uploads`, `/swagger` locations from `nginx.conf`, change `proxy_pass` to `http://127.0.0.1:8080` |
---
### ⚠️ 3 Must-Dos for Production
| # | Item | Action | Priority |
|---|---|---|---|
| 1 | 🔑 **JWT Secret** | Add `JWT_SECRET=` to backend container env | 🔴 Critical |
| 2 | 👤 **Admin Password** | Change immediately after login (default `admin / Admin123`) | 🔴 Critical |
| 3 | 💾 **Data Backup** | SQLite data in volume `blog-data` (`blog.db`); schedule volume backups in 1Panel | 🟡 Important |
---
## ❓ FAQ
1. http://localhost:8080 returns 404?
**Expected** — the backend is a pure API service with no root page. Use:
- API docs: `http://localhost:8080/swagger/index.html`
- Frontend: `http://localhost:5173`
2. Blank frontend page?
Check backend is running, open browser DevTools → Console/Network for errors. Common causes:
- Backend not started or port conflict
- CORS missing frontend origin
- Build output path incorrect
3. Image upload fails?
Verify `backend/uploads` directory is writable (Docker: confirm volume mount).
4. CORS errors?
Ensure `cors.allow_origins` in `config.yaml` includes the actual frontend origin (protocol, domain, port).
5. "Too many attempts" on login?
Repeated login failures from same username + IP trigger a **5-minute lock** (security policy, in-memory counter).
Fix: wait for unlock, or restart backend to clear in-memory counter.
---
## 📄 License
This project is open-sourced under the [MIT License](LICENSE).
---
### 💖 Like this project?
**Give it a ⭐ Star!** Every star fuels ongoing maintenance.
[](https://star-history.com/#chenzhanxu/chen-dynasty&Date)
---
**Made with ❤️ by [chenzhanxu](https://gitee.com/chenzhanxu)**