# dev-tunnel - 本地开发隧道 通过 SSH 反向隧道将本地服务暴露到生产服务器,实现完整的本地开发调试(前端+后端),同时使用生产域名和微信授权。 ## 使用场景 - 本地调试需要微信授权回调 - 本地调试需要使用生产域名 - 需要同时调试前端和后端 - 本地没有公网 IP ## 命令 ``` /dev-tunnel start # 启动本地调试模式 /dev-tunnel stop # 恢复生产环境 /dev-tunnel status # 查看当前状态 ``` ## 架构说明 ``` 生产环境: /api/*, /socket.io/* → localhost:3000 → PM2(gala-server) /screen* → 静态文件 (client-screen/dist) 其他 → 静态文件 (client-mobile/dist) 调试模式: /api/*, /socket.io/* → localhost:3001 → 隧道 → 本地:3000 (后端) /screen* → localhost:5174 → 隧道 → 本地:5174 (大屏 dev) 其他 → localhost:5173 → 隧道 → 本地:5173 (移动端 dev) ``` ## 隧道端口映射 | 服务 | 服务器端口 | 本地端口 | |------|-----------|---------| | 后端 API | 3001 | 3000 | | 移动端前端 | 5173 | 5173 | | 大屏端前端 | 5174 | 5174 | ## 操作步骤 ### start - 启动调试模式 1. **服务器**: 停止 PM2 后端服务 2. **服务器**: 切换 Caddy 为调试模式配置 3. **本地**: 切换 MOBILE_CLIENT_URL 为生产域名(自动执行) 4. **本地**: 建立 SSH 隧道(自动执行) 5. **本地**: 启动后端和前端 dev server(手动执行) ### stop - 恢复生产环境 1. **本地**: 终止 SSH 隧道进程(自动执行) 2. **本地**: 恢复 MOBILE_CLIENT_URL 为本地地址(自动执行) 3. **服务器**: 恢复 Caddy 生产环境配置 4. **服务器**: 重启 PM2 后端服务 ## 具体命令 ### 启动调试模式 ```bash # 1. 停止服务器后端 ssh vote "pm2 stop gala-server" # 2. 切换 Caddy 为调试模式配置 # 注意:需要先将 Caddyfile.debug 上传到服务器,或直接替换内容 ssh vote "cat > /etc/caddy/Caddyfile << 'EOF' { email let5sne@gmail.com } 2026.cptp.let5see.xyz { handle /A6e75lM1ge.txt { respond \"3a5d2d7f410fbcbc32e3c222b2cf28bf\" } handle /screen* { reverse_proxy localhost:5174 } handle /api/* { header Cache-Control \"no-store, no-cache, must-revalidate\" reverse_proxy localhost:3001 } handle /socket.io/* { reverse_proxy localhost:3001 } handle /avatars/* { reverse_proxy localhost:3001 } handle { reverse_proxy localhost:5173 } encode gzip } EOF" # 3. 重载 Caddy ssh vote "caddy reload --config /etc/caddy/Caddyfile" # 4. 切换 MOBILE_CLIENT_URL 为生产域名 sed -i '' 's|MOBILE_CLIENT_URL=http://localhost:5173|MOBILE_CLIENT_URL=https://2026.cptp.let5see.xyz|g' packages/server/.env # 5. 切换大屏端 VITE_MOBILE_URL 为生产域名 sed -i '' 's|VITE_MOBILE_URL=http://localhost:5173|VITE_MOBILE_URL=https://2026.cptp.let5see.xyz|g' packages/client-screen/.env.development # 6. 切换移动端 VITE_SOCKET_URL/VITE_API_URL 为生产域名 sed -i '' 's|VITE_SOCKET_URL=http://localhost:3000|VITE_SOCKET_URL=https://2026.cptp.let5see.xyz|g' packages/client-mobile/.env.development sed -i '' 's|VITE_API_URL=http://localhost:3000|VITE_API_URL=https://2026.cptp.let5see.xyz|g' packages/client-mobile/.env.development # 7. 建立 SSH 隧道(自动后台运行) ssh -R 3001:localhost:3000 -R 5173:localhost:5173 -R 5174:localhost:5174 vote -N -o ServerAliveInterval=30 # 6. 本地启动服务(3个终端,手动执行) # 终端1: 后端 pnpm --filter @gala/server dev # 终端2: 移动端前端 pnpm --filter @gala/client-mobile dev --host # 终端3: 大屏端前端 pnpm --filter @gala/client-screen dev --host ``` ### 恢复生产环境 ```bash # 1. 终止本地 SSH 隧道进程 pkill -f "ssh -R 3001:localhost:3000" # 2. 恢复 MOBILE_CLIENT_URL 为本地地址 sed -i '' 's|MOBILE_CLIENT_URL=https://2026.cptp.let5see.xyz|MOBILE_CLIENT_URL=http://localhost:5173|g' packages/server/.env # 3. 恢复大屏端 VITE_MOBILE_URL 为本地地址 sed -i '' 's|VITE_MOBILE_URL=https://2026.cptp.let5see.xyz|VITE_MOBILE_URL=http://localhost:5173|g' packages/client-screen/.env.development # 4. 恢复移动端 VITE_SOCKET_URL/VITE_API_URL 为本地地址 sed -i '' 's|VITE_SOCKET_URL=https://2026.cptp.let5see.xyz|VITE_SOCKET_URL=http://localhost:3000|g' packages/client-mobile/.env.development sed -i '' 's|VITE_API_URL=https://2026.cptp.let5see.xyz|VITE_API_URL=http://localhost:3000|g' packages/client-mobile/.env.development # 5. 恢复 Caddy 生产环境配置 ssh vote "cat > /etc/caddy/Caddyfile << 'EOF' { email let5sne@gmail.com } 2026.cptp.let5see.xyz { handle /A6e75lM1ge.txt { respond \"3a5d2d7f410fbcbc32e3c222b2cf28bf\" } handle /screen* { root * /root/company-celebration/packages/client-screen/dist uri strip_prefix /screen try_files {path} /index.html file_server header Cache-Control \"no-cache, no-store, must-revalidate\" @screenassets path_regexp assets \\/assets\\/.* header @screenassets Cache-Control \"public, max-age=31536000, immutable\" } handle /api/* { header Cache-Control \"no-store, no-cache, must-revalidate\" reverse_proxy localhost:3000 } handle /socket.io/* { reverse_proxy localhost:3000 } handle { root * /root/company-celebration/packages/client-mobile/dist try_files {path} /index.html file_server header Cache-Control \"no-cache, no-store, must-revalidate\" @mobileassets path_regexp assets \\/assets\\/.* header @mobileassets Cache-Control \"public, max-age=31536000, immutable\" } encode gzip } EOF" # 3. 重载 Caddy ssh vote "caddy reload --config /etc/caddy/Caddyfile" # 4. 重启服务器后端 ssh vote "pm2 restart gala-server" ``` ## 前端 dev server 配置 ### 必需配置 两个前端项目的 `vite.config.ts` 需要包含以下配置: **client-mobile** (端口 5173): ```ts server: { host: '0.0.0.0', port: 5173, allowedHosts: ['2026.cptp.let5see.xyz'], } ``` **client-screen** (端口 5174): ```ts server: { host: '0.0.0.0', port: 5174, allowedHosts: ['2026.cptp.let5see.xyz'], } ``` ### 配置说明 | 配置项 | 说明 | |--------|------| | `host: '0.0.0.0'` | 允许外部网络访问 | | `allowedHosts` | 允许通过生产域名访问,否则 Vite 会拒绝请求 | | `base: '/screen/'` | 大屏端需要配置,支持 `/screen` 路径前缀 | ## 注意事项 - SSH 隧道断开后,生产环境将不可用,务必及时恢复 - 调试完成后**必须执行 stop** 恢复生产环境 - 隧道命令需要保持终端运行,关闭终端会断开隧道 - 本地需要同时运行 4 个终端(后端 + 2个前端 + 隧道) ## 文件说明 - `Caddyfile.production` - 生产环境 Caddy 配置模板 - `Caddyfile.debug` - 调试模式 Caddy 配置模板