Appearance
部署说明
一台 Ubuntu 服务器 + 域名即可完成全栈部署。
与代码一致的生产默认路径(宝塔):deploy/docker-compose.prod.yml 仅编排 MySQL、Redis、Go backend 三个容器;前端静态文件由 deploy.sh 调用 build-frontend-inner.sh 构建并写入本机目录 FRONTEND_DIST_PATH(宝塔 www 站点根);SSL / Nginx 由宝塔站点配置(或自建 Nginx),不是 compose 里的 shice-nginx 容器。下文「§3 全容器 Nginx」为可选/历史示意,若未单独启用对应 compose 栈则不存在这些容器名。
1. 服务器要求
| 项目 | 最低 | 推荐 |
|---|---|---|
| 系统 | Ubuntu 20.04 / Debian 11 | Ubuntu 22.04+ |
| CPU | 2 核 | 4 核 |
| 内存 | 4 GB | 8 GB |
| 磁盘 | 20 GB SSD | 40 GB+ SSD |
| 软件 | Docker 24+、Docker Compose v2 | — |
| 网络 | 公网 IP + 域名 | — |
2. 目录结构
部署相关文件全部在 deploy/ 目录下:
deploy/
├── docker-compose.yml # 开发:MySQL + Redis + Qdrant + MinIO
├── docker-compose.prod.yml # 生产:mysql + redis + backend(无 Nginx 容器)
├── docker-compose.frontend-builder.yml # 可选:compose 内构建前端镜像时
├── deploy.sh # 宝塔一键:前端静态 → FRONTEND_DIST_PATH;后端 build 或 pull
├── build-frontend-inner.sh # pnpm + vite 构建(被 deploy.sh 或 node 容器调用)
├── build-push-backend-image.sh # 本地/CI:buildx 推送后端镜像
├── .env.example # 含 BACKEND_IMAGE、BACKEND_PULL_ONLY 等
├── config.prod.yaml # 后端生产配置(挂载进容器)
├── init.sql
└── nginx/ # 参考配置(宝塔站点可照抄)
├── default.conf
└── baota-*.conf3. 生产架构(当前默认:宝塔 Nginx + Docker 应用)
text
Internet (HTTPS)
|
[宝塔 Nginx 宿主机 ]
www -> FRONTEND_DIST_PATH(静态 SPA)
api -> http://127.0.0.1:8080
|
[ Docker: shice-backend ]
+-- shice-mysql
+-- shice-redis| 单元 | 说明 |
|---|---|
| 前端静态 | deploy.sh 写入 FRONTEND_DIST_PATH;FRONTEND_BUILD_WITH_DOCKER 控制是否用 Docker 跑 Node |
shice-backend | 默认 docker compose build;可设 BACKEND_PULL_ONLY=1 与 BACKEND_IMAGE 仅 pull |
shice-mysql / shice-redis | 与 docker-compose.prod.yml 一致,端口不暴露公网 |
3.1 可选:全容器 Nginx(未包含在默认 prod compose)
若自行扩展 compose(增加 Nginx 容器与前端静态卷),可能出现文档旧版中的 shice-nginx、shice-frontend-builder 等命名。本仓库默认的 deploy.sh + docker-compose.prod.yml 不创建这些服务。
4. 一键部署步骤
4.1 安装 Docker
bash
# Ubuntu
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# 重新登录 shell 使 docker 组生效4.2 克隆代码
bash
git clone <repo-url> && cd shice_dev4.3 配置环境变量
bash
cd deploy
cp .env.example .env
vim .env.env 中必须修改的字段:
| 变量 | 说明 | 示例 |
|---|---|---|
MYSQL_ROOT_PASSWORD | MySQL root 密码 | 随机强密码 |
MYSQL_PASSWORD | 应用数据库密码 | 随机强密码 |
REDIS_PASSWORD | Redis 密码(可选) | 留空或设置密码 |
JWT_SECRET | JWT 签名密钥,至少 32 位随机字符串 | openssl rand -hex 32 |
AI_API_KEY | AI 模型 API Key(DeepSeek / OpenAI) | sk-xxx |
DOMAIN | 你的域名(用于推导默认 VITE_API_BASE_URL) | shice.example.com |
FRONTEND_DIST_PATH | 前端静态输出目录(宝塔站点根) | /www/wwwroot/www.example.com |
VITE_API_BASE_URL | 前端构建时 API 根路径(须含 /api/v1) | https://api.example.com/api/v1 |
FRONTEND_BUILD_WITH_DOCKER | 1 用官方 Node 镜像构建;0 用宿主机 pnpm | 0 或 1 |
BACKEND_IMAGE | 预构建后端镜像全名(与 BACKEND_PULL_ONLY 联用) | ghcr.io/org/shice-backend:tag |
BACKEND_PULL_ONLY | 1 时 deploy.sh 对 backend 执行 pull 而非 build | 0 或 1 |
4.4 同步生产配置
编辑 config.prod.yaml,确保以下值与 .env 一致:
yaml
database:
dsn: "shice:<MYSQL_PASSWORD>@tcp(mysql:3306)/shice?charset=utf8mb4&parseTime=True&loc=Local"
redis:
addr: "redis:6379"
password: "<REDIS_PASSWORD>"
jwt:
secret: "<JWT_SECRET>"
ai.api_key留空即可,运行时从环境变量AI_API_KEY注入。
4.5 执行部署
bash
chmod +x deploy.sh
./deploy.sh脚本会自动完成:
- 检查 Docker 环境
- 拉取最新代码(如果在 git 仓库中)
- 构建前端静态资源到
FRONTEND_DIST_PATH(Docker 内 Node 或宿主机 pnpm,见.env) - 后端镜像:默认
docker compose build backend;若BACKEND_PULL_ONLY=1则pull已推送的BACKEND_IMAGE docker compose up -d mysql redis backend- 打印服务状态与宝塔后续步骤提示
4.6 配置 HTTPS
bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.comCertbot 会自动修改 Nginx 配置并安装证书,证书自动续期。
5. 验证部署
bash
# 查看容器状态(应全部为 Up / healthy)
docker compose -f docker-compose.prod.yml ps
# 直接探活后端(根路径 /health,不经 /api/v1 前缀)
curl -sS http://127.0.0.1:8080/health
# 经域名(宝塔已反代 api 子域到 8080 时)
curl -sS https://api.your-domain.com/health
# 浏览器访问前端站点
https://your-domain.com6. 日常运维
查看日志
bash
cd deploy
# 后端日志
docker compose -f docker-compose.prod.yml logs -f backend
# MySQL 日志
docker compose -f docker-compose.prod.yml logs -f mysql
# 全部日志
docker compose -f docker-compose.prod.yml logs -f更新部署
bash
cd deploy
git -C .. pull
./deploy.sh脚本会重新构建前端静态、按需构建或拉取后端镜像并滚动重启相关容器。
重启单个服务
bash
docker compose -f docker-compose.prod.yml restart backend(默认 compose 无 Nginx 容器;Web 服务器日志在宝塔面板查看。)
停止 / 启动
bash
# 停止所有服务(保留数据)
docker compose -f docker-compose.prod.yml down
# 启动
docker compose -f docker-compose.prod.yml up -d
# 停止并删除所有数据卷(⚠️ 慎用!不可恢复)
docker compose -f docker-compose.prod.yml down -v数据库备份
bash
# 备份
docker exec shice-mysql mysqldump -u root -p<MYSQL_ROOT_PASSWORD> shice > backup_$(date +%Y%m%d).sql
# 恢复
docker exec -i shice-mysql mysql -u root -p<MYSQL_ROOT_PASSWORD> shice < backup_20260412.sql进入容器调试
bash
# 进入后端容器
docker exec -it shice-backend sh
# 进入 MySQL
docker exec -it shice-mysql mysql -u shice -p shice
# 进入 Redis
docker exec -it shice-redis redis-cli7. Nginx 配置说明
默认生产:Nginx 跑在宝塔宿主机上,可参考 deploy/nginx/baota-*.conf 与 README 中的 location 示例。default.conf 描述的是「单 Nginx 同时反代前后端」的参考写法(上游可能是 127.0.0.1:8080 或 Docker 网络中的 backend:8080,取决于你是否全容器化)。
deploy/nginx/default.conf 的关键配置(摘录):
| 路由 | 行为 |
|---|---|
/ | 前端 SPA,try_files 回退到 index.html |
/api/ | 反代到 backend:8080,关闭 proxy_buffering 以支持 SSE |
/health | 后端健康检查 |
静态资源 *.js, *.css 等 | 缓存 30 天,Cache-Control: public, immutable |
SSE 流式对话需要 Nginx 关闭代理缓冲:
nginx
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
chunked_transfer_encoding on;8. 安全清单
- [ ]
.env中所有密码改为强随机值 - [ ]
JWT_SECRET使用openssl rand -hex 32生成 - [ ]
AI_API_KEY通过环境变量注入,不提交到 git - [ ]
config.prod.yaml中server.mode: release - [ ]
config.prod.yaml中allow_mock_purchase: false - [ ] MySQL / Redis 端口不对外暴露(生产 compose 已默认不映射)
- [ ] 开启 UFW 防火墙,仅放行 22 / 80 / 443
- [ ] 配置 HTTPS(Let's Encrypt)
- [ ] 定期备份数据库
- [ ]
.env文件权限设为600
bash
# 防火墙设置
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable
# 限制 .env 权限
chmod 600 deploy/.env9. 开发环境
开发环境只需启动基础设施容器,前后端在本地运行:
bash
# 启动 MySQL + Redis + Qdrant + MinIO
cd deploy && docker-compose up -d
# 配置后端
cp backend/config.example.yaml backend/config.yaml
# 编辑 config.yaml,填入数据库密码和 AI API Key
# 启动后端
cd backend && go run ./cmd/server
# 启动前端 Web
cd frontend && pnpm install && pnpm dev:web
# 可选:Electron 壳(会再起 Vite 于 3000,勿与已有 dev:web 重复占用端口)
cd frontend && pnpm dev:desktop| 服务 | 地址 |
|---|---|
| 前端 | http://localhost:3000 |
| Electron 开发 | 同上(Electron 加载 Vite);生产包见 frontend/apps/desktop |
| 后端 API | http://localhost:8080 |
| MySQL | localhost:3306 |
| Redis | localhost:6379 |
| Qdrant | localhost:6333 |
| MinIO 控制台 | localhost:9001 |
10. 故障排查
| 症状 | 排查 |
|---|---|
| 容器启动失败 | docker compose logs <服务名> 查看错误日志 |
| 后端连不上 MySQL | 检查 config.prod.yaml 中 DSN 密码是否与 .env 一致 |
| 前端白屏 | 看 deploy.sh 是否成功;检查 FRONTEND_DIST_PATH 下是否有 index.html / assets;浏览器控制台是否 404;VITE_API_BASE_URL 是否指向正确 API |
| SSE 流式不工作 | 确认 Nginx proxy_buffering off;检查是否有 CDN 缓冲 |
| HTTPS 证书过期 | sudo certbot renew(通常自动续期) |
| 数据库表缺少新字段 | 后端启动时 GORM AutoMigrate 会自动添加新列;或手动执行 init.sql |
| AI 返回空 / 报错 | 检查 AI_API_KEY 是否有效、额度是否充足 |