当前位置: 首页 > news >正文

项目web服务器部署流程(supervisor+nginx+django)

Django + Supervisor + Nginx 部署说明

花了一下午一晚上时间在gpt5.4大人的帮助下,好歹把导师给的项目在虚拟机上以web服务器的形式跑起来了,让gpt总结了一下聊天记录,写了一份完整的部署过程,贴在这里做个记录。

以下为AI生成部分

本说明基于一台 Ubuntu 虚拟机,将一个前后端分离项目部署到本地 Web 服务器中。
后端使用 Django,应用服务使用 Gunicorn,进程守护使用 Supervisor,Web 服务与反向代理使用 Nginx。
前端构建完成后由 Nginx 直接提供静态页面访问。

1. 项目结构说明

项目中主要包含以下部分:

  • Django_Vue_Element_Admin/:Django 主配置目录
  • core/:Django 应用
  • manage.py:Django 启动入口
  • ruoyi-ui/:前端源码目录
  • electron-desktop/:前端构建相关目录
  • requirements.txt:Python 依赖
  • db.sqlite3:SQLite 数据库

后端主配置文件位于:

Django_Vue_Element_Admin/settings.py

Django WSGI 入口位于:

Django_Vue_Element_Admin/wsgi.py

2. 服务器环境准备

先更新软件包,并安装部署需要的基础组件:

sudo apt update
sudo apt install -y python3 python3-venv python3-pip nginx supervisor

3. 进入项目目录

假设项目放在:

/home/besti-dhp/photo_filing

进入项目目录:

cd /home/besti-dhp/photo_filing

4. 安装 Python 依赖

安装项目依赖:

pip install -r requirements.txt

安装 Gunicorn:

pip install gunicorn

本项目实际使用的 gunicorn 路径为:

/home/besti-dhp/miniconda3/envs/photo/bin/gunicorn

可通过以下命令确认:

which gunicorn

5. 配置 Django

编辑 Django 配置文件:

nano Django_Vue_Element_Admin/settings.py

关键配置如下:

DEBUG = FalseALLOWED_HOSTS = ['192.168.200.9', '127.0.0.1', 'localhost']STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'

如果仅用于临时测试,也可以先写成:

ALLOWED_HOSTS = ['*']

6. 查看虚拟机 IP 地址

在 Ubuntu 虚拟机中查看 IP:

ip addr

或:

hostname -I

本次部署中虚拟机 IP 为:

192.168.200.9

7. 初始化 Django 项目

执行数据库迁移和静态文件收集:

python manage.py migrate
python manage.py collectstatic --noinput

执行成功后,静态文件会被收集到:

/home/besti-dhp/photo_filing/staticfiles

8. 本地测试 Django 是否可运行

先用 Django 自带开发服务器测试项目本身:

python manage.py runserver 0.0.0.0:8000

此时可在浏览器访问:

http://192.168.200.9:8000

如果根路径返回 404,不一定是失败。
需要检查主路由配置。

本项目的主路由中主要配置了:

  • /admin/
  • /api/
  • /api/ai/

因此访问根路径 / 返回 404 是正常现象。
可以通过访问接口路径验证后端是否正常,例如:

http://192.168.200.9:8000/api/login/

若能看到 Django REST Framework 页面,说明 Django 后端已经正常运行。


9. 使用 Gunicorn 运行 Django

确认 Django 正常后,停止开发服务器:

Ctrl + C

改为使用 Gunicorn 启动:

/home/besti-dhp/miniconda3/envs/photo/bin/gunicorn --bind 127.0.0.1:8000 Django_Vue_Element_Admin.wsgi:application

可通过 curl 测试:

curl http://127.0.0.1:8000/api/login/

如果返回类似:

{"code":401,"msg":"方法 “GET” 不被允许。"}

说明 Gunicorn 已成功将请求转发到 Django,接口正常存在,只是该接口不允许 GET。

测试完成后停止 Gunicorn:

Ctrl + C

10. 配置 Supervisor 守护 Gunicorn

创建 Supervisor 配置文件:

sudo nano /etc/supervisor/conf.d/photo_filing.conf

写入以下内容:

[program:photo_filing]
command=/home/besti-dhp/miniconda3/envs/photo/bin/gunicorn --bind 127.0.0.1:8000 Django_Vue_Element_Admin.wsgi:application
directory=/home/besti-dhp/photo_filing
user=besti-dhp
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/photo_filing.log
environment=PATH="/home/besti-dhp/miniconda3/envs/photo/bin"

加载并启动 Supervisor 配置:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start photo_filing
sudo supervisorctl status

如果看到:

photo_filing RUNNING

说明 Gunicorn 已被 Supervisor 成功托管。


11. 配置 Nginx 代理 Django 后端

先创建 Nginx 配置文件:

sudo nano /etc/nginx/sites-available/photo_filing

先使用后端代理版配置:

server {listen 80;server_name 192.168.200.9;location /static/ {alias /home/besti-dhp/photo_filing/staticfiles/;}location /media/ {alias /home/besti-dhp/photo_filing/upload/;}location / {proxy_pass http://127.0.0.1:8000;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;}
}

启用该站点:

sudo ln -s /etc/nginx/sites-available/photo_filing /etc/nginx/sites-enabled/photo_filing

如果默认站点冲突,可以删除默认链接:

sudo rm -f /etc/nginx/sites-enabled/default

测试配置:

sudo nginx -t

如果测试通过,启动 Nginx:

sudo systemctl restart nginx
sudo systemctl enable nginx

此时访问:

http://192.168.200.9/api/login/

如果能看到接口页面,说明 Nginx 已成功反向代理到 Django。


12. 构建前端项目

本项目不是纯 Django 模板项目,而是前后端分离项目。
因此如果希望访问首页时显示真正的页面,而不是 API 界面,就必须先构建前端。

进入前端目录:

cd /home/besti-dhp/photo_filing/ruoyi-ui

先查看可用脚本:

npm run

本项目实际使用了:

npm run build:desktop

如果 package.json 中脚本原本写成:

"build:desktop": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build --mode desktop"

并导致构建失败,则改为:

"build:desktop": "vue-cli-service build --mode desktop"

然后重新执行:

npm run build:desktop

本次构建完成后,前端产物位于:

/home/besti-dhp/photo_filing/electron-desktop/dist

目录中应能看到:

  • index.html
  • favicon.ico
  • static/

13. 将前端部署到 Nginx 可访问目录

由于 Nginx 运行用户通常无权直接访问 /home/用户名/... 下的前端文件,因此推荐将前端产物复制到 /var/www

创建目录并复制前端文件:

sudo mkdir -p /var/www/photo_filing
sudo cp -r /home/besti-dhp/photo_filing/electron-desktop/dist/* /var/www/photo_filing/
sudo chown -R www-data:www-data /var/www/photo_filing
sudo chmod -R 755 /var/www/photo_filing

14. 配置 Nginx 同时提供前端与后端接口

重新编辑 Nginx 配置文件:

sudo nano /etc/nginx/sites-available/photo_filing

改成如下内容:

server {listen 80;server_name 192.168.200.9;root /var/www/photo_filing;index index.html;location / {try_files $uri $uri/ /index.html;}location /api/ {proxy_pass http://127.0.0.1:8000;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;}location /media/ {alias /home/besti-dhp/photo_filing/upload/;}
}

这里要特别注意:

  • 前端页面由 root /var/www/photo_filing 提供
  • 所有 /api/ 请求继续代理到 Django
  • 不再单独配置 Django 的 /static/,避免和前端构建出来的 /static/... 资源冲突

测试并重启 Nginx:

sudo nginx -t
sudo systemctl restart nginx

15. 验证部署结果

15.1 访问前端页面

浏览器访问:

http://192.168.200.9

如果能打开项目首页,说明前端已成功部署。

15.2 验证后端接口仍可访问

浏览器访问:

http://192.168.200.9/api/login/

如果仍可访问后端接口,说明 Nginx 已成功实现前后端分流:

  • / 提供前端页面
  • /api/ 转发 Django 接口

15.3 验证 Supervisor 状态

sudo supervisorctl status

如果输出:

photo_filing RUNNING

说明后端服务处于正常托管状态。


16. 最终架构

部署完成后的访问链路如下:

浏览器 -> Nginx -> 前端页面
浏览器 -> Nginx -> /api/ -> Gunicorn -> Django
Supervisor -> 守护 Gunicorn 进程

Q&A

Q1:为什么访问 http://IP:8000/ 是 404?

因为 Django 主路由没有配置根路径 /,只配置了 /api//admin//api/ai/ 等路径。
因此访问 / 返回 404 是正常现象,不代表 Django 没跑起来。


Q2:为什么访问 /api/login/ 时显示的是 Django REST Framework 页面?

因为这是后端接口地址,不是前端页面地址。
能看到 DRF 页面说明后端已经正常运行。


Q3:为什么一开始看不到真正的项目界面?

因为项目是前后端分离结构:

  • Django 只负责后端接口
  • 前端页面需要单独构建
  • 构建后由 Nginx 提供静态页面访问

Q4:为什么前端构建时 npm run build 失败?

因为 package.json 中没有定义 build 脚本。
应先通过:

npm run

查看可用脚本,再选择正确的脚本,比如:

npm run build:desktop

Q5:为什么前端构建时报 --openssl-legacy-provider is not allowed in NODE_OPTIONS

因为构建脚本中使用了:

export NODE_OPTIONS=--openssl-legacy-provider

在当前环境下该写法不被允许。
删除这部分后,改为直接执行 vue-cli-service build --mode desktop 即可。


Q6:为什么访问首页时出现 500 Internal Server Error

因为 Nginx 无法读取 /home/用户名/... 下的前端文件,属于权限问题。
解决方法是将前端构建产物复制到 /var/www/...,并赋予 www-data 访问权限。


Q7:为什么前端页面出来了,但 JS/CSS 资源是 403?

因为 Nginx 同时把 /static/ 指向了 Django 的 staticfiles/,而前端打包出来的资源也在 /static/... 路径下,二者冲突。
删除 Django 的 /static/ 映射,改由前端根目录直接提供 /static/ 资源即可。


Q8:为什么手机访问 http://192.168.200.9 不通,但宿主机浏览器能访问?

这是网络可达性问题,不是 Django 或 Nginx 配置错误。
最常见原因是虚拟机处于 NAT 或仅主机模式,导致该 IP 只对宿主机可达,对手机不可达。
如果希望手机也能访问,需要将虚拟机网络改为桥接模式,并确保手机与宿主机处于同一局域网。


Q9:页面打开后控制台里仍有个别接口报错怎么办?

如果页面主体已经正常显示,而个别接口报错,通常是前端中某些接口地址写死成了 127.0.0.1:8000
这类问题属于接口配置或业务逻辑问题,不影响部署链路本身是否成功。


17. 简短结论

本项目已经成功部署在 Ubuntu 虚拟机上,使用:

  • Django 作为后端框架
  • Gunicorn 作为应用服务
  • Supervisor 进行进程守护
  • Nginx 提供 Web 服务与反向代理
  • 前端构建产物由 Nginx 直接提供访问

最终可通过服务器 IP 正常访问项目页面,并通过 /api/ 调用 Django 后端接口。

http://www.jsqmd.com/news/573050/

相关文章:

  • DeepSeek-Coder-V2终极指南:如何免费打造你的专属AI编程助手
  • 资源下载终极解决方案:res-downloader完全指南
  • 保姆级教程:用宝塔面板+Java环境,30分钟搞定ARM网络验证系统(含APK脱壳与加固)
  • RVC新手必看:常见问题解决,快速排除语音转换故障
  • AI原生应用 vs 传统AI应用:核心差异与优势对比
  • Elsevier投稿状态跟踪:科研工作者的终极效率神器
  • Markdown使用技巧
  • 蓝牙连接与通讯机制深度解析:从广播到数据交互
  • 拉普拉斯变换实战:如何用零极点分析设计稳定控制系统?
  • OpenClaw 本地部署全教程:打造专属 AI 执行体
  • 整流器模型预测控制(MPC)仿真:三相三电平NPC型整流器有限集模型预测控制FCS-MPS及电...
  • 26春 日总结14
  • OpenUI深度体验:它真能替代前端吗?我拿它和V0、GPTs Builder做了个横向对比
  • 告别命令行恐惧:给新手的Ubuntu 20.04图形化远程桌面指南(VNC+Remmina保姆级教程)
  • 突破硬件限制:OpenCore Legacy Patcher让老款Mac重获新生
  • QwQ-32B×ollama效果案例:科学假设生成、实验设计推理与结果预测
  • 20252812 2025-2026-2 《网络攻防实践》实践四报告
  • MindIE部署DeepSeek-V3.2-Exp-W8A8后,Function Call不生效?手把手教你修改chat_template和源码
  • Kandinsky-5.0-I2V-Lite-5s Web工具实操:生成历史管理+结果对比+参数回溯功能
  • 罗卡V5系列软启动器配置方法
  • 为什么Inconsolata成为程序员首选字体:从设计哲学到实战配置完整指南
  • 告别刺眼白屏:XTerm终端个性化配色与字体调优实战
  • Open3D点云处理避坑指南:如何高效实现交互式点选与颜色渲染
  • 3步掌握DLSS状态指示器:零门槛实现游戏性能可视化监控
  • 如何用Real-ESRGAN-GUI在3分钟内将模糊图片变高清:终极AI图像修复指南
  • 进阶指南:利用iText7在PDF中打造动态斜纹水印效果
  • 快速部署AI超清画质增强镜像:持久化存储,重启不丢失模型
  • Linux命令diff实战:从基础到高级的文件差异比较技巧
  • macOS下通过Shell脚本自动化重置Navicat试用状态
  • 抖音批量下载器终极指南:免费无水印视频一键获取