# AI-Proj 部署指南 **创建时间**: 2026-01-29 11:50:00 CST **父技能**: ops-tools ## 环境概览 | 环境 | 服务器 | 域名 | 镜像标签 | |------|--------|------|----------| | 生产 | tools_ai_proj (152.136.104.251) | https://ai.pipexerp.com | `latest` | | 测试 | singapore (43.134.28.147) | http://staging.ai.pipexerp.com | `test` | ## 镜像信息 | 服务 | 镜像 | |------|------| | 后端 | `saltthing123/ai-proj-backend` | | 前端 | `saltthing123/ai-proj-frontend` | ## 标准部署流程 ### 部署到测试环境 ```bash cd /path/to/new-ai-proj # 构建后端 test 镜像 docker buildx build --platform linux/amd64 -f backend/Dockerfile --target production \ -t saltthing123/ai-proj-backend:test --push backend/ # 构建前端 test 镜像 docker buildx build --platform linux/amd64 -f frontend/Dockerfile.prod --target production \ --build-arg REACT_APP_API_URL=https://staging.ai.pipexerp.com/api/v1 \ --build-arg REACT_APP_API_BASE_URL=https://staging.ai.pipexerp.com/api/v1 \ --build-arg REACT_APP_ENV=staging \ -t saltthing123/ai-proj-frontend:test --push frontend/ # 部署到测试服务器 ssh singapore "cd /opt/ai-project-staging && sudo docker-compose pull && sudo docker-compose up -d" ``` ### 部署到生产环境 ```bash cd /path/to/new-ai-proj # 构建后端 latest 镜像 docker buildx build --platform linux/amd64 -f backend/Dockerfile --target production \ -t saltthing123/ai-proj-backend:latest --push backend/ # 构建前端 latest 镜像 docker buildx build --platform linux/amd64 -f frontend/Dockerfile.prod --target production \ --build-arg REACT_APP_API_URL=https://ai.pipexerp.com/api/v1 \ --build-arg REACT_APP_API_BASE_URL=https://ai.pipexerp.com/api/v1 \ --build-arg REACT_APP_ENV=production \ -t saltthing123/ai-proj-frontend:latest --push frontend/ # 部署到生产服务器 ssh tools_ai_proj "cd /opt/ai-project && \ docker compose -f deploy/tencent-cloud/docker-compose.dockerhub.yml pull && \ docker compose -f deploy/tencent-cloud/docker-compose.dockerhub.yml up -d" ``` ## 新加坡服务器 Build(备选方案) 本地网络慢时,在新加坡服务器构建: ```bash # 后端 ssh singapore "cd ~/projects/new-ai-proj && git pull && \ docker build --platform linux/amd64 -f backend/Dockerfile --target production \ -t saltthing123/ai-proj-backend:latest ./backend && \ docker push saltthing123/ai-proj-backend:latest" # 前端(生产) ssh singapore "cd ~/projects/new-ai-proj && \ docker build --platform linux/amd64 -f frontend/Dockerfile.prod --target production \ --build-arg REACT_APP_API_URL=https://ai.pipexerp.com/api/v1 \ --build-arg REACT_APP_API_BASE_URL=https://ai.pipexerp.com/api/v1 \ --build-arg REACT_APP_ENV=production \ -t saltthing123/ai-proj-frontend:latest ./frontend && \ docker push saltthing123/ai-proj-frontend:latest" ``` ## 自动部署(Webhook) **状态**: 已启用 (2026-01-16) ``` git push main → Gitea webhook → Jenkins ai-proj → 生产自动部署 ``` ## 服务管理 ```bash # 查看容器状态 ssh tools_ai_proj "docker ps --format 'table {{.Names}}\t{{.Status}}'" # 查看日志 ssh tools_ai_proj "docker logs -f ai_backend_prod --tail 100" # 重启服务 ssh tools_ai_proj "docker restart ai_backend_prod" # 健康检查 curl -s https://ai.pipexerp.com/api/v1/health | jq . ``` ## 测试环境管理 ```bash # 查看状态 ssh singapore "sudo docker-compose -f /opt/ai-project-staging/docker-compose.yml ps" # 查看日志 ssh singapore "sudo docker logs -f ai_backend_staging --tail 100" # 健康检查 ssh singapore "curl -s -H 'Host: staging.ai.pipexerp.com' http://127.0.0.1/api/v1/health" ``` ## Docker Volumes 配置 **重要**: 数据卷必须标记为 `external: true` ```yaml volumes: postgres_prod_data: external: true name: ai-project_postgres_prod_data redis_prod_data: external: true name: ai-project_redis_prod_data ``` ## 数据库操作 ```bash # 运行迁移 ssh tools_ai_proj "cd /opt/ai-project/backend/migrations && \ for file in \$(ls *.sql | grep -v _down.sql | sort); do \ docker exec -i ai_postgres_prod psql -U ai_prod_user -d ai_project_prod < \"\$file\"; \ done" # 备份 ssh tools_ai_proj "docker exec ai_postgres_prod pg_dump -U ai_prod_user ai_project_prod > /tmp/backup.sql" ``` ## 用户管理 > **重要**: 密码哈希必须使用 bcrypt **cost 12**,这是后端 `utils/password.go` 中的 `DefaultCost` 值。 ### 创建用户完整流程 由于 bcrypt 哈希包含 `$` 字符会被 shell 解释,必须使用文件传输方式: ```bash # 1. 生成密码哈希(在有 Go 环境的机器上执行) cd /path/to/new-ai-proj/backend cat > /tmp/genhash.go << 'EOF' package main import ("fmt"; "golang.org/x/crypto/bcrypt") func main() { hash, _ := bcrypt.GenerateFromPassword([]byte("用户密码"), 12) fmt.Println(string(hash)) } EOF HASH=$(go run /tmp/genhash.go) echo "Generated hash: $HASH" # 2. 创建 SQL 文件 cat > /tmp/create_user.sql << EOF INSERT INTO users (username, email, password_hash, user_type, role, status, created_at, updated_at) VALUES ('newuser', 'newuser@example.com', '$HASH', 'system', 'admin', 'active', NOW(), NOW()); EOF # 3. 传输并执行 scp /tmp/create_user.sql tools_ai_proj:/tmp/ ssh tools_ai_proj "docker cp /tmp/create_user.sql ai_postgres_prod:/tmp/ && \ docker exec ai_postgres_prod psql -U ai_prod_user -d ai_project_prod -f /tmp/create_user.sql" # 4. 验证 curl -s -X POST "https://ai.pipexerp.com/api/v1/auth/login" \ -H "Content-Type: application/json" \ -d '{"username":"newuser","password":"用户密码"}' | jq '.success' ``` ### 用户角色 | user_type | role | 权限 | |-----------|------|------| | system | admin | 系统管理员 | | system | user | 系统用户 | | tenant | admin | 租户管理员 | | tenant | user | 租户用户 | ### 重置密码 ```bash # 生成新哈希并更新 cd /path/to/new-ai-proj/backend HASH=$(go run -e 'package main; import ("fmt";"golang.org/x/crypto/bcrypt"); func main() { h,_:=bcrypt.GenerateFromPassword([]byte("新密码"),12); fmt.Println(string(h)) }' 2>/dev/null || cat > /tmp/h.go << 'E' package main import ("fmt";"golang.org/x/crypto/bcrypt") func main() { h,_:=bcrypt.GenerateFromPassword([]byte("新密码"),12); fmt.Println(string(h)) } E go run /tmp/h.go) cat > /tmp/reset.sql << EOF UPDATE users SET password_hash = '$HASH' WHERE username = 'targetuser'; EOF scp /tmp/reset.sql tools_ai_proj:/tmp/ ssh tools_ai_proj "docker cp /tmp/reset.sql ai_postgres_prod:/tmp/ && \ docker exec ai_postgres_prod psql -U ai_prod_user -d ai_project_prod -f /tmp/reset.sql" ``` ### 常见错误 | 问题 | 原因 | 解决 | |------|------|------| | 登录失败 | bcrypt cost 不是 12 | 用 Go 重新生成 cost 12 的哈希 | | 哈希被截断 | shell 解释了 $ 符号 | 使用文件传输方式 | ### 已创建的系统用户 | 用户名 | 邮箱 | user_type | role | 创建时间 | |--------|------|-----------|------|----------| | qiudl | qiudl@zhiyuncai.com | system | admin | - | | jiaxiang | jiaxiang@joylodging.com | system | admin | 2026-01 | | haiqing | haiqing@joylodging.com | system | admin | 2026-02 | > 注意:密码信息不在文档中记录,如需重置请使用上述重置密码流程 ## 前端构建注意事项 必须同时设置两个 URL 变量: - `REACT_APP_API_URL` - `REACT_APP_API_BASE_URL` 否则会使用 `.env.production` 中的生产 URL。 验证镜像中的 URL: ```bash docker exec sh -c 'grep -oE "https://[a-zA-Z0-9.-]*pipexerp[a-zA-Z0-9./-]*" /usr/share/nginx/html/static/js/main*.js | sort | uniq -c' ```