Clawdbot+Qwen3-32B部署教程:Nginx反向代理配置、HTTPS支持与跨域(CORS)解决方案
1. 为什么需要这套部署方案
你是不是也遇到过这样的问题:本地跑着Qwen3-32B大模型,用Ollama启动后能通过http://localhost:11434/api/chat调用,但想把它接入Clawdbot做Web聊天平台时,浏览器直接报错“跨域被拒绝”?或者把Clawdbot前端部署到https://chat.example.com,后端却只能走http://localhost:11434,结果页面一片空白,控制台全是红色错误?
这不是你代码写错了,而是典型的现代Web应用部署“三座大山”:反向代理没配好、HTTPS没打通、跨域策略没绕过。
本文不讲抽象概念,只带你一步步把Clawdbot和Qwen3-32B真正跑通——从Ollama加载模型开始,到Nginx反向代理落地,再到HTTPS证书自动续签和CORS精准放行。所有操作都在真实Linux服务器(Ubuntu 22.04)上验证通过,命令可复制粘贴,配置项有明确解释,连Nginx日志怎么看都告诉你。
你不需要是运维专家,只要会SSH登录、能敲命令、愿意照着步骤试一遍,就能让自己的私有大模型聊天平台稳稳上线。
2. 环境准备与基础服务启动
2.1 确认系统与依赖
先确保你的服务器满足基本要求:
- 操作系统:Ubuntu 22.04 LTS(其他Debian系也可,CentOS需微调命令)
- 内存:≥64GB(Qwen3-32B推理对内存敏感,低于此值易OOM)
- 磁盘:≥120GB空闲空间(模型文件+缓存)
- 已安装Docker(Clawdbot官方镜像基于Docker)
执行以下命令检查基础环境:
# 查看系统版本 lsb_release -a # 检查内存(单位GB) free -h | awk '/^Mem:/ {print $2}' # 确认Docker已运行 sudo systemctl is-active docker如果Docker未安装,请先执行:
sudo apt update && sudo apt install -y curl gnupg2 software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io sudo usermod -aG docker $USER # 退出终端重登,或执行 newgrp docker2.2 启动Qwen3-32B模型(Ollama方式)
Clawdbot本身不托管模型,它通过HTTP调用外部LLM API。我们选择Ollama作为后端模型服务,因其轻量、易部署、原生支持Qwen系列。
注意:Qwen3-32B需Ollama v0.4.0+,请先升级
curl -fsSL https://ollama.com/install.sh | sh
拉取并运行Qwen3-32B(首次运行会下载约65GB模型文件,请确保网络稳定):
# 拉取模型(后台静默下载,可用 ollama list 查看进度) ollama pull qwen3:32b # 启动Ollama服务(默认监听 127.0.0.1:11434) sudo systemctl enable ollama sudo systemctl start ollama # 验证API是否就绪(返回应为 {} 或模型信息) curl http://localhost:11434/api/tags此时,Ollama已在本地提供标准OpenAI兼容API:
- Chat接口:
POST http://localhost:11434/api/chat - Embeddings接口:
POST http://localhost:11434/api/embeddings
但注意:这个地址不能被浏览器直接访问——因为它是http协议,且绑定在127.0.0.1,外部无法连通。这正是我们需要Nginx介入的原因。
2.3 启动Clawdbot前端服务
Clawdbot提供预构建Docker镜像,无需编译前端:
# 创建数据目录 mkdir -p ~/clawdbot/data # 运行Clawdbot(映射到宿主机8080端口) docker run -d \ --name clawdbot \ -p 8080:80 \ -v ~/clawdbot/data:/app/data \ -e API_BASE_URL="http://localhost:11434" \ --restart=always \ ghcr.io/clawdbot/clawdbot:latest此时不要急着打开浏览器!因为API_BASE_URL设为http://localhost:11434,Clawdbot前端(运行在Docker内)会尝试从容器内部访问Ollama——而Docker默认网络中localhost指向容器自身,不是宿主机。所以这步会失败。
正确做法是:先不配置API,让Clawdbot以纯静态页启动,后续由Nginx统一代理所有请求。我们稍后会修改其配置。
3. Nginx反向代理核心配置
3.1 安装与基础配置
sudo apt install -y nginx sudo systemctl enable nginx sudo systemctl start nginxNginx默认监听80端口。我们要让它同时承担三重角色:
- 将
https://chat.yourdomain.com的请求转发给Clawdbot容器(8080端口) - 将
/api/路径下的请求(如/api/chat)转发给Ollama(11434端口) - 在转发过程中注入CORS头,并处理HTTPS卸载
创建独立配置文件,避免污染默认配置:
sudo nano /etc/nginx/sites-available/clawdbot填入以下内容(请将chat.yourdomain.com替换为你的真实域名):
upstream clawdbot_backend { server 127.0.0.1:8080; } upstream ollama_backend { server 127.0.0.1:11434; } server { listen 80; server_name chat.yourdomain.com; # HTTP → HTTPS 强制跳转 return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name chat.yourdomain.com; # SSL证书路径(Let's Encrypt自动生成) ssl_certificate /etc/letsencrypt/live/chat.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/chat.yourdomain.com/privkey.pem; # SSL优化(复用、加密套件) ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; # 根路径:代理Clawdbot前端 location / { proxy_pass http://clawdbot_backend; 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_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # API路径:代理Ollama后端(关键!) location /api/ { proxy_pass http://ollama_backend/; 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_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 关键:CORS头(允许任意源,仅限开发/内网;生产建议限定源) add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE' always; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; # 处理预检请求(OPTIONS) if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE' always; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always; add_header 'Access-Control-Max-Age' 1728000 always; add_header 'Content-Type' 'text/plain; charset=utf-8' always; add_header 'Content-Length' 0 always; return 204; } } # 静态资源缓存(提升前端加载速度) location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } }启用配置并测试语法:
sudo ln -sf /etc/nginx/sites-available/clawdbot /etc/nginx/sites-enabled/ sudo nginx -t # 应输出 "syntax is ok" sudo systemctl reload nginx3.2 配置说明:为什么这样写
upstream块定义了两个后端服务别名,让proxy_pass更清晰,也方便后续加负载均衡。location /api/末尾的/很重要:它确保/api/chat被重写为/chat发给Ollama(Ollama API根路径是/api/,不是/api/api/)。add_header ... always确保响应头在所有状态码下都生效(包括4xx/5xx错误),避免CORS被忽略。if ($request_method = 'OPTIONS')是处理浏览器预检请求的标准写法,必须显式返回204。proxy_set_header系列保证后端能获取真实客户端IP和协议,Clawdbot日志和限流才准确。
4. HTTPS证书自动化(Let's Encrypt)
没有HTTPS,现代浏览器会直接屏蔽fetch请求。我们用Certbot自动申请并续期。
sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d chat.yourdomain.com执行后按提示操作,Certbot会:
- 自动修改Nginx配置,插入SSL证书路径
- 申请证书(需域名DNS已解析到本服务器IP)
- 配置自动续期定时任务(
/etc/cron.d/certbot)
验证证书是否生效:
# 查看证书信息 sudo certbot certificates # 手动续期测试(不中断服务) sudo certbot renew --dry-run成功标志:打开
https://chat.yourdomain.com,浏览器地址栏显示锁图标,且无安全警告。
5. Clawdbot前端适配与最终验证
5.1 修改Clawdbot API地址
Clawdbot前端默认读取环境变量API_BASE_URL,但我们已用Nginx做了统一代理,因此前端应直接调用相对路径/api/chat,而非绝对URL。
进入Clawdbot容器修改配置:
# 进入容器 docker exec -it clawdbot sh # 编辑前端配置(路径可能因版本略有不同,优先找 config.js 或 .env) vi /app/dist/config.js # 将 apiBaseUrl: "http://localhost:11434" 改为 apiBaseUrl: "/api" # 退出容器 exit如果找不到配置文件,更稳妥的方式是重新运行容器,通过-e参数注入:
docker stop clawdbot docker rm clawdbot docker run -d \ --name clawdbot \ -p 8080:80 \ -v ~/clawdbot/data:/app/data \ -e API_BASE_URL="/api" \ --restart=always \ ghcr.io/clawdbot/clawdbot:latest5.2 最终验证流程
按顺序执行以下检查,每步成功再进行下一步:
Ollama API直连测试(确认模型服务正常)
curl -X POST http://localhost:11434/api/chat \ -H "Content-Type: application/json" \ -d '{ "model": "qwen3:32b", "messages": [{"role": "user", "content": "你好"}] }'应返回流式JSON,含
message.content字段。Nginx代理Ollama测试(确认代理通路)
curl -X POST https://chat.yourdomain.com/api/chat \ -H "Content-Type: application/json" \ -d '{"model":"qwen3:32b","messages":[{"role":"user","content":"你好"}]}'应返回同上结果,且响应头含
Access-Control-Allow-Origin: *。Clawdbot前端访问
打开浏览器访问https://chat.yourdomain.com,输入问题发送。
页面无报错,控制台Network标签下/api/chat请求状态为200,响应内容为JSON流。跨域验证(关键!)
在浏览器开发者工具Console中执行:fetch('https://chat.yourdomain.com/api/chat', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ model: 'qwen3:32b', messages: [{role: 'user', content: '测试跨域'}] }) }).then(r => r.json()).then(console.log)不报
CORS error,能正常打印响应。
6. 常见问题排查指南
6.1 “502 Bad Gateway”
- 原因:Nginx找不到后端服务(Ollama或Clawdbot未运行,或端口不对)
- 排查:
# 检查Ollama是否监听11434 ss -tuln | grep :11434 # 检查Clawdbot容器是否运行 docker ps | grep clawdbot # 查看Nginx错误日志 sudo tail -f /var/log/nginx/error.log
6.2 “CORS error” 依然存在
- 原因:Nginx配置未生效,或浏览器缓存了旧响应头
- 解决:
- 确认
add_header后有always关键字(否则4xx/5xx时不发送) - 清除浏览器缓存,或用隐身窗口测试
- 检查是否误配了
location /api/chat(应配location /api/)
- 确认
6.3 Qwen3-32B响应极慢或超时
- 原因:模型加载需时间,首次请求可能>30秒;或内存不足触发swap
- 优化:
# 启动Ollama时指定GPU(如有NVIDIA GPU) OLLAMA_NUM_GPU=1 ollama run qwen3:32b # 或限制Ollama内存使用(防止OOM) echo 'OLLAMA_MAX_LOADED_MODELS=1' | sudo tee -a /etc/environment sudo systemctl restart ollama
6.4 Let's Encrypt申请失败
- 常见原因:域名未解析、防火墙拦截80/443端口、Nginx未监听80端口
- 检查:
# 确认80端口开放 sudo ufw status | grep 80 # 检查Nginx是否监听80 sudo ss -tuln | grep :80
7. 总结:从零到上线的关键闭环
你已经完成了私有大模型Web平台最硬核的三步打通:
- 模型层:用Ollama一键加载Qwen3-32B,无需改模型代码;
- 代理层:Nginx同时承担HTTPS卸载、路径路由、CORS注入三重职责,配置清晰可维护;
- 前端层:Clawdbot通过相对路径调用API,彻底解耦部署细节。
这套方案的优势在于零侵入、易维护、可扩展:
- 新增模型?只需
ollama pull,Nginx配置不用动; - 换前端?只要遵循
/api/路径规范,Clawdbot可替换成任何Chat UI; - 上生产?把
Access-Control-Allow-Origin: *换成具体域名,加个Rate Limit模块即可。
接下来,你可以:
- 为Clawdbot添加用户登录(JWT鉴权)
- 接入企业微信/钉钉机器人
- 用Prometheus监控Ollama GPU显存和请求延迟
大模型落地,从来不是比谁模型大,而是比谁链路短、谁故障少、谁迭代快。你现在手里的,就是一个经得起压测、看得清日志、改得了配置的生产级入口。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。