# 多站点管理后台 前后端分离的多站点管理系统。 ## 项目结构 ``` yh_web/ ├── admin/ # 管理后台前端 (Vue 3 + Element Plus) - 端口 3000 ├── web/ # 前台页面 (Vue 3) - 端口 3001 ├── server/ # 后端 API (Go + Gin) - 端口 8080 └── README.md ``` ## 快速启动 ### 0. 本地开发:先启动 MongoDB 后端依赖 MongoDB,二选一即可: **方式一:本机已安装 MongoDB** 启动 MongoDB 服务后,在 `server/.env` 中设置 `MONGODB_URI=mongodb://localhost:27017`(复制 `.env.example` 为 `.env` 后改此项即可)。 **方式二:只用 Docker 跑一个 MongoDB(推荐,无需本机安装)** ```bash docker run -d --name yh_mongo -p 27017:27017 mongo:7 ``` 同样在 `server/.env` 中保持 `MONGODB_URI=mongodb://localhost:27017`。停止:`docker stop yh_mongo`,再启:`docker start yh_mongo`。 ### 1. 启动后端 ```bash cd server go mod tidy go run main.go ``` ### 2. 启动管理后台 ```bash cd admin npm install npm run dev ``` ### 3. 启动前台 ```bash cd web npm install npm run dev ``` ## 访问地址 - 管理后台: http://localhost:3000 - 前台: http://localhost:3001 - API: http://localhost:8080 ## 用 Docker 一键跑起来(推荐) 在项目根目录执行,用 Docker 拉镜像并启动全部服务(API、Web、Admin、MongoDB): **1. 准备环境变量** 若还没有 `server/.env`,复制一份并可按需修改: ```bash cp server/.env.example server/.env ``` **2. 国内网络可设镜像再拉镜像(避免超时)** ```bash # Windows PowerShell $env:REGISTRY_MIRROR="docker.m.daocloud.io/library/" docker compose up -d --build # Linux / Mac / Git Bash export REGISTRY_MIRROR=docker.m.daocloud.io/library/ docker compose up -d --build ``` 不设 `REGISTRY_MIRROR` 时直连 Docker Hub;若拉取超时再按上面设置镜像后重试。 **3. 访问** - 当前 compose 仅暴露 443,由 Nginx 反代;API 容器内监听 8088,通过 https 访问 /api。 停止:`docker compose down`。 ## 线上部署(项目根目录:~/project/yh_web) 线上路径为 `yxd@server1:~/project/yh_web`(即 `/home/yxd/project/yh_web`)。 ### 线上跑起来(以 Gitea 为准) 1. **本地**:提交并推送含「镜像加速」的代码(`docker-compose.yml`、各 `Dockerfile`、若已改脚本也同步到服务器)。 2. **服务器**:进入项目目录,**以 Gitea 为准**,直接执行拉取并重启脚本(脚本内会 `git fetch` + `git reset --hard origin/master`,本地修改会被覆盖)。 ```bash cd /www/yh_web # 或你的项目路径 ./pull-and-restart.sh ``` **重要**:`deploy/` 下构建产物(web/admin 静态文件、api 二进制)**不在仓库里**,仅靠 `git pull` 不会生成。拉取后**必须执行** `./pull-and-restart.sh`(或 `./restart.sh`)才会构建并启动,否则访问会 403/404。脚本已记录可执行权限,拉取后可直接 `./pull-and-restart.sh`,无需 chmod。 若你已手动执行过 `git pull` 且报错 `Your local changes would be overwritten`,先以远程为准:`git fetch origin && git reset --hard origin/master`,再执行 `./pull-and-restart.sh`。 采用**挂目录 + 替换文件**部署:脚本将 web/admin 构建到 `deploy/web/dist`、`deploy/admin/dist`,api 二进制到 `deploy/api/server`,容器挂载这些目录;更新时只重新构建产物并重启,无需重建前端镜像,仅 api 使用轻量运行时镜像。详见 `deploy/README.md`。构建会从 DaoCloud 等镜像拉取 node、nginx、golang、alpine、mongo,启动后**对外仅 443**,由 compose 内 Nginx 反代到 api/web/admin,证书按脚本自动处理。 **脚本说明**:仅保留两个脚本,均会检测 Docker 并在未安装时一键安装(apt 或 yum/dnf)。 - **拉取代码并重启**:`./pull-and-restart.sh` — 若无 Git 仓库会提示设置 `GIT_REPO_URL` 后自动克隆;然后拉取并构建、启动。 - **仅重启**:`./restart.sh` — 不拉代码,仅 `docker compose down` 后 `up -d`。 **Permission denied**:拉取后脚本可能无可执行权限,任选其一即可: ```bash chmod +x pull-and-restart.sh restart.sh # 或直接用 bash 执行(脚本内会自修复权限供下次使用) bash pull-and-restart.sh ``` 若报错 `bash\r`,先执行 `sed -i 's/\r$//' pull-and-restart.sh restart.sh`。 首次部署若目录为空,可先放入两个脚本,设置 `export GIT_REPO_URL='https://用户:Token@gitea.../web.git'` 后执行 `./pull-and-restart.sh` 完成克隆与启动。配置好 `server/.env` 后再次运行即可。 **产品视频自动导入**:`server/.env.example` 已含默认 `YH_IMPORT_PROMOTION_SITE_ID`;首次或拉代码后脚本会把 **`.env.example` 里尚未出现在 `server/.env` 的键自动追加**到 `server/.env`,**服务器只需执行 `./pull-and-restart.sh`**,无需手改配置。每次部署在 `compose up` 后会将 `web/promotion/视频发布/` 导入 `data/uploads` + `site_assets`(与 [官网](https://yuheng.yuxindazhineng.com/) `promotion-media` 一致)。多站点请改仓库内 `server/.env.example` 后再部署。 - **拉取并重启**:`cd ~/project/yh_web && ./pull-and-restart.sh` - **仅重启**:`cd ~/project/yh_web && ./restart.sh` - **对外域名**:https://yuheng.yuxindazhineng.com(所有请求均通过该域名,见下) **所有请求通过域名**:前台/后台生产环境使用同一域名,API 也走同域 `/api`。 - **有 Nginx Proxy Manager 时**:在 NPM 中配置反代即可: - `https://yuheng.yuxindazhineng.com/` → 本机 9528(web) - `https://yuheng.yuxindazhineng.com/admin/` → 本机 9529(admin) - `https://yuheng.yuxindazhineng.com/api` → 本机 8088(api) - **新服务器无 NPM、自建 Nginx 时**:使用项目内 **`nginx/`** 配置,强制 HTTPS,SSL 证书按域名单独目录存放。详见 **`nginx/README.md`**(证书目录:`/etc/ssl/yh_web/yuheng.yuxindazhineng.com/`,复制 `nginx/yuheng.yuxindazhineng.com.conf` 到 `/etc/nginx/conf.d/` 后重载 Nginx)。 前端 `VITE_API_BASE` 留空即请求同域 `/api`;后端 `server/.env` 中 `ALLOWED_ORIGINS=https://yuheng.yuxindazhineng.com` 用于 CORS。 **服务器无法访问 Docker Hub 时**(报错 `dial tcp ... i/o timeout`):一键脚本会自动写入 Podman 镜像配置到 `/etc/containers/registries.conf.d/99-docker-mirror.conf`(DaoCloud / 1ms / 徐轩辕等镜像)。若仍拉取失败: - **Podman**:确认主配置会加载该目录。若无效,可把 `99-docker-mirror.conf` 中的 `[[registry]]` 段合并进 `/etc/containers/registries.conf`。 - **Docker**:编辑 `/etc/docker/daemon.json` 添加 `"registry-mirrors": ["https://docker.1ms.run"]` 后 `sudo systemctl restart docker`。 然后重新运行启动脚本。 **报错 `listen tcp4 :8088: bind: address already in use`**:当前 `docker-compose.yml` 中 **api 未映射任何宿主机端口**,`PORT=8088` 仅容器内监听。该错误多为服务器上曾用旧版 compose 映射过 8088,或宿主机其他进程占用。处理:确认已 `git pull` 到最新(compose 无 api 的 `ports`),执行 `docker compose down`(或直接再次执行 `./pull-and-restart.sh`,脚本内已先 down 再 up)后重试;若仍报错,在服务器上执行 `ss -tlnp | grep 8088` 或 `lsof -i :8088` 查看占用进程并结束。