资讯动态

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

发布时间:2026/10/20 4:30:15 来源:尧图企业网站定制
前后端分离的项目部署到服务器上的时候最怕的就是环境不一致、配置改来改去然后崩掉。今天这篇博文我想把自己在实际服务器部署 Nginx Django Vue 这个组合的经验完整梳理一遍从架构思路到每一步实操再到我踩过的坑一次性讲清楚。适合刚接触服务器部署、或者已经能写前后端代码但不知道怎么跑在公网上的朋友参考同时也给已经部署过但总遇到 502、静态文件 404 这类问题的人一些排查思路。我默认你本地开发环境已经能跑通 Django 后端和 Vue 前端服务器用的是常见的 Linux 发行版。整个部署链路拆开看就是Vue 打包成静态文件交给 Nginx 托管Django 用 Gunicorn 跑起来处理动态请求Nginx 负责对外接收请求并转发给 Gunicorn。下面我按我实际操作的顺序来写。1. 部署架构与整体方案选型1.1 这套组合的请求链路和组件职责很多新手部署前后端分离项目脑子里只有一个模糊的概念“我把后端跑了前端也跑了是不是就行了” 实际上生产环境里的请求链路比本地开发要长很多。我画的最终形态是这样用户浏览器 ↓ HTTPS请求 Nginx服务器 80/443 端口 ├── 路径 /api/ 或 /admin/ → GunicornDjango 应用 ├── 路径 / 或 /assets/ → Vue 打包后的静态文件 └── 静态资源 → 直接返回 /static/xxx.jsDjango 在生产环境里扮演的是纯后端角色它接受从 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 管理服务时指定 Userdeploy 可以最小化权限范围。创建用户和基础工具链的命令大致是# 更新系统源 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 ufw2.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.9Node 环境同理我推荐用 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_userlocalhost IDENTIFIED BY 强密码; GRANT ALL PRIVILEGES ON myproject_db.* TO myproject_userlocalhost; 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 后设成 TrueHTTP 阶段先不设否则会被浏览器拦截导致登录失效。这些配置改完后最好用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] DescriptionGunicorn service for myproject Afternetwork.target [Service] Userdeploy Groupdeploy WorkingDirectory/home/deploy/projects/myproject EnvironmentPATH/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] WantedBymulti-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 gunicorn4. 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

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑