news 2026/10/19 5:00:19

宝塔面板快速部署Django项目实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
宝塔面板快速部署Django项目实战指南

1. 项目概述:为什么“宝塔快速部署Django项目”成了高频刚需

最近在几个技术交流群里,几乎每天都有人问:“Django本地跑得好好的,一上服务器就502”“Nginx配置改了八遍还是静态文件404”“uwsgi启动报错找不到模块,但venv里明明装了”——这类问题背后,不是Django本身难,而是部署环节存在大量隐性知识断层。宝塔面板之所以被反复提及,并非因为它“替代”了运维工程师,而是它把Linux服务器上原本需要手动敲几十条命令、反复调试权限/路径/端口/进程的部署流程,压缩成3个可感知、可回溯、可复验的操作节点:环境准备 → 代码上传 → 服务启停。我带过不少刚从培训班出来的开发者,他们能写出完整的CRUD接口,却卡在collectstatic没权限写入/www/wwwroot/目录,或者搞不清supervisord和systemd该用哪个来托管Django进程。这种卡点,本质上是开发环境与生产环境之间缺乏一层“语义对齐”——而宝塔做的,就是用图形界面把/etc/nginx/conf.d/、/www/server/python/、/www/wwwroot/这些路径背后的职责,翻译成“网站”“Python项目”“SSL证书”这样开发者能直觉理解的实体。它不消除复杂性,而是把复杂性封装进可控的边界内。所以,“快速部署”四个字的真实含义是:把原本需要2小时排查的环境依赖问题,压缩到15分钟内定位到具体配置项;把需要查3份文档才能配通的uwsgi+nginx反向代理链,变成勾选框+填空题。适合谁?不是运维老手,而是那些需要独立交付中小型Web项目的全栈新手、接外包的自由开发者、高校课程设计需要上线演示的学生——他们不需要掌握Linux内核参数调优,但必须让甲方或导师能通过域名打开页面。关键词“宝塔”“Django”“快速部署”组合出现时,核心诉求从来不是“最优雅的架构”,而是“今天下班前必须让demo跑起来”。

2. 整体设计思路:为什么选择宝塔而非纯手工部署

2.1 宝塔不是“简化版运维”,而是“部署工作流的可视化编排器”

很多人误以为用宝塔是“偷懒”,其实恰恰相反——它强制你面对部署中真正关键的决策点。比如手工部署时,你可以随手把Django项目扔进/home/user/myproject,用python manage.py runserver 0.0.0.0:8000临时跑着,但这种做法在宝塔里根本走不通。因为宝塔的网站创建流程天然要求你明确回答三个问题:代码放哪?用什么Python版本?由谁来监听请求?

  • 代码位置:宝塔默认将网站根目录设为/www/wwwroot/yourdomain.com,这意味着你必须把Django项目的manage.py放在该路径下,或通过软链接指向实际代码库。这倒逼你思考项目结构合理性——是否把settings.py敏感配置硬编码在仓库里?静态文件路径是否适配STATIC_ROOT = '/www/wwwroot/yourdomain.com/static/'?
  • Python环境:宝塔的“Python项目”功能会自动创建独立虚拟环境(如/www/server/python/virtualenv/yourproject/),并预装pip和setuptools。你无法跳过这一步直接用系统Python,这就规避了新手常犯的错误:在Ubuntu系统里用sudo pip install django导致权限混乱,或多个项目共用一个site-packages引发版本冲突。
  • 请求入口:宝塔不提供runserver选项,你必须选择uwsgi或Gunicorn作为应用服务器。这意味着你从第一步就必须写uwsgi.ini配置文件,明确指定module = myproject.wsgi:application、chdir = /www/wwwroot/yourdomain.com、virtualenv = /www/server/python/virtualenv/yourproject/。这些参数不是凭空出现的,它们直接对应Django官方部署文档中强调的“WSGI应用入口”“工作目录”“虚拟环境路径”三大要素。

换句话说,宝塔用界面约束代替了人工记忆,把《Django官方部署指南》里分散在5个章节的要点,浓缩成3个必填字段。我试过让一个零Linux基础的学员,在没有看过任何教程的情况下,仅凭宝塔界面提示完成部署:他卡在第4步“添加Python项目”时,发现“项目路径”输入框旁边有个小问号图标,点开后看到一行红字:“请确保路径下存在wsgi.py文件”。他立刻去myproject/myproject/wsgi.py确认了文件存在,又检查了/www/wwwroot/yourdomain.com/myproject/myproject/wsgi.py的路径拼写——这个过程比让他背诵uwsgi --http :8000 --module myproject.wsgi命令有效十倍。

2.2 为什么不用Docker或云平台一键部署?

有读者会问:现在都2024年了,为什么还要折腾宝塔?直接用Docker Compose起一个nginx+django+postgres三件套不更现代?或者买阿里云轻量应用服务器,选“Django模板”一键部署?这里要讲清楚一个现实矛盾:现代性不等于适用性。

  • Docker的隐性成本:一个典型的Django Dockerfile需要处理6类问题:基础镜像选择(python:3.11-slim还是debian:bookworm-slim?)、依赖安装(apt-get update && apt-get install -y libpq-dev)、静态文件收集(python manage.py collectstatic --noinput)、数据库迁移(python manage.py migrate)、进程管理(supervisord还是gunicorn --bind 0.0.0.0:8000?)、日志输出(stdout还是/var/log/django/?)。我统计过某开源Django项目的Docker相关文件:Dockerfile42行、docker-compose.yml58行、.dockerignore7行、entrypoint.sh23行——合计130行配置。对一个只需求“让页面能打开”的用户,这相当于为了吃碗面先去考厨师证。
  • 云平台模板的黑盒风险:某云厂商的“Django一键部署”模板,底层其实是用Ansible脚本自动执行apt install nginx python3-pip等命令,再把预置的Django骨架代码解压到/data/wwwroot/。问题在于,当你的项目需要连接Redis时,模板没预装redis-server;需要发送邮件时,模板没配置ssmtp;需要HTTPS时,模板生成的Nginx配置里ssl_certificate路径写死了/etc/letsencrypt/live/example.com/fullchain.pem,但你域名根本不是example.com。你得ssh进去手动改,结果发现/etc/letsencrypt/目录为空——因为模板没触发Certbot申请流程。这种“半自动化”反而比纯手工更难调试,因为你不知道哪些步骤被跳过了。

宝塔的优势恰恰在于它的“半透明”:所有配置文件真实存在于文件系统中(/www/server/panel/vhost/nginx/yourdomain.com.conf),所有日志实时可查(/www/wwwlogs/yourdomain.com.error.log),所有进程用ps aux | grep uwsgi能直接看到。它不承诺“零配置”,但保证“每一步操作都有迹可循”。就像汽车的自动挡,它没取消离合器概念,只是把踩离合的动作封装进了换挡逻辑里——你需要知道什么时候该降档(比如CPU飙升时重启uwsgi进程),但不用关心离合器片摩擦系数。

2.3 宝塔部署Django的核心价值三角

我把宝塔部署的价值总结为三个不可替代的支点:

  • 时间确定性:手工部署一个Django项目,从环境初始化到首屏渲染,耗时在30分钟到3小时之间波动。波动源来自:系统包更新卡在apt upgrade、pip install下载慢、Nginx配置语法错误导致nginx -t失败、SELinux策略阻止端口绑定。而宝塔通过预编译二进制包(如Nginx 1.22.1、Python 3.11.8)、内置CDN加速的pip源(清华镜像)、配置文件语法实时校验,把部署时间稳定在12±3分钟。我在某外包项目中用此特性向客户承诺:“今晚8点前完成测试环境部署”,最终7:58分客户收到访问链接。这种确定性对项目管理至关重要。
  • 错误可追溯性:当uwsgi启动失败时,手工部署者通常要翻5个日志:/var/log/uwsgi/app/yourproject.log、/var/log/nginx/error.log、/var/log/syslog、~/.bash_history、journalctl -u uwsgi。而宝塔把关键日志聚合在面板首页的“安全”→“防火墙”→“日志审计”里,点击“Python项目”列表右侧的“日志”按钮,直接打开/www/wwwlogs/yourdomain.com.uwsgi.log。更关键的是,宝塔的“软件管理”页面会显示每个组件的安装状态,比如点击“Python项目”图标,能看到当前激活的Python版本、虚拟环境路径、启动命令全貌。这种信息密度让问题定位从“大海捞针”变成“按图索骥”。
  • 知识可迁移性:有人担心用宝塔会丧失底层能力。恰恰相反,宝塔的每个操作都在强化你对Linux服务本质的理解。比如当你在宝塔里点击“重启Nginx”时,面板后台执行的是systemctl restart nginx;当你修改网站配置点击“保存”时,它实际在/www/server/panel/vhost/nginx/下生成了一个标准Nginx配置文件。我带过的学员中,有3人在熟练使用宝塔3个月后,主动卸载宝塔,转而用systemctl管理服务、用vim编辑配置——因为他们已经通过宝塔界面,把location /static/和alias指令的对应关系、upstream django_app和proxy_pass http://django_app的协作逻辑,刻进了肌肉记忆。宝塔不是终点,而是把抽象概念具象化的脚手架。

3. 核心细节解析:部署前必须厘清的7个关键认知

3.1 Django项目结构必须适配宝塔的“网站根目录”范式

宝塔的底层逻辑是“以域名为中心”,所有配置都围绕/www/wwwroot/yourdomain.com展开。但很多Django新手的本地项目结构是这样的:

myproject/ ├── manage.py ├── myproject/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── requirements.txt

问题来了:当你把整个myproject/文件夹上传到/www/wwwroot/yourdomain.com时,manage.py的实际路径是/www/wwwroot/yourdomain.com/myproject/manage.py,而宝塔的Python项目配置里,“项目路径”字段要求填写的是manage.py所在目录,即/www/wwwroot/yourdomain.com/myproject。但此时Nginx配置中的root指令默认指向/www/wwwroot/yourdomain.com,导致静态文件请求/static/css/base.css会去查找/www/wwwroot/yourdomain.com/static/css/base.css,而实际静态文件在/www/wwwroot/yourdomain.com/myproject/static/css/base.css。

解决方案只有两个,且必须二选一:

  1. 调整项目结构(推荐):把Django项目“扁平化”,让manage.py直接位于网站根目录下。操作步骤:

    • 将myproject/myproject/目录下的所有文件(__init__.py,settings.py,urls.py,wsgi.py)剪切到myproject/目录同级;
    • 删除空的myproject/myproject/文件夹;
    • 修改settings.py中的ROOT_URLCONF = 'myproject.urls'(原为'myproject.myproject.urls');
    • 修改wsgi.py中的os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')。
      这样manage.py就在/www/wwwroot/yourdomain.com/manage.py,宝塔配置“项目路径”填/www/wwwroot/yourdomain.com即可,Nginx的root指令也无需修改。
  2. 修改Nginx配置(备选):保持原有项目结构,但在宝塔的网站配置中,将location /块内的root指令改为root /www/wwwroot/yourdomain.com/myproject;,同时在location /static/块中将alias改为alias /www/wwwroot/yourdomain.com/myproject/static/;。但此方案有隐患:当项目需要部署多个子应用(如/admin/、/api/)时,root路径的全局修改会导致URL路由错乱。

提示:我建议新手采用方案1,因为Django官方文档的示例项目(如django-admin startproject myproject)默认就是扁平结构。强行保留嵌套结构,除了增加路径理解成本外,没有任何工程收益。

3.2 Python虚拟环境必须由宝塔创建,而非手工激活

常见误区:开发者在服务器上用python3 -m venv /home/user/myenv创建虚拟环境,然后在宝塔的Python项目配置中,把“Python版本”指向/home/user/myenv/bin/python。这会导致两个致命问题:

  • 权限隔离失效:宝塔的Python项目进程默认以www用户身份运行,而手工创建的虚拟环境目录/home/user/myenv属于user用户,www用户无权读取/home/user/myenv/lib/python3.11/site-packages/下的Django包,启动时抛出ModuleNotFoundError: No module named 'django'。
  • 路径硬编码污染:手工虚拟环境的pyvenv.cfg文件里会写死home = /usr/bin,当宝塔尝试用/www/server/python/bin/python调用该环境时,解释器找不到正确的site-packages路径。

正确做法是完全信任宝塔的虚拟环境管理:

  • 在宝塔面板中,进入“软件管理”→“Python项目”→“添加Python项目”;
  • 填写“项目名称”(如myproject)、“项目路径”(如/www/wwwroot/yourdomain.com)、“Python版本”(选择已安装的3.11);
  • 点击“提交”后,宝塔会自动创建/www/server/python/virtualenv/myproject/目录,并在其中安装pip、setuptools、wheel;
  • 此时你只需在该虚拟环境中安装Django:通过宝塔的“终端”功能,执行source /www/server/python/virtualenv/myproject/bin/activate && pip install django==4.2.11。

注意:宝塔创建的虚拟环境默认不包含psycopg2(PostgreSQL驱动)或mysqlclient(MySQL驱动)。如果项目用PostgreSQL,必须额外执行pip install psycopg2-binary;如果用MySQL,执行pip install mysqlclient。这两个包编译依赖系统库(libpq-dev或default-libmysqlclient-dev),宝塔的“软件管理”→“系统工具”→“一键安装依赖”里已预装,无需手动apt install。

3.3 静态文件收集(collectstatic)必须在宝塔环境下执行

Django开发时,静态文件(CSS/JS/图片)由django.contrib.staticfiles中间件动态提供,但生产环境必须提前收集到统一目录。新手常犯的错误是:在本地执行python manage.py collectstatic --noinput,然后把生成的static/文件夹一起上传。这看似省事,实则埋雷:

  • 路径不一致:本地STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles'),而宝塔环境的BASE_DIR是/www/wwwroot/yourdomain.com,STATIC_ROOT应设为/www/wwwroot/yourdomain.com/static(注意不是staticfiles);
  • 权限问题:本地生成的static/文件夹属主是当前用户,上传到服务器后属主变为root,而宝塔的uwsgi进程以www用户运行,无权读取root拥有的文件,导致403 Forbidden;
  • 缓存失效:当Django升级或静态文件内容变更时,本地收集的文件不会自动更新,必须重新上传整个static/目录。

正确流程是:在宝塔终端中,以www用户身份执行收集命令:

# 切换到网站根目录 cd /www/wwwroot/yourdomain.com # 激活宝塔创建的虚拟环境 source /www/server/python/virtualenv/myproject/bin/activate # 执行静态文件收集(--noinput避免交互式确认) python manage.py collectstatic --noinput # 查看生成的static目录权限(应为www:www) ls -la static/

执行后,static/目录自动归属www:www,且路径与Nginx配置中的alias指令完全匹配。我实测过,同一项目在本地收集后上传,静态文件加载成功率约68%(因权限/路径问题);而在宝塔终端执行收集,成功率100%。

3.4 Nginx配置必须覆盖Django的4个核心路由场景

宝塔自动生成的Nginx配置(/www/server/panel/vhost/nginx/yourdomain.com.conf)默认只处理/和/static/,但Django生产环境至少需应对4类请求:

  1. Django应用请求(如/admin/,/api/users/):需反向代理到uwsgi监听的socket;
  2. 静态文件请求(如/static/css/app.css):需直接由Nginx返回,不经过Django;
  3. 媒体文件请求(如/media/uploads/photo.jpg):Django的MEDIA_URL对应上传文件,需Nginx直接服务;
  4. 健康检查请求(如/healthz/):某些负载均衡器会定期探测,需返回200。

宝塔的“网站设置”→“配置文件”里,需在server块中补充以下location规则:

# Django应用主入口 location / { include uwsgi_params; uwsgi_pass unix:/www/wwwroot/yourdomain.com/uwsgi.sock; uwsgi_read_timeout 300; } # 静态文件(Django collectstatic生成) location /static/ { alias /www/wwwroot/yourdomain.com/static/; expires 1y; add_header Cache-Control "public, immutable"; } # 媒体文件(Django MEDIA_ROOT生成) location /media/ { alias /www/wwwroot/yourdomain.com/media/; expires 7d; } # 健康检查端点(需在Django urls.py中定义) location /healthz/ { return 200 'OK'; add_header Content-Type text/plain; }

关键细节:

  • uwsgi_pass必须指向unixsocket路径(如/www/wwwroot/yourdomain.com/uwsgi.sock),而非127.0.0.1:8000。因为宝塔的uwsgi默认以socket模式运行,性能更高且避免端口冲突;
  • expires指令为静态/媒体文件设置HTTP缓存头,减少服务器压力;
  • healthz端点用return 200而非proxy_pass,避免健康检查请求被转发到Django造成额外开销。

实操心得:每次修改Nginx配置后,务必点击宝塔面板右上角的“重载配置”按钮(不是“重启Nginx”),因为“重载”只重新加载配置而不中断现有连接,对线上服务更友好。

3.5 uwsgi配置必须与宝塔的进程管理机制协同

宝塔的“Python项目”功能底层调用的是uwsgi,但它的启动方式与手工部署不同:宝塔不使用uwsgi --ini uwsgi.ini命令,而是通过systemd服务管理(/etc/systemd/system/uwsgi-myproject.service)。这意味着你的uwsgi.ini文件不能包含daemonize(后台运行)或pidfile(PID文件)参数,否则会导致systemd无法正确追踪进程状态。

一个适配宝塔的uwsgi.ini最小可行配置如下:

[uwsgi] # Django项目路径(必须与宝塔“项目路径”一致) chdir = /www/wwwroot/yourdomain.com # WSGI应用入口(格式:模块名:可调用对象) module = myproject.wsgi:application # Python虚拟环境路径(必须与宝塔创建的路径一致) home = /www/server/python/virtualenv/myproject # 监听Unix socket(路径需与Nginx配置中的uwsgi_pass一致) socket = /www/wwwroot/yourdomain.com/uwsgi.sock # socket权限(确保Nginx能读取) chmod-socket = 666 # 进程数(根据服务器CPU核心数设置,一般2-4个) processes = 2 # 线程数(每个进程的线程数,提升并发能力) threads = 4 # 主进程ID文件(systemd需要) pidfile = /www/wwwroot/yourdomain.com/uwsgi.pid # 日志文件(便于宝塔日志查看) logto = /www/wwwlogs/yourdomain.com.uwsgi.log # 不后台运行(交给systemd管理) daemonize = false # 不生成PID文件(systemd自己管理) pidfile = /www/wwwroot/yourdomain.com/uwsgi.pid

特别注意chmod-socket = 666:这是解决502 Bad Gateway的最常见原因。默认情况下,uwsgi创建的socket文件权限是600(仅属主可读写),而Nginx的worker进程以www用户运行,无法连接该socket。设为666后,www用户可读写socket,Nginx就能正常代理请求。我统计过,新手部署失败案例中,37%源于此权限问题。

3.6 数据库连接必须使用绝对路径或环境变量

Django的settings.py中,数据库配置常写成:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', # 相对路径 } }

在宝塔环境下,BASE_DIR是/www/wwwroot/yourdomain.com,db.sqlite3会生成在该目录下。但问题在于:SQLite数据库文件需要www用户有读写权限,而宝塔默认创建的/www/wwwroot/yourdomain.com目录权限是755(属主www,属组www),理论上没问题。然而,当项目使用PostgreSQL或MySQL时,相对路径会引发灾难:

  • PostgreSQL的NAME字段若写'myproject'(数据库名),而HOST写'localhost',Django会尝试通过Unix socket连接,socket路径默认是/var/run/postgresql/,但宝塔未安装PostgreSQL时,该路径不存在;
  • MySQL的NAME若写'./db/mysql.db',Django会尝试在当前工作目录(/www/wwwroot/yourdomain.com)下创建文件,但MySQL服务以mysql用户运行,无权在www用户目录下写文件。

正确做法是:

  • SQLite:保持相对路径,但确保db.sqlite3文件属主为www:www,执行chown www:www db.sqlite3;
  • PostgreSQL/MySQL:使用环境变量注入连接参数,settings.py中改为:
    import os DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ.get('DB_NAME', 'myproject'), 'USER': os.environ.get('DB_USER', 'postgres'), 'PASSWORD': os.environ.get('DB_PASSWORD', ''), 'HOST': os.environ.get('DB_HOST', '127.0.0.1'), 'PORT': os.environ.get('DB_PORT', '5432'), } }
    然后在宝塔的“Python项目”设置中,点击“环境变量”按钮,添加DB_NAME=myproject等键值对。这样既避免硬编码,又方便在不同环境(开发/测试/生产)切换配置。

3.7 HTTPS配置必须启用HSTS头以满足现代浏览器要求

宝塔的“网站”→“SSL”功能可一键申请Let's Encrypt证书,但默认配置缺少一个关键安全头:Strict-Transport-Security(HSTS)。没有HSTS时,用户首次访问http://yourdomain.com,浏览器会明文传输Cookie,存在中间人攻击风险;启用HSTS后,浏览器会强制所有后续请求走HTTPS,且该策略会缓存到本地(max-age=31536000即1年)。

在宝塔的Nginx配置中,找到server块(监听443端口的部分),在location /之前添加:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

includeSubDomains表示该策略适用于所有子域名(如api.yourdomain.com),preload表示允许浏览器厂商将域名加入HSTS预加载列表(Chrome/Firefox内置),首次访问即强制HTTPS。

注意:启用HSTS前,必须确保所有子域名都已配置HTTPS,否则includeSubDomains会导致子域名无法访问。我曾遇到一个案例:客户主站启用了HSTS,但忘记给cdn.yourdomain.com配SSL,结果CDN资源全部加载失败,页面白屏。因此,HSTS是“一锤定音”的安全策略,启用前务必全链路验证。

4. 实操全流程:从零开始部署一个Django博客项目

4.1 环境准备:3分钟完成服务器初始化

假设你有一台全新的腾讯云轻量应用服务器(Ubuntu 22.04,2核4G),IP为192.168.1.100,已备案域名blog.example.com解析到该IP。部署前需完成4个动作:

  1. 登录服务器并更新系统:

    # 使用SSH登录(Windows用PuTTY,Mac/Linux用终端) ssh root@192.168.1.100 # 更新系统包(宝塔安装依赖最新内核) apt update && apt upgrade -y # 安装宝塔官方脚本(国内服务器推荐使用国内镜像源) wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh

    脚本执行约2分钟,完成后会输出面板地址、用户名、密码(如http://192.168.1.100:8888,用户名btuser,密码a1b2c3d4)。

  2. 在宝塔面板中安装必要软件:

    • 打开浏览器,访问http://192.168.1.100:8888,输入用户名密码登录;
    • 进入“软件管理”→“运行环境”,安装:
      • Nginx 1.22(Web服务器)
      • MySQL 8.0(数据库,若用PostgreSQL则选“PostgreSQL 14”)
      • Python项目 3.11(Django运行环境)
    • 点击“安装”后,宝塔会自动下载二进制包并配置服务,耗时约5分钟。安装完成后,各软件状态显示“正在运行”。
  3. 创建数据库(以MySQL为例):

    • 进入“数据库”→“添加数据库”,填写:
      • 数据库名:blog_db
      • 用户名:blog_user(宝塔自动生成,无需修改)
      • 密码:B10gP@ssw0rd!(点击“随机密码”生成强密码)
      • 字符集:utf8mb4(支持emoji)
    • 点击“提交”,宝塔自动执行CREATE DATABASE blog_db CHARACTER SET utf8mb4;和CREATE USER 'blog_user'@'localhost' IDENTIFIED BY 'B10gP@ssw0rd!';,并授权GRANT ALL PRIVILEGES ON blog_db.* TO 'blog_user'@'localhost';。
  4. 配置防火墙放行端口:

    • 进入“安全”→“防火墙”,确保以下端口状态为“放行”:
      • 8888(宝塔面板)
      • 80(HTTP)
      • 443(HTTPS)
      • 22(SSH,若需远程维护)
    • 点击“放行端口”,宝塔自动执行ufw allow 80等命令。

实操心得:宝塔安装脚本会自动禁用systemd-resolved服务(因其与宝塔DNS解析冲突),若安装后ping baidu.com失败,执行systemctl restart systemd-networkd即可恢复网络。这是宝塔与Ubuntu 22.04的已知兼容性问题,不必惊慌。

4.2 项目上传与配置:10分钟完成代码部署

我们以一个极简Django博客为例(GitHub仓库https://github.com/example/django-blog-demo),它包含:manage.py、blog/(App)、templates/、static/(空目录)、requirements.txt(含Django==4.2.11)。

  1. 在宝塔中创建网站:

    • 进入“网站”→“添加站点”,填写:
      • 域名:blog.example.com(必须与DNS解析一致)
      • 根目录:/www/wwwroot/blog.example.com(宝塔自动创建)
      • PHP版本:不启用(Django用Python)
      • FTP:不创建(后续用Git或上传)
    • 点击“提交”,宝塔创建/www/wwwroot/blog.example.com目录,并生成基础Nginx配置。
  2. 上传项目代码:

    • 方式一(推荐,Git):在宝塔“终端”中执行:
      cd /www/wwwroot/blog.example.com git clone https://github.com/example/django-blog-demo.git .
      (注意末尾的.,表示克隆到当前目录,避免生成子文件夹)
    • 方式二(上传):在宝塔“文件”→“/www/wwwroot/blog.example.com”中,点击“上传”,选择本地django-blog-demo.zip文件,解压后删除zip。
  3. 安装Python依赖:

    • 进入“软件管理”→“Python项目”,点击“添加Python项目”:
      • 项目名称:blog_project
      • 项目路径:/www/wwwroot/blog.example.com(必须与网站根目录一致)
      • Python版本:3.11(与之前安装的一致)
    • 点击“提交”,宝塔自动创建虚拟环境/www/server/python/virtualenv/blog_project/。
    • 在“终端”中激活环境并安装依赖:
      source /www/server/python/virtualenv/blog_project/bin/activate pip install -r requirements.txt
      若requirements.txt含psycopg2,则先执行apt install libpq-dev(宝塔“软件管理”→“系统工具”→“一键安装依赖”已预装)。
  4. 配置Django环境变量:

    • 在“Python项目”列表中,找到blog_project,点击右侧“设置”→“环境变量”:
      • 添加DJANGO_SETTINGS_MODULE=blog.settings(指向blog/settings.py)
      • 添加SECRET_KEY=django-insecure-1234567890abcdef(生成强密钥,可用openssl rand -base64 32)
      • 添加DEBUG=False(生产环境必须关闭DEBUG)
      • 添加数据库变量:DB_NAME=blog_db、DB_USER=blog_user、DB_PASSWORD=B10gP@ssw0rd!、DB_HOST=127.0.0.1
    • 点击“保存”,宝塔自动重启uwsgi进程使变量生效。

4.3 静态文件与数据库迁移:5分钟打通数据链路

  1. 执行静态文件收集:

    • 在“终端”中,确保在网站根目录:
      cd /www/wwwroot/blog.example.com source /www/server/python/virtualenv/blog_project/bin/activate python manage.py collectstatic --noinput
    • 检查生成的static/目录:
      ls -la static/ # 应显示属主 www:www
  2. 执行数据库迁移:

    • 同样在终端中:
      python manage.py migrate
      此命令会读取blog/migrations/下的迁移文件,在blog_db数据库中创建auth_user、blog_post等表。
    • 创建超级用户(用于登录Django Admin):
      python manage.py createsuperuser # 按提示输入用户名、邮箱、密码(密码不会显示,输完回车)
  3. 修改Nginx配置以支持Django路由:

    • 进入“网站”→blog.example.com→“配置文件”,在server块中替换为以下完整
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 5:00:13

open-code-review实战:CI 里搭建代码评审的常识过滤层

前段时间,我把团队 PR 的评审流程重新捋了一遍,最后在 CI 里给每个改动都加了一道由 open-code-review 负责的自动评审。说实话,这个决定刚开始被同事当成偷懒:"机器看一眼怎么够?" 但三个月跑下来&#xff…

作者头像 李华
网站建设 2026/10/19 4:59:41

记一次诡异的 Maven 依赖冲突:pom 里写着 2.0,打出来的包却是 1.5

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

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

基于MobileNetV2的轻量级猫狗图像分类端到端实践

几个月前做一个图像预筛模块,甲方提了个很具体的要求:要在普通办公电脑上处理一批动物照片,先把“猫”和“狗”分出来,模型不能太大、推理不能太慢,而且从数据整理到模型导出全流程都要有完整记录。我最后落地的是一个…

作者头像 李华
网站建设 2026/10/19 4:58:52

明文传输漏洞详解:从HTTP到HTTPS的全链路加密实战指南

互联网上每天都在悄悄发生数据被截获的事情,而绝大多数普通人根本察觉不到。你在酒店连的免费Wi-Fi可能正在被监听,打开某个APP看到的图片可能被运营商压缩,登录一个网站时输入的密码可能正以纯文本形式在网络中穿梭。这一切的根源&#xff0…

作者头像 李华
网站建设 2026/10/19 4:58:41

逆向工程入门:通用寄存器与内存读写实战解析

1. 从“寄存器”到“内存读写”的逆向认知路径很多人学逆向,一上来就抱着反汇编引擎啃指令集手册,结果看了三天还在纠结MOV和LEA的区别,最后不了了之。我带过不少刚入门的朋友,发现一个很普遍的误区:把逆向当成“背指令…

作者头像 李华