# 萌芽小店 · 生产环境部署指南

> 本指南覆盖从零开始将萌芽小店完整部署到生产服务器的全部步骤，包括后端 Docker 部署与前端静态文件托管。

---

## 目录

1. [环境要求](#1-环境要求)
2. [准备 MySQL 数据库](#2-准备-mysql-数据库)
3. [部署后端（Docker）](#3-部署后端docker)
4. [构建并部署前端](#4-构建并部署前端)
5. [Nginx 反向代理配置](#5-nginx-反向代理配置)
6. [验证部署](#6-验证部署)
7. [常见问题排查](#7-常见问题排查)
8. [升级与回滚](#8-升级与回滚)

---

## 1. 环境要求

| 组件 | 最低版本 | 说明 |
|------|----------|------|
| 服务器 OS | Linux (Ubuntu 22.04 / Debian 12 推荐) | 也支持 CentOS / AlmaLinux |
| Docker | 24.x | `docker --version` 确认 |
| Docker Compose | v2.x | `docker compose version` 确认 |
| MySQL | 8.x | 可使用内网 MySQL 实例 |
| Nginx | 1.20+ | 用于前端静态托管 + API 反向代理 |
| Node.js（构建时） | 18+ | 仅前端打包时需要 |

---

## 2. 准备 MySQL 数据库

> **表结构无需手动创建**，后端启动时 GORM 会自动执行 `AutoMigrate` 建表。

### 2.1 创建数据库和用户

在 MySQL 服务器上执行：

```sql
CREATE DATABASE IF NOT EXISTS `mengyastore`
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

CREATE USER IF NOT EXISTS 'mengyastore'@'%'
  IDENTIFIED BY 'your_strong_password';

GRANT ALL PRIVILEGES ON `mengyastore`.* TO 'mengyastore'@'%';

FLUSH PRIVILEGES;
```

或者使用项目提供的初始化脚本：

```bash
mysql -u root -p < mengyastore-backend/init.sql
```

### 2.2 验证连接

```bash
mysql -h 192.168.1.100 -P 3306 -u mengyastore -p mengyastore
# 出现 mysql> 提示符即表示连接成功
```

---

## 3. 部署后端（Docker）

### 3.1 将代码上传到服务器

```bash
# 方式一：git clone（推荐）
git clone https://your-repo-url/mengyastore.git
cd mengyastore/mengyastore-backend

# 方式二：scp 上传
scp -r mengyastore-backend/ user@your-server:/opt/mengyastore/
```

### 3.2 创建 `config.json`

在 `mengyastore-backend/` 目录下创建配置文件（**此文件不会被提交到 Git，需手动创建**）：

```bash
cat > /opt/mengyastore/mengyastore-backend/config.json << 'EOF'
{
  "adminToken": "your_strong_admin_token",
  "databaseDsn": "mengyastore:your_password@tcp(192.168.1.100:3306)/mengyastore?charset=utf8mb4&parseTime=True&loc=Local"
}
EOF
```

> ⚠️ `adminToken` 请设置为足够强的随机字符串（建议 16 位以上），这是进入管理后台的唯一凭证。

### 3.3 检查 `docker-compose.yml`

确认 `mengyastore-backend/docker-compose.yml` 中的 `DATABASE_DSN` 与你的生产数据库匹配：

```yaml
services:
  backend:
    build:
      context: .
    container_name: mengyastore-backend
    ports:
      - "28081:8080"          # 宿主机端口:容器端口，可按需修改
    environment:
      GIN_MODE: release
      TZ: Asia/Shanghai
      DATABASE_DSN: "mengyastore:your_password@tcp(192.168.1.100:3306)/mengyastore?charset=utf8mb4&parseTime=True&loc=Local"
    volumes:
      - ./config.json:/app/config.json:ro    # 挂载配置文件（只读）
    restart: unless-stopped
```

> `DATABASE_DSN` 环境变量优先级高于 `config.json`，两者保持一致即可。

### 3.4 构建并启动容器

```bash
cd /opt/mengyastore/mengyastore-backend

# 首次部署
docker compose up -d --build

# 查看启动日志
docker compose logs -f

# 预期看到：
# [DB] 数据库连接成功，表结构已同步
# 萌芽小店后端启动于 http://localhost:8080
```

### 3.5 验证后端

```bash
curl http://localhost:28081/api/health
# 应返回：{"status":"ok"}

curl http://localhost:28081/api/products
# 应返回：{"data":[...]}（空数组或商品列表）
```

---

## 4. 构建并部署前端

### 4.1 本地构建（推荐在本地完成后上传 dist）

```bash
cd mengyastore-frontend

# 安装依赖
npm install

# 生产构建
npm run build
# 输出目录：dist/
```

### 4.2 配置 API 地址

前端通过 Vite 的 `VITE_API_BASE_URL` 环境变量指定后端地址。如果前端与后端同域（通过 Nginx 代理），也可以不配置，默认会使用当前站点域名。

如果前后端跨域，在 `mengyastore-frontend/` 目录创建 `.env.production`：

```ini
VITE_API_BASE_URL=https://store.api.shumengya.top
```

然后重新 `npm run build`。

### 4.3 上传 dist 到服务器

```bash
# 假设静态文件托管在 /var/www/mengyastore/
scp -r dist/* user@your-server:/var/www/mengyastore/

# 或使用 rsync（增量同步更快）
rsync -avz --delete dist/ user@your-server:/var/www/mengyastore/
```

---

## 5. Nginx 反向代理配置

### 5.1 安装 Nginx

```bash
# Ubuntu / Debian
sudo apt update && sudo apt install -y nginx

# CentOS / AlmaLinux
sudo yum install -y nginx
```

### 5.2 创建站点配置

```bash
sudo nano /etc/nginx/sites-available/mengyastore
```

写入以下内容（替换 `your-domain.com` 为你的实际域名）：

```nginx
server {
    listen 80;
    server_name your-domain.com;

    # 前端静态文件
    root /var/www/mengyastore;
    index index.html;

    # Vue Router History 模式：所有路由回退到 index.html
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 反向代理后端 API
    location /api/ {
        proxy_pass http://127.0.0.1:28081;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 30s;
        proxy_read_timeout 60s;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2|webmanifest)$ {
        expires 7d;
        add_header Cache-Control "public, immutable";
    }
}
```

### 5.3 启用配置并重启

```bash
sudo ln -s /etc/nginx/sites-available/mengyastore /etc/nginx/sites-enabled/
sudo nginx -t          # 测试配置语法
sudo systemctl reload nginx
```

### 5.4 （可选）配置 HTTPS（Let's Encrypt）

```bash
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
# 按提示操作，certbot 会自动修改 Nginx 配置并续签证书
```

---

## 6. 验证部署

### 6.1 检查列表

- [ ] `https://your-domain.com` 能正常打开首页
- [ ] 商品列表加载正常（若为空请先登录后台添加商品）
- [ ] 登录 SproutGate 账号后，收藏夹/聊天等功能正常
- [ ] **Logo 点击 5 次**弹出管理员登录框，输入 `adminToken` 能进入后台
- [ ] 后台可以新建/编辑/删除商品
- [ ] 下单流程（自动发货）能正常获取卡密
- [ ] PWA：在 Chrome 地址栏点击安装图标，可添加到桌面

### 6.2 后端日志查看

```bash
docker compose -f /opt/mengyastore/mengyastore-backend/docker-compose.yml logs -f
```

---

## 7. 常见问题排查

### 问题：前端白屏 / 控制台报 CORS 错误

**原因**：Nginx 未正确代理 `/api/` 请求，或后端未启动。

**排查**：
```bash
curl http://127.0.0.1:28081/api/health
docker compose ps   # 确认容器正在运行
```

---

### 问题：管理员登录失败（"验证失败，无法连接服务器"）

**原因**：后端容器未运行，或 Nginx `/api/` 代理配置有误。

**排查**：
```bash
docker compose ps
curl http://127.0.0.1:28081/api/health
```

---

### 问题：管理员登录失败（"令牌错误，请重试"）

**原因**：输入的令牌与 `config.json` 中的 `adminToken` 不一致。

**排查**：检查服务器上的 `config.json`：
```bash
cat /opt/mengyastore/mengyastore-backend/config.json
```

---

### 问题：商品列表为空

**原因**：数据库为空，需要通过管理后台添加商品。

**步骤**：
1. 登录管理后台
2. 点击"商品管理" → "新增商品"
3. 填写商品名称、价格、卡密（自动发货）或选择手动发货模式

---

### 问题：数据库连接失败（启动时报错）

**原因**：`DATABASE_DSN` 配置错误，或 MySQL 服务不可达。

**排查**：
```bash
# 在宿主机上测试数据库连接
mysql -h 192.168.1.100 -P 3306 -u mengyastore -p

# 查看后端详细日志
docker compose logs backend | head -50
```

---

### 问题：`record not found` 日志警告

**说明**：这是 GORM 的正常行为，表示某些站点设置（如维护模式）在数据库中尚未有记录。**不影响功能**，首次设置后会自动写入。

---

## 8. 升级与回滚

### 升级

```bash
cd /opt/mengyastore/mengyastore-backend

# 拉取最新代码（如果使用 git）
git pull

# 重新构建并重启
docker compose up -d --build

# 查看新版本日志
docker compose logs -f
```

### 回滚

```bash
# 查看历史镜像
docker images | grep mengyastore

# 停止当前容器，启动旧版本
docker compose down
docker tag mengyastore-backend-backend:previous mengyastore-backend-backend:latest
docker compose up -d
```

---

## 附：目录结构参考

```
/opt/mengyastore/
  mengyastore-backend/
    config.json          ← 生产配置（不要提交到 Git！）
    docker-compose.yml
    Dockerfile
    ...（Go 源码）

/var/www/mengyastore/    ← 前端 dist 文件
  index.html
  assets/
  ...
```

---

> 如遇到本指南未覆盖的问题，请查看后端实时日志：  
> `docker compose -f /opt/mengyastore/mengyastore-backend/docker-compose.yml logs -f`

**部署完成 🎉** 访问 `https://your-domain.com` 即可看到萌芽小店正式上线。
