# 萌芽小店 · 生产环境部署指南 > 覆盖生产环境部署要点:后端目录为 **`mengyastore-backend-go`**,配置以 **环境变量** 为主(与本地 `.env` / `.env.production` 一致),无需再依赖 `config.json`。 --- ## 目录 1. [环境要求](#1-环境要求) 2. [准备 MySQL](#2-准备-mysql) 3. [部署后端(Docker)](#3-部署后端docker) 4. [构建并部署前端](#4-构建并部署前端) 5. [Nginx 反向代理](#5-nginx-反向代理) 6. [验证部署](#6-验证部署) 7. [常见问题](#7-常见问题) 8. [升级与回滚](#8-升级与回滚) --- ## 1. 环境要求 | 组件 | 说明 | |------|------| | Linux 服务器 | Ubuntu 22.04 / Debian 12 等 | | Docker 24+、Compose v2 | `docker compose version` | | MySQL 8.x | 可内网独立实例 | | Nginx 1.20+ | 静态资源 + `/api/` 反代 | | Node.js 18+ | 仅前端 **构建** 时使用 | 可选:内网 **RabbitMQ**、**Redis**(与 `docker-compose` / 环境变量一致即可)。 --- ## 2. 准备 MySQL 表结构由后端 **GORM AutoMigrate** 自动创建,只需 **建库 + 授权**: ```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; ``` 也可参考仓库内 `mengyastore-backend-go/init.sql`。 --- ## 3. 部署后端(Docker) ### 3.1 代码路径 ```bash git clone https://github.com/shumengya/mengyastore.git # 或你的仓库 cd mengyastore/mengyastore-backend-go ``` > 若历史文档写成 `mengyastore-backend`,请改为 **`mengyastore-backend-go`**。 ### 3.2 配置方式(推荐) 生产 **不要** 把真实口令写进 Git。任选其一: - **A.** 在宿主机导出环境变量后执行 `docker compose up`(Compose 中 `${VAR:-默认值}` 会读取宿主机环境)。 - **B.** 在服务器的 `mengyastore-backend-go/` 放置 **`.env`**(勿提交),并在 `docker-compose.yml` 中增加 `env_file: .env`(若你自行加上该条目);当前仓库默认 compose **未挂载** `.env`,请通过 **environment** 或 **export** 注入。 **必填 / 常用变量(与 `internal/config/config.go` 一致):** | 变量 | 说明 | |------|------| | `APP_ENV` | `production` | | `DATABASE_DSN` | 生产 MySQL 连接串 | | `ADMIN_TOKEN` | 管理后台令牌(强随机) | | `AUTH_API_URL` | SproutGate 认证网关 Base URL | | `RABBITMQ_ENABLED` | `true` / `false` | | `RABBITMQ_URL` | 启用 MQ 时完整 `amqp://…`(或用各 `RABBITMQ_*` 拼装,见配置注释) | | `REDIS_ENABLED` | `true` / `false` | | `REDIS_ADDR`、`REDIS_PASSWORD`、`REDIS_DB` | 启用 Redis 探测/缓存时 | | `HTTP_LISTEN_ADDR` | 可选,默认容器内 `:8080` | | `PUBLIC_API_BASE_URL` | 可选,管理端「系统状态」展示的对外 API 基址(反代 HTTPS 时建议设) | 根据业务关闭不需要的中间件时,将 `RABBITMQ_ENABLED` 或 `REDIS_ENABLED` 设为 `false`,避免无实例仍去连接。 ### 3.3 修改 `docker-compose.yml` 部署前请 **核对并本地化**: - `DATABASE_DSN` 指向你的库。 - `ports`(示例 `28081:8080`)是否与 Nginx `proxy_pass` 一致。 - **删除或替换** 仓库中带默认口令的示例值;通过宿主机环境注入生产密钥。 示例(**仅结构示意,口令用环境变量**): ```yaml services: backend: build: { context: . } container_name: mengyastore-backend ports: - "28081:8080" environment: APP_ENV: production GIN_MODE: release TZ: Asia/Shanghai DATABASE_DSN: ${DATABASE_DSN} ADMIN_TOKEN: ${ADMIN_TOKEN} AUTH_API_URL: ${AUTH_API_URL:-} REDIS_ENABLED: ${REDIS_ENABLED:-false} REDIS_ADDR: ${REDIS_ADDR:-} REDIS_PASSWORD: ${REDIS_PASSWORD:-} RABBITMQ_ENABLED: ${RABBITMQ_ENABLED:-false} RABBITMQ_ENV: prod RABBITMQ_URL: ${RABBITMQ_URL:-} restart: unless-stopped ``` ### 3.4 启动 ```bash cd /opt/mengyastore/mengyastore-backend-go # 你的实际路径 export DATABASE_DSN='...' export ADMIN_TOKEN='...' # … 其他变量按需 export docker compose up -d --build docker compose logs -f ``` 预期日志含:`[DB] 数据库连接成功,表结构已同步`、`萌芽小店后端启动于 http://localhost:8080`。 ### 3.5 健康检查 ```bash curl -s http://127.0.0.1:28081/api/health curl -s http://127.0.0.1:28081/api/products ``` --- ## 4. 构建并部署前端 ```bash cd mengyastore-frontend npm ci || npm install ``` **同源部署**(Nginx 把 `/api/` 反代到后端):构建前可不设 `VITE_API_BASE_URL`,打包后请求会走当前站点域名。 **前后端不同域**:创建 `.env.production`: ```env VITE_API_BASE_URL=https://你的-api-域名 ``` ```bash npm run build ``` 将 `dist/` 同步到服务器,例如 `/var/www/mengyastore/`: ```bash rsync -avz --delete dist/ user@server:/var/www/mengyastore/ ``` --- ## 5. Nginx 反向代理 ```nginx server { listen 80; server_name your-domain.com; root /var/www/mengyastore; index index.html; location / { try_files $uri $uri/ /index.html; } 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"; } } ``` HTTPS 可使用 `certbot --nginx` 签发 Let's Encrypt。 --- ## 6. 验证部署 - [ ] 首页与商品列表正常。 - [ ] SproutGate 登录后收藏、聊天、我的订单可用。 - [ ] **Logo 连点 5 次** → 管理员验证 → 带 `?token=` 或使用 `X-Admin-Token` 访问后台。 - [ ] 后台 **系统状态**:MySQL / Redis / RabbitMQ(若启用)显示合理。 - [ ] 商品:**卡密** 与 **固定内容** 两种类型可分别保存;固定内容商品前台库存显示「不限」。 - [ ] 下一单:结算页金额、收款码区、**复制订单号**、确认后内容与邮件/MQ 预期一致(依你的 SMTP/MQ 配置)。 - [ ] PWA 可安装(如需要)。 --- ## 7. 常见问题 **CORS / 白屏** 确认 Nginx `location /api/` 指向后端端口,且容器 `docker compose ps` 为运行中。 **管理 Token 无效** 核对容器内实际生效的 `ADMIN_TOKEN`(与前端输入一致)。当前项目 **不再依赖** `config.json`。 **RabbitMQ 报 504 / channel closed** 服务端已实现重连与消费重启;若仍异常,查 Broker 日志、网络与 `RABBITMQ_URL`/vhost/权限。 **数据库连不上** 在宿主机用 `mysql` 客户端测 `DATABASE_DSN` 同款主机端口账号;Docker 网络须能访问 MySQL。 **站点设置 KV 查询** 后端对缺失的 `site_settings` 键使用不产生「record not found」噪声的查询方式;首次保存 SMTP 等后会写入库表。 --- ## 8. 升级与回滚 ```bash cd mengyastore-backend-go git pull docker compose up -d --build docker compose logs -f --tail=100 ``` 回滚:保留上一版本的镜像 tag 或 git tag,重新 `docker compose up` 指定旧镜像(视你实际镜像命名而定)。 --- ## 附:目录结构示例 ``` /opt/mengyastore/ mengyastore-backend-go/ docker-compose.yml Dockerfile .env ← 仅存服务器本地,勿提交 Git ... /var/www/mengyastore/ ← 前端 dist index.html assets/ ``` 部署完成后访问你的域名即可。