ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

宝塔面板部署Django项目:从安装到外网访问完整指南

宝塔面板部署Django项目:从安装到外网访问完整指南 简介面向需要在 CentOS 服务器上快速上线 Django 项目的开发者与运维人员这份教程系统讲解了如何利用宝塔面板完成从环境搭建到站点发布的全流程。内容以实际操作为主线涵盖 Python 项目管理器、Nginx、Git/FTP 代码上传、项目映射、静态文件与媒体资源代理设置等关键环节尤其针对配置过程中易混淆的 uswgi 启动、路径指向和端口设置给出了明确说明。资源包为 1 个 PDF 文档体积仅 139KB但图文步骤完整适合作为部署时的便捷参考手册。目前已有 2371 人学习实用价值获得较多认可。通过该教程读者既能获得可复制的部署流程也能理解宝塔面板下反向代理与静态资源管理的底层逻辑从而减少试错成本更自信地承担生产环境部署与后期维护任务。1. 宝塔部署 Django 项目从装面板到外网能访问总共分几步在 CentOS 上把 Django 项目部署到外网很多人第一反应是去啃 uWSGI 和 Nginx 的配置文档结果折腾一晚上还在跟 502 搏斗。用宝塔面板的 Python 项目管理器这条路会短很多项目创建、依赖安装、Web 服务映射都有面板入口最折腾的静态文件代理也可以在 Nginx 配置文件里直接改。但面板化不等于没有坑我见过最多的问题是路径填错、静态文件 404、改完代码不生效这三类。下面就把我在 CentOS 宝塔环境下部署 Django 的完整步骤写出来参数怎么填、配置改哪里、报错看哪里都会说到适合第一次用宝塔部署 Django 的新手也适合从命令行部署转过来想提高效率的熟手。2. 基础环境准备先把内存、Python 项目管理器、Nginx 三件套装对2.1 装面板前先确认系统类型和内存余量部署第一步不是装软件而是确认服务器本身扛不扛得住。宝塔面板对内存有硬性要求官方提示至少需要 3700MB 内存才能安装这个数字在低配云服务器上非常容易触发。拿到服务器先执行两条命令cat /etc/redhat-release free -h第一条看系统版本确认是不是 CentOS 7 或 8 系列第二条看内存余量。如果内存低于要求安装脚本可能直接拒绝执行或者面板装上了但操作起来特别卡。常见做法是给服务器加 swap 交换分区再重试但我的建议还是部署 Django 至少要 2 核 4G 起步的配置不然项目跑起来后 uWSGI 和 MySQL 抢内存排查起来更费时间。确认系统没问题后去宝塔官网获取对应版本的安装脚本。注意 CentOS 7 和 CentOS 8 的安装命令不同别复制错。安装完成后面板会输出访问地址、账号和初始密码这些信息先存到本地后面每一步都要用到。如果在几个面板之间纠结比如宝塔和 1Panel 哪个好我的看法是单看 Django 部署这个场景宝塔的 Python 项目管理器更直接项目创建、依赖安装、Web 映射都在一个入口里完成比命令行手搓省事得多。2.2 在软件商店里安装 Python 项目管理器和 Nginx登录面板后打开软件商店按顺序安装两样东西Python 项目管理器、Nginx。组件在部署中负责什么宝塔面板服务器管理入口统一管理文件、服务、配置Python 项目管理器创建 Python 虚拟环境、安装依赖、以 uWSGI 方式启动进程、设置开机启动Nginx对外提供 HTTP 服务反向代理到 Django 进程处理静态文件请求先装 Python 项目管理器。这个插件的作用是管理 Python 项目的运行环境Django 项目能不能跑起来很大程度上取决于这个插件的配置细节下一章会重点讲。再装 Nginx它在这里承担两个角色一是对外接收 80 端口的外部请求二是把这些请求反向代理给内部端口上的 Django 进程。静态文件和媒体资源的访问也由 Nginx 直接处理。安装顺序我一般按「Python 项目管理器 → Nginx」来原因很简单先装完项目管理器再去配置项目可以把依赖装好避免后续映射站点时还要回头补环境。装完之后的检查左侧菜单栏出现「Python 项目管理器」入口软件商店里 Nginx 显示已安装且处于运行状态如果 Nginx 启动失败优先检查 80 端口是否被占用netstat -tlnp | grep :80如果 80 端口被其他服务占着需要先停掉占用进程否则后续映射域名时会有冲突。2.3 目录规划和权限检查项目代码放在哪里宝塔有一套默认约定/www/wwwroot/ 是站点根目录。在这个目录下为每个项目单独建一个文件夹避免多个项目文件混在一起。mkdir -p /www/wwwroot/myblog chown -R www:www /www/wwwroot/myblogchown 这一步容易被忽略。面板进程默认以 www 用户运行如果目录属主不对后面创建项目或上传文件时大概率会遇到权限不足的报错。改完属主后再继续下一步。这里建好的目录就是后面「添加项目」时路径参数要指向的位置。目录名建议用项目代号比如 myblog、cms、api别用带空格的目录名Nginx 配置和 uWSGI 命令解析起来容易出问题。3. 上传代码与创建项目Git 与 FTP 两种方式以及添加项目时的参数逐项说3.1 先把 Django 代码弄到服务器上代码上传有两种常见方式。方式一Git Clone。适合代码托管在 Gitee、GitHub 这类平台的场景。先在服务器装 Gityum install -y git cd /www/wwwroot/myblog git clone https://gitee.com/你的用户名/你的项目仓库.git .注意 clone 后面的空格加点表示克隆到当前目录而不是多套一层目录。如果你的仓库是私有的clone 的时候会要求输入账号密码这属于正常情况。方式二宝塔 FTP 上传。适合代码在自己电脑上、没有版本管理托管的场景。打开面板的「文件」菜单进入 /www/wwwroot/myblog 目录把本地项目压缩成 zip 包传上去然后在面板里右键解压。解压后确认目录结构/www/wwwroot/myblog/ ├── manage.py ├── myblog/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── static/ └── media/这个结构里最关键的是两层路径manage.py 所在的那一层是后面「添加项目」时路径参数要填的位置wsgi.py 所在的 myblog 内层目录是启动文件要填的位置。这两层不要搞混否则创建项目后大概率启动失败。我一般建议项目不大就用 zip 上传简单直接项目有持续迭代需求、经常要拉取更新的就配好 Git 方式后续更新只需要 git pull 一条命令。3.2 添加项目Python 项目管理器里的参数逐项说代码就位后打开面板首页的「Python 项目管理器」点击「添加项目」会看到一个表单。这里每一项我都填过把容易出错的地方一并说明。参数填写内容容易踩的坑项目名称自定义建议与目录名一致太随意后续看不出是哪个项目路径manage.py 所在目录填成项目最外层目录会找不到 manage.pyPython 版本与项目 requirements 兼容的版本盲目选新版可能依赖装不上框架Django选错框架生成的启动命令不对启动方式uWSGI生产环境部署 Django 的标准选择启动文件/文件夹wsgi.py 的完整路径填目录而不是文件会启动失败端口1024 之后的未占用端口与 MySQL、Redis 等端口冲突安装模块依赖勾选不勾选就得手动装依赖开机启动勾选不勾选服务器重启后项目不会自启其中几个参数展开说一下。路径填到 manage.py 所在的目录层级。判断方法很简单在面板「文件」里进入该目录能看到 manage.py 和项目配置目录这就是对的层级。Python 版本选择与项目实际使用的版本一致。比如项目在本地用 Python 3.8 开发的某些依赖库在更高版本上有兼容问题就老老实实选 3.8。面板会基于这个版本创建独立的虚拟环境与系统 Python 隔离互不干扰。启动方式选择 uWSGI。这是一个高性能的 WSGI 服务器生产环境部署 Django 的标准选择。Django 自带的 runserver 只能用于本地开发不适合对外提供服务性能和安全都达不到要求。启动文件/文件夹定位到 wsgi.py 文件而不是它的上级目录。wsgi.py 是 Django 项目对外提供 WSGI 入口的文件uWSGI 靠它加载整个应用。这个路径填错了项目启动日志里会直接报找不到模块。端口填一个 1024 以上的端口这个端口是 Django 进程实际监听的端口外部请求会经 Nginx 转发到这里。建议避开 3306、6379、8080 这些常用端口选一个不容易冲突的高位端口。勾选「是否安装模块依赖」后面板会读取项目里的 requirements.txt 并自动安装依赖。如果 requirements.txt 里版本写得很笼统比如只写了 Django面板会装出当前 Python 版本下最新的兼容版本可能和你本地有差异。所以我的习惯是创建项目之前先在本地把 requirements.txt 里的版本号固定好。提示requirements.txt 建议把主版本和次版本锁死比如 Django4.2.7而不是 Django4.0这样面板安装出来的环境和本地一致能少很多「本地能跑线上报错」的问题。全部填完后点确定面板会开始创建虚拟环境、安装依赖、启动项目。这个过程根据依赖数量不同可能需要几分钟。创建期间不要反复点击「添加项目」避免重复创建。3.3 创建完成后先看日志项目创建完成后列表里能看到项目状态。如果状态不是「运行中」点开项目的日志入口看具体报错。最常见的两类错误一是依赖安装失败日志里会有 pip 报错信息。通常是某个包在当前 Python 版本下没有对应版本或者下载超时。解决方案是改用国内 pip 源或者手动改 requirements.txt 里的版本号。二是找不到 wsgi.py日志里会提示模块导入错误。解决方案是回到「编辑项目」里修正启动文件的路径。这个阶段把日志看明白能省掉后面排查的很多时间。另外说明一点宝塔的 Python 项目管理器本质上是把虚拟环境创建、uWSGI 启动这些操作封装成面板按钮日志里暴露出的信息比面板展示的更详细出了问题先看日志不要盲改配置。4. 配置外网访问与静态文件代理映射、location 与路径对位4.1 在 Python 项目管理器里做「映射」项目在服务器内部已经跑起来了但此时外部还访问不到。接下来要做「映射」把域名或外网 IP 绑定到项目上。在 Python 项目管理器的项目列表右侧点击「映射」弹出窗口里填写域名或外网 IP。有条件就填自己的域名比如 www.example.com没有域名就填服务器外网 IP。映射成功后面板会自动在 Nginx 里生成一条反向代理站点配置。这时候打开面板左侧的「网站」菜单能看到刚才映射出的站点记录。直接用浏览器访问域名或 IP会发现页面能打开但 CSS、JS、图片全部加载不出来页面是裸的。这是正常的因为静态文件代理还没配。理解这个过程Nginx 负责接收外网请求并转发给 Django 进程Django 处理完业务逻辑返回页面。但 CSS、JS 这些静态文件不该让 Django 去读而是由 Nginx 直接从磁盘上的 static 目录返回这是效率更高的做法。所以需要在 Nginx 配置里告诉它遇到 /static/ 开头的请求去哪找文件。如果你的服务器在云厂商控制台开了安全组或者启用了系统防火墙还需要放行 80 端口和项目监听端口否则外部请求根本到不了 Nginx 这一层。放行系统防火墙端口的命令是firewall-cmd --permanent --add-port80/tcp firewall-cmd --reloadport 参数可以替换成项目实际监听的端口。安全组规则需要在云厂商控制台操作面板这边无法处理。4.2 在反向代理配置文件里加 location点击「网站」菜单里刚才映射出的站点弹出窗口中选「反向代理 → 配置文件」进入 Nginx 的站点配置文件。在这里面添加静态文件相关的 location 规则。server { listen 80; server_name www.example.com; 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; } location /static/ { alias /www/wwwroot/myblog/static/; } location /media/ { alias /www/wwwroot/myblog/media/; } }上面这份配置是完整示意实际由宝塔映射生成的内容会把 location / 部分配好你只需要把 location /static/ 和 location /media/ 两块加进去然后替换成自己的路径。这里解释一下两个指令的区别proxy_pass 是反向代理把请求转给内部端口的 Django 进程alias 是路径映射把 URL 前缀直接映射到服务器的某个物理目录。静态文件走 alias不需要经过 Django响应速度更快。两个 location 块的含义location /static/凡是以 /static/ 开头的 URL都去 /www/wwwroot/myblog/static/ 目录下找对应文件location /media/用户上传的图片等媒体文件映射到 /www/wwwroot/myblog/media/ 目录alias 后面路径的末尾斜杠建议带着并且保证目录真实存在。如果目录不存在Nginx 会返回 404。路径换成你自己的项目路径即可其他内容不用动。注意Nginx 的 location 匹配是按前缀来的。/static/ 和 /media/ 这两条规则要写在 location / 的外面与它平级不要嵌套进 location / 里面否则匹配不到。4.3 静态文件与媒体资源目录结构和 collectstatic 的关系Django 项目里的静态文件和媒体文件有两个容易混淆的概念。静态文件指 css、js、图片这类随项目一起发布的文件。在 Django 项目标准结构中通常以 static 命名位于 manage.py 同级目录下。开发环境里 Django 会自动处理它们但生产环境 DEBUGFalse 之后需要先收集一次cd /www/wwwroot/myblog python manage.py collectstatic --noinputcollectstatic 会把各 app 里的 static 目录文件统一复制到 settings.py 里 STATIC_ROOT 指定的目录。执行前需要确认 settings.py 里配好了 STATIC_ROOTSTATIC_URL /static/ STATIC_ROOT os.path.join(BASE_DIR, static)这里的 STATIC_ROOT 路径要与 Nginx 里 alias 的路径一致。如果 alias 指向 /www/wwwroot/myblog/static/那 STATIC_ROOT 就是 /www/wwwroot/myblog/static/。路径对不上collectstatic 收集上去的文件 Nginx 就找不到。媒体文件指用户上传的文件比如头像、图片、附件。Django 用 MEDIA_ROOT 和 MEDIA_URL 管理对应 Nginx 里的 /media/ location。配置要点同样是对齐路径。MEDIA_URL /media/ MEDIA_ROOT os.path.join(BASE_DIR, media)路径对位关系是整个部署过程中最容易出错的一环。我在生产环境里遇到过的情况大多是location 配了但 alias 路径比实际项目路径多了一层或少了一层导致静态文件 404。排查方法很简单在面板「文件」菜单里对照 Nginx 配置里的路径看目录是否真实存在目录里是否真的有文件一层层核下去很快能定位。4.4 重启项目与重载 Nginx 的正确顺序配置改完最后一步是让配置生效。回到面板首页进入「Python 项目管理器」对项目点击「重启」然后到「网站」菜单或 Nginx 管理界面里点击「重载配置」。这两步的顺序不要颠倒也不要只做一步。先重启项目让新的代码和依赖生效再重载 Nginx让新的代理配置生效。如果只重载 Nginx 不重启项目代码修改不会生效只重启项目不重载 Nginx静态文件代理配置不会生效。到这里通过域名或 IP 就能正常访问网站了静态文件和媒体资源也能正常加载。5. 部署避坑五个高频报错的现象、原因与解决下面这五个坑是我在 CentOS 宝塔部署 Django 实际过程中遇到过的按「现象 → 原因 → 解决」的格式写出来多数场景可以直接照方抓药。5.1 安装宝塔时报内存不足现象安装脚本执行到一半中断提示内存不满足要求或者在低配服务器上安装成功后面板操作卡顿明显。原因宝塔面板对内存有最低要求官方提示至少需要 3700MB 内存才能安装。1G 或 2G 内存的服务器直接裸装跑不起来。解决先给服务器加 swap 交换分区再重新执行安装脚本。加 swap 的命令是dd if/dev/zero of/swapfile bs1M count2048 mkswap /swapfile swapon /swapfile echo /swapfile swap swap defaults 0 0 /etc/fstabdd 命令创建一个 2G 大小的 swap 文件mkswap 格式化swapon 启用最后一行写入 /etc/fstab 保证重启后仍然生效。但这只是让安装能通过的临时手段如果项目本身比较大建议还是升级内存。我从那以后给团队定了个规矩部署 Django 的机器起步 2 核 4G不给 swap 兜底的机会。5.2 添加项目后启动失败日志提示找不到 manage.py 或 wsgi.py现象项目状态一直显示停止日志里出现 No module named XXX 或者路径不存在的报错。原因添加项目时路径填到了 manage.py 的上一层或者启动文件/文件夹填的是目录而不是 wsgi.py 文件本身。解决在面板「文件」菜单里核对目录结构确认路径层级。manage.py 所在目录就是项目根目录wsgi.py 一般在项目根目录下的同名配置目录里。修正后重新在「编辑项目」里更新路径再重启项目。这个坑出现的频率极高因为很多人会下意识地把仓库克隆下来的最外层目录当成「项目路径」。判断标准只有一个路径下必须直接看到 manage.py。5.3 静态文件全部 404页面只有文字没有样式现象页面能打开但样式全丢浏览器 F12 里 css、js 请求全是 404。原因三个因素任选其一Nginx 配置里没有写 location /static/ 块写了但 alias 路径不对目录不存在或者写完配置没有重载 Nginx。解决先确认静态文件真实存在再去「网站 → 反向代理 → 配置文件」检查 location 块。路径对齐后保存配置在 Nginx 管理界面点击「重载配置」。另外提醒一点开发模式下用 runserver 访问文件路径对的情况下静态文件能直接出来但生产环境下 Django 不再托管静态文件必须由 Nginx 处理这也是「开发好好的上线就 404」的高频原因。5.4 代码改完上传后线上页面没有任何变化现象本地改好代码传到服务器并重启项目后刷新页面还是旧内容。原因改完代码只重启了「项目」没有重载 Nginx。或者项目实际上没有重启成功uWSGI 进程还跑着旧代码。解决严格按照「重启项目 → 重载 Nginx」的顺序执行。重载完成后再刷新页面同时加一个强刷CtrlF5排除浏览器缓存干扰。如果还不生效去项目日志里确认启动时间看进程是否是新起的。代码更新后不生效八成不是配置问题而是流程问题。把这个流程固定下来能省掉大量无效排查。5.5 访问时出现 DisallowedHost 或 502 Bad Gateway现象域名或 IP 打开页面时Django 直接报 DisallowedHost或者 Nginx 返回 502 Bad Gateway。原因DisallowedHost 是 Django 的 ALLOWED_HOSTS 配置里没有包含当前域名或 IP502 是 Nginx 无法连接后端的 Django 进程通常是项目没起来、端口没监听、或者防火墙没放行。解决DisallowedHost 去 settings.py 里把域名加入 ALLOWED_HOSTSALLOWED_HOSTS [www.example.com, 服务器IP]改完这个需要重启项目才会生效。502 则先确认项目状态是不是运行中再确认端口是否被监听netstat -tlnp | grep 8000把 8000 替换成你添加项目时填的端口。如果端口没在监听回到项目日志查启动报错如果端口在监听但仍 502检查 Nginx 的 proxy_pass 端口和项目端口是否一致很多时候是复制配置时改了前面的域名字段忘了改后面的端口号。6. 上线后的验证清单把「好像能跑」变成「确实能用」部署完成不等于万事大吉还有一套验证流程要走。我每次部署完都会按下面三个步骤过一遍第一步验证首页。用 curl 确认 HTTP 状态码正常curl -I http://你的域名或IP看到 200 OK 再继续下一步。如果返回 502 或 403说明后端或权限还有问题先解决再往下走。第二步验证静态资源。在浏览器里打开一个已知存在的 css 文件地址http://你的域名或IP/static/css/style.css能正常显示内容说明 Nginx 的 location 配置生效了。这一步能过滤掉绝大多数路径对位问题。第三步验证媒体文件。登录后台随便上传一张图片再看 /media/ 下对应地址能不能访问。uploads 传不上去或者访问出现 404优先查 MEDIA_ROOT 路径和 Nginx 的 /media/ alias 是否一致。之后我把分布在各处的验证动作收拢成一条固定检查链重启项目 → 重载 Nginx → curl 页面 → curl 静态文件 → 看日志。每次改完代码上线都强制走一遍不做任何跳过。上线之后的维护核心是盯两个日志入口Python 项目管理器里的项目日志看 uWSGI 和 Django 的报错网站菜单里的站点日志看 Nginx 的访问和错误记录。这两处是排查一切线上问题的第一现场比在代码里打 print 然后刷新页面猜错因要高效得多。依赖安装的后悔药也要提前备好修改 requirements.txt 后需要重装依赖时常见做法是在项目管理器里重新执行一次依赖安装或者手动进入对应虚拟环境执行 pip install -r requirements.txt。如果 pip 下载慢把源换成国内镜像能避免大量超时报错。那次项目上线后用户反馈页面样式丢失我排查到半夜最后发现只是改了代码忘了重启项目Nginx 和静态文件配置其实都好好的。从那以后我每次部署改完代码都强制走一遍「重启项目 → 重载 Nginx → curl 验证」这条链再没出过同类问题。希望帮到你。本文还有配套的精品资源点击获取
返回列表