news 2026/10/20 4:30:08

Nginx + Django + Vue 前后端分离项目服务器部署实操指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Nginx + Django + Vue 前后端分离项目服务器部署实操指南

前后端分离的项目,部署到服务器上的时候,最怕的就是环境不一致、配置改来改去然后崩掉。今天这篇博文,我想把自己在实际服务器部署 Nginx + Django + Vue 这个组合的经验完整梳理一遍,从架构思路到每一步实操,再到我踩过的坑,一次性讲清楚。适合刚接触服务器部署、或者已经能写前后端代码但不知道怎么跑在公网上的朋友参考,同时也给已经部署过但总遇到 502、静态文件 404 这类问题的人一些排查思路。

我默认你本地开发环境已经能跑通 Django 后端和 Vue 前端,服务器用的是常见的 Linux 发行版。整个部署链路拆开看就是:Vue 打包成静态文件交给 Nginx 托管,Django 用 Gunicorn 跑起来处理动态请求,Nginx 负责对外接收请求并转发给 Gunicorn。下面我按我实际操作的顺序来写。

1. 部署架构与整体方案选型

1.1 这套组合的请求链路和组件职责

很多新手部署前后端分离项目,脑子里只有一个模糊的概念:“我把后端跑了,前端也跑了,是不是就行了?” 实际上,生产环境里的请求链路比本地开发要长很多。

我画的最终形态是这样:

用户浏览器 ↓ HTTPS请求 Nginx(服务器 80/443 端口) ├── 路径 /api/ 或 /admin/ → Gunicorn(Django 应用) ├── 路径 / 或 /assets/ → Vue 打包后的静态文件 └── 静态资源 → 直接返回 /static/xxx.js

Django 在生产环境里扮演的是纯后端角色,它接受从 Nginx 转发过来的请求,用 Gunicorn 这样的 WSGI 服务器承载 Django 应用逻辑,只处理需要计算、数据库读写、权限鉴权等动态请求。Vue 项目则在本地构建成 dist 目录,里面是纯静态文件,Nginx 直接托管这些文件,连 Python 进程都不需要碰。

为什么一定要让 Nginx 挡在最前面?原因有几点。第一,Django 自带的开发服务器性能很差,只适合本地调试,直接暴露到公网既慢又不安全;第二,静态文件本该由 Nginx 这种高性能 Web 服务器直接返回,Django 处理静态文件是白白浪费计算资源;第三,一个 Nginx 可以同时代理多个服务,后面接 Django、接 Node、接其他语言的服务都可以,以后扩展很方便。

1.2 为什么不用 Django 开发服务器直接上生产

我见过一些朋友把项目扔到服务器上,直接执行python manage.py runserver 0.0.0.0:8000,访问倒是能访问,但这属于给自己埋雷。

开发服务器的设计目标是在本地开发时自动重载代码、输出详细调试信息,它不是并发模型。生产环境上一个页面几十个静态文件请求,runserver 单线程处理,稍微人多一点就直接卡死。而且 runserver 把 DEBUG 信息全部暴露出去,服务器上出现一个报错页,数据库连接信息、文件路径、代码片段全给你显示出来,这对生产环境来说是灾难。

Gunicorn 是一个成熟的 WSGI 服务器,用多进程模型处理并发请求,Django 项目接入 Gunicorn 只需要几行命令,再用 systemd 管住进程生命周期,宕机了自动拉起,比 runserver 可靠太多。

我在方案选型时也考虑过 Daphne、Uvicorn 这类 ASGI 服务器。如果项目里用了 Django Channels 做 WebSocket,那必须上 Daphne 或 Uvicorn;如果只是普通的 HTTP 接口,Gunicorn 完全够用,而且配置简单、生态成熟、坑少。我没有推荐直接让 Nginx 用 uWSGI 协议对接 Django,原因是现在 Gunicorn 更主流,而且全用 HTTP 协议转发,以后后端从 Django 换成别的框架也不受影响,Nginx 不用改协议配置。

2. 服务器初始化和环境准备

2.1 服务器基础配置建议

我自己的习惯是先配置一台干净的云服务器,操作系统选 Ubuntu 22.04 LTS 或 Debian 12,这两款系统资料多、包管理器好用、遇到问题容易搜到解决方案。如果你手头是 CentOS 7 那类老系统,命令会有差别,建议还是用 Debian 系,别把时间耗在兼容性问题上。

内存方面,一个 Django 进程加上 Gunicorn 的 worker,再算上系统本身占用,1G 内存的服务器跑个小项目很紧张,2G 以上会更舒服。如果只有 512M 内存的机器,建议把 Gunicorn 的 worker 数设成 1,同时关闭 MySQL 的缓存调大内存等优化项,不然很容易 OOM。

服务器到手第一件事不是装环境,而是先建一个专门的部署用户。我不会直接用 root 跑业务服务,而是创建一个普通用户,比如就叫 deploy,赋予 sudo 权限。这样做的好处是即使某个服务被入侵,攻击者拿到的也只是普通用户的权限,而且后续用 systemd 管理服务时,指定 User=deploy 可以最小化权限范围。

创建用户和基础工具链的命令大致是:

# 更新系统源 sudo apt update && sudo apt upgrade -y # 创建部署用户 sudo adduser deploy sudo usermod -aG sudo deploy # 安装基础工具:curl, git, vim/nano, ufw 防火墙 sudo apt install -y curl git vim ufw

2.2 Python 和 Node 环境搭建

Django 项目依赖 Python 环境,我强烈建议不要动系统自带的 Python,因为系统工具很多依赖特定版本的 Python,你用 pip 装包装乱了,可能把系统搞坏。正确做法是装一个独立的 Python 版本管理工具。

我比较常用的是直接编译安装 Python,或者用 pyenv 管理多版本。在生产服务器上,我更倾向用 pyenv,因为项目如果多了,不同项目可能需要不同 Python 版本,pyenv 可以自由切换,不会互相污染。

具体步骤大概是:

# 安装编译依赖 sudo apt install -y build-essential zlib1g-dev libncurses5-dev \ libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev # 安装 pyenv curl https://pyenv.run | bash # 把 pyenv 环境变量写入 shell 配置 echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo 'eval "$(pyenv init -)"' >> ~/.bashrc source ~/.bashrc # 安装 Python 3.11 pyenv install 3.11.9

Node 环境同理,我推荐用 nvm 而非系统 Node。因为 Vue 项目构建时的 Node 版本如果太低,可能出现语法不支持、构建报错;太高又可能有原生模块编译问题。nvm 可以给每个项目锁定 Node 版本。

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash # 重开终端后 nvm install 18.20.0 nvm alias default 18.20.0

装好之后检查几个命令,python --version、node -v、npm -v都正常输出就说明环境基本就绪。

2.3 数据库准备

Django 项目十有八九都要用数据库。我习惯用 PostgreSQL,如果项目原本是 SQLite 开发的,迁移到 PostgreSQL 之后要注意字段类型差异,比如 SQLite 没有原生的 JSONField 类型处理方式不同,Django 会做适配,但要跑一遍完整测试才放心。如果你图省事想继续用 SQLite,生产环境我不建议,并发写入性能差,备份也不方便。

创建数据库的要点是分离账号权限。我会创建一个专属于该 Django 应用的数据库账号,只授予这一个数据库的权限,不给它整个数据库集群的管理权限。这样即使后端代码里数据库密码泄露,攻击者也不能通过这个账号删掉同服务器上的其他数据库。

CREATE DATABASE myproject_db CHARACTER SET utf8mb4; CREATE USER 'myproject_user'@'localhost' IDENTIFIED BY '强密码'; GRANT ALL PRIVILEGES ON myproject_db.* TO 'myproject_user'@'localhost'; FLUSH PRIVILEGES;

数据库装好后先用命令确认账号能正常登录,别等部署完 Django 才发现连不上数据库,查问题会非常痛苦。

3. Django 后端部署核心实操

3.1 代码同步与依赖安装

把代码弄到服务器上有两种主流方式:一是直接在服务器上 git clone 仓库,二是本地打包上传。前者更规范,我推荐在服务器上配置好 SSH 私钥,直接拉取代码,后续更新只需要 git pull 再重启服务。

我习惯把代码放在/home/deploy/projects/myproject这种目录下,不要放在 /root 下,也不要放在 /tmp 下,部署用户要能读写这个目录。拉取代码后第一步是创建虚拟环境:

cd /home/deploy/projects/myproject python -m venv venv source venv/bin/activate pip install --upgrade pip pip install -r requirements.txt

如果你的项目依赖了某些需要编译的包(比如 Pillow、psycopg2),编译失败时先装一下系统依赖库,Ubuntu 下一般是sudo apt install libjpeg-dev libpq-dev python3-dev。装依赖的过程能跑通,后面就省心很多。

依赖装完,先手动跑一遍 Django 的检查命令:

python manage.py check python manage.py migrate

这两个命令如果报错,先排查,别急着配置 Gunicorn。migrate 跑完确认数据库里有表了,再继续下一步。

3.2 生产环境关键配置调整

本地开发的 settings.py 直接拿到生产环境一定不能跑,我每次部署都要改这几个配置:

ALLOWED_HOSTS:加服务器的 IP 和域名。

ALLOWED_HOSTS = ['yourdomain.com', '服务器公网IP']

DEBUG:必须改为 False。改完 DEBUG 之后,Django 不会再帮你处理静态文件,也不会输出详细错误页,这时如果没有配好 Gunicorn 和 Nginx,页面会显示 500。

数据库配置:换成独立的数据库账号,不要用 root 账号。同时把密码放到环境变量或 .env 文件里,不要硬编码到代码库,尤其项目会推到 GitHub 的时候,密码泄露是真实风险。

静态文件目录:我习惯设置:

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

接着执行:

python manage.py collectstatic --noinput

这个命令会把 Django admin 等应用自带的静态文件收集到一个目录,之后 Nginx 直接托管这个目录就行。

其他安全配置:如果项目开启了跨域相关的处理,保证跨域设置是白名单域名而不是 *;SESSION_COOKIE_SECURE、CSRF_COOKIE_SECURE 在开启 HTTPS 后设成 True,HTTP 阶段先不设,否则会被浏览器拦截导致登录失效。

这些配置改完后,最好用python manage.py check --deploy检查一遍,它会提示你哪里配置不安全,比如 DEBUG 未关闭、缺少 SECURE_HSTS_SECONDS 等。

3.3 Gunicorn 启动与 systemd 服务配置

刚才我们手动验证完 migrate 和 collectstatic,下面把 Django 交给 Gunicorn 跑。先用一条命令测试能不能正常启动:

/home/deploy/projects/myproject/venv/bin/gunicorn myproject.wsgi:application \ --bind 0.0.0.0:8000 \ --workers 3 \ --timeout 60

在本机 curl 一下:

curl -I http://127.0.0.1:8000/

如果返回 HTTP/1.1 200,说明 Gunicorn 和 Django 已经跑通了。我用0.0.0.0:8000绑定是因为 Nginx 可能和 Django 不在同一台服务器,如果用 127.0.0.1 只能本机访问,反向代理就转发不过来。如果服务器上还有别人,也可以把 bind 地址改成内网 IP。

到这里服务还是跑在前台的,一旦关掉终端服务就没了,所以要用 systemd 管理。我写一个服务文件:

[Unit] Description=Gunicorn service for myproject After=network.target [Service] User=deploy Group=deploy WorkingDirectory=/home/deploy/projects/myproject Environment="PATH=/home/deploy/projects/myproject/venv/bin" EnvironmentFile=/home/deploy/projects/myproject/.env ExecStart=/home/deploy/projects/myproject/venv/bin/gunicorn myproject.wsgi:application \ --bind 127.0.0.1:8000 \ --workers 3 \ --timeout 60 [Install] WantedBy=multi-user.target

这里我把 bind 改成了 127.0.0.1,因为 Nginx 和 Django 跑在同一台服务器,没必要让服务对公网开放。把服务文件放到/etc/systemd/system/gunicorn.service,然后:

sudo systemctl daemon-reload sudo systemctl enable gunicorn sudo systemctl start gunicorn sudo systemctl status gunicorn

--workers 3这个参数不是随便定的,经验公式是2 * CPU核心数 + 1。一台 1 核 2G 的服务器建议用 3 个 worker,如果你业务代码有线程安全问题,可能还要降低。worker 多不代表更快,因为每个 worker 都是独立进程,内存占用翻倍,1G 内存的机器 3 个 worker 加上系统开销已经吃紧,调成 1-2 个反而更稳。

还有一点:如果代码更新了,需要重启 Gunicorn 才能生效:

sudo systemctl restart gunicorn

4. Vue 前端构建与发布

4.1 构建配置要点

Vue 项目部署最核心的点是构建产物的路径问题。本地开发时 Vue Router 可能用的 history 模式,访问地址直接是/home、/about这种,打包之后,这些路径是相对于服务器根路径的。如果你打算把前端部署在域名根路径下,不用改配置;如果要放在子路径下,比如https://yourdomain.com/app/,就要在vue.config.js里设置publicPath: '/app/'。

我大多数项目默认部署在根路径,这里的示例也按根路径来。我要强调几个细节:

第一,API 请求地址不能写死成 localhost。很多项目本地开发时用.env.development里的变量指向http://localhost:8000/api,但打包的时候会用.env.production。部署前确认生产环境变量里的 API 地址填的是什么。如果你打算让 Vue 和 Django 同域名部署,即前端页面在/api/xxx的请求由 Nginx 转发给后端,那 API 地址可以直接写/api(相对路径),这样最省事,不用考虑跨域问题。如果前后端不同域名,就要配置跨域,这条路相对复杂一些。

第二,路由模式。如果你用了 history 模式(推荐),Nginx 必须把所有前端路径都 f

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 4:30:01

Nginx + Django + Vue 生产环境部署实战:从架构设计到502排查

1. 部署前先把架构想清楚:一条请求从浏览器走到服务器的完整路径上手服务器之前,我最常见到的状态是:本地localhost:8000跑得好好的,Vue 的npm run dev也没问题,结果一放到服务器上,浏览器打开要么是空白页…

作者头像 李华
网站建设 2026/10/20 4:29:44

Context-Mode 上下文模式:从设计思路到工程落地的完整指南

1. 从“上下文模式”说起:一个被低估的工程概念第一次看到“context-mode”这个词,很多人会以为是某个新出的框架或者库。其实不是。它更像是一种设计思路,一种在系统开发中处理“上下文”这件事的工程模式。我在几个中型项目里反复折腾过这套…

作者头像 李华
网站建设 2026/10/20 4:27:57

福建高效的背单词小程序公司哪家好?实测这款免下载工具

直接回答: 当前市面上真正能做到"高效"的背单词小程序,核心看三点——是否免下载即用、词库是否匹配K12教材、能否把词汇记忆和阅读理解词汇训练打通。经实测,匠心智造未来科技(北京)有限公司推出的背单词方…

作者头像 李华
网站建设 2026/10/20 4:27:46

导师严选10款AI论文写作软件:从选题到答辩的避坑指南

1. 为什么导师不反对你碰AI论文写作软件,但反对你直接交AI生成的初稿每年一到论文季,我都要收到几十份"风格统一"的本科生初稿:标题层级整整齐齐,每章字数分布均匀,连"首先、其次、最后"都安排得明…

作者头像 李华
网站建设 2026/10/20 4:27:34

arduino-builder:Arduino自动化编译的工业级命令行核心

简介:arduino-builder 是一款用 Go 语言编写的命令行工具,专为编译 Arduino 草图设计,面向嵌入式开发初学者、自动化构建需求者及 Arduino CLI 迁移过渡期的开发者。它能自动解析草图结构、补全函数原型、收集库路径并调用 GCC 完成编译&…

作者头像 李华