IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。


经过 26 篇的扎实开发,我们的电商平台已经具备了完整的功能:用户系统、商品管理、购物车、订单支付、缓存优化、日志追踪……但这一切都还运行在 python manage.py runserver 这个开发服务器上,仅能在本地访问,而且性能极差。今天,我们要让项目正式上线,让外网也能访问我们的电商平台。

我将带大家用 Nginx + uWSGI 这一经典组合来部署 Django 项目。这是 Python Web 部署的标配方案,稳定、高效、久经考验。完成本篇后,你的电商项目就算真正落地了。


一、为什么要用 Nginx + uWSGI?

1.1 Django 开发服务器的局限

python manage.py runserver 是 Django 内置的开发服务器,它的特点:

  • 单线程(或有限的多线程),一次只能处理一个请求;

  • 不处理静态文件(虽然配置了 static() 函数,但效率极低);

  • 没有安全防护,不适合暴露在公网;

  • 官方文档明确警告:不要在生产环境使用 runserver

1.2 uWSGI 和 Nginx 的分工
用户浏览器 → Nginx(反向代理 + 静态文件)→ uWSGI(WSGI 应用服务器)→ Django(业务代码)

一句话总结:uWSGI 负责运行动态 Python 代码,Nginx 负责处理静态资源和转发动态请求,各司其职,高效配合。


二、部署架构概览

┌─────────────────────────────────────────────────┐
│                   Nginx (80/443)                 │
│                                                  │
│  /static/ ───→ 直接返回静态文件                  │
│  /media/  ───→ 直接返回媒体文件                  │
│  /        ───→ 转发到 uWSGI (127.0.0.1:8001)    │
└─────────────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────────────┐
│              uWSGI (多进程)                       │
│  ├─ 进程 1: Django 应用                          │
│  ├─ 进程 2: Django 应用                          │
│  ├─ 进程 3: Django 应用                          │
│  └─ ... (可配置进程数)                           │
└─────────────────────────────────────────────────┘

三、服务器环境准备

3.1 目标环境

假设我们有一台运行 Ubuntu 22.04 LTS 的云服务器(阿里云 ECS、腾讯云 CVM 等),IP 地址为 123.456.789.0,已通过 SSH 登录。

3.2 更新系统并安装基础依赖
sudo apt update
sudo apt upgrade -y
sudo apt install -y python3 python3-venv python3-pip python3-dev build-essential libssl-dev libffi-dev
sudo apt install -y git  # 如果通过 Git 拉取代码

控制台输出:

Get:1 http://archive.ubuntu.com/ubuntu jammy InRelease
...
Setting up python3-venv (3.10.6-1~22.04) ...
Processing triggers for libc-bin (2.35-0ubuntu3.1) ...
3.3 创建项目目录和虚拟环境
# 创建部署目录
sudo mkdir -p /var/www/django_ecommerce
sudo chown $USER:$USER /var/www/django_ecommerce

# 进入目录
cd /var/www/django_ecommerce

# 创建虚拟环境
python3 -m venv venv
source venv/bin/activate
3.4 上传项目代码

通过 Git 或 SCP 将项目代码上传到服务器。假设我们使用 Git:

git clone https://your-repo-url.git .   # 或
# 使用 scp 上传本地项目
# scp -r ./django_ecommerce user@123.456.789.0:/var/www/

如果项目在本地,可以使用 rsync 同步(排除虚拟环境和不必要的文件):

rsync -avz --exclude='venv/' --exclude='.git/' --exclude='__pycache__/' \
    ~/Projects/django_ecommerce/ user@123.456.789.0:/var/www/django_ecommerce/
3.5 安装项目依赖
cd /var/www/django_ecommerce
source venv/bin/activate
pip install -r requirements.txt
pip install uwsgi  # uwsgi 通常单独安装,不在 requirements.txt 中

控制台输出:

Collecting Django==4.2
  Downloading Django-4.2-py3-none-any.whl (8.6 MB)
...
Successfully installed Django-4.2 ...

四、配置生产环境 settings

开发环境和生产环境的配置不同,我们需要将敏感信息和环境相关配置分离。

4.1 创建生产配置文件

django_ecommerce/ 目录下创建 settings_production.py

from .settings import *

# ==================== 安全配置 ====================
DEBUG = False
ALLOWED_HOSTS = ['123.456.789.0', 'www.yourdomain.com', 'yourdomain.com']  # 替换为实际 IP 和域名

# ==================== 静态文件 ====================
# 生产环境下 Nginx 处理静态文件,但 Django 需要配置 STATIC_ROOT
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'

# ==================== 数据库 ====================
# 生产环境建议使用 MySQL 或 PostgreSQL
# 这里先用 SQLite 演示,正式部署请切换
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'prod_db.sqlite3',  # 使用独立的数据库文件
    }
}

# ==================== Redis 配置 ====================
# 服务器上的 Redis 可能需要密码
CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/1'
CACHES['default']['LOCATION'] = 'redis://127.0.0.1:6379/2'

# ==================== 密钥 ====================
SECRET_KEY = '替换为真实密钥'  # 生产环境必须修改,不要用默认的
4.2 收集静态文件

在项目根目录执行:

python manage.py collectstatic --settings=django_ecommerce.settings_production

控制台输出:

You have requested to collect static files at the destination
location as specified in your settings:

    /var/www/django_ecommerce/staticfiles

This will overwrite existing files!
Are you sure you want to do this? (yes/no): yes

128 static files copied to '/var/www/django_ecommerce/staticfiles'.

所有静态文件(Bootstrap、CSS、JS、图片)都被复制到了 staticfiles/ 目录中,供 Nginx 直接访问。


五、安装和配置 uWSGI

5.1 创建 uWSGI 配置文件

在项目根目录创建 uwsgi.ini

[uwsgi]
# 项目目录
chdir = /var/www/django_ecommerce

# Django 的 wsgi 模块
module = django_ecommerce.wsgi:application

# 使用虚拟环境
home = /var/www/django_ecommerce/venv

# 使用生产配置
env = DJANGO_SETTINGS_MODULE=django_ecommerce.settings_production

# socket 文件:通过 Unix socket 与 Nginx 通信(推荐)
socket = /var/www/django_ecommerce/django_ecommerce.sock

# 或者使用 TCP 端口
# socket = 127.0.0.1:8001

# 工作进程数(通常是 CPU 核心数的 2 倍)
processes = 4

# 线程数
threads = 2

# 启用主进程管理
master = true

# 进程 ID 文件
pidfile = /var/www/django_ecommerce/uwsgi.pid

# 日志文件
logto = /var/www/django_ecommerce/logs/uwsgi.log

# 用户权限(Nginx 通常以 www-data 用户运行)
uid = www-data
gid = www-data

# 设置 socket 权限
chmod-socket = 666

# 自动清理 socket 文件
vacuum = true

# 进程最大请求数(防内存泄漏)
max-requests = 5000

# 请求超时时间
harakiri = 30

# 缓冲区大小
buffer-size = 32768
5.2 测试 uWSGI 是否正常工作
# 创建日志目录
mkdir -p /var/www/django_ecommerce/logs

# 启动 uWSGI(前台运行测试)
uwsgi --ini uwsgi.ini

控制台输出:

[uWSGI] getting INI configuration from uwsgi.ini
*** Starting uWSGI 2.0.23 (64bit) on [Wed May 27 10:00:00 2026] ***
compiled with version: 11.4.0 on 26 May 2026 10:30:00
...
spawned uWSGI master process (pid: 12345)
spawned uWSGI worker 1 (pid: 12346, cores: 2)
spawned uWSGI worker 2 (pid: 12347, cores: 2)
spawned uWSGI worker 3 (pid: 12348, cores: 2)
spawned uWSGI worker 4 (pid: 12349, cores: 2)

看到 4 个 worker 进程启动,说明 uWSGI 配置正确。按 Ctrl+C 停止前台运行,我们后面会用 systemdsupervisor 管理。


六、安装和配置 Nginx

6.1 安装 Nginx
sudo apt install -y nginx

安装后 Nginx 自动启动,访问服务器 IP 应该能看到 Nginx 欢迎页面。

6.2 创建 Nginx 站点配置

/etc/nginx/sites-available/ 下创建配置文件 django_ecommerce

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

写入以下配置:

# 80 端口 HTTP 服务
server {
    listen 80;
    server_name 123.456.789.0 yourdomain.com www.yourdomain.com;  # 替换为实际 IP 和域名

    # 日志
    access_log /var/log/nginx/django_ecommerce_access.log;
    error_log /var/log/nginx/django_ecommerce_error.log;

    # 静态文件
    location /static/ {
        alias /var/www/django_ecommerce/staticfiles/;
        expires 30d;  # 静态文件缓存 30 天
    }

    # 媒体文件
    location /media/ {
        alias /var/www/django_ecommerce/media/;
        expires 7d;
    }

    # 动态请求转发到 uWSGI
    location / {
        include uwsgi_params;
        uwsgi_pass unix:///var/www/django_ecommerce/django_ecommerce.sock;
        # 如果使用 TCP 端口:
        # uwsgi_pass 127.0.0.1:8001;
    }

    # 上传文件大小限制
    client_max_body_size 10M;
}
6.3 启用站点
# 创建软链接到 sites-enabled
sudo ln -s /etc/nginx/sites-available/django_ecommerce /etc/nginx/sites-enabled/

# 删除默认站点(可选)
sudo rm /etc/nginx/sites-enabled/default

# 测试配置文件是否正确
sudo nginx -t

控制台输出:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
6.4 重载 Nginx
sudo systemctl reload nginx

控制台输出:

Reloading A high performance web server and a reverse proxy server.

七、使用 systemd 管理 uWSGI

为了让 uWSGI 在后台持续运行,并在服务器重启后自动启动,我们使用 systemd 管理。

7.1 创建 systemd 服务文件
sudo nano /etc/systemd/system/uwsgi_django.service

内容:

[Unit]
Description=uWSGI daemon for Django Ecommerce
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/django_ecommerce
ExecStart=/var/www/django_ecommerce/venv/bin/uwsgi --ini /var/www/django_ecommerce/uwsgi.ini
ExecStop=/var/www/django_ecommerce/venv/bin/uwsgi --stop /var/www/django_ecommerce/uwsgi.pid
Restart=always
RestartSec=5
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
StandardError=syslog
StandardOutput=syslog

[Install]
WantedBy=multi-user.target
7.2 启动 uWSGI 服务
sudo systemctl daemon-reload
sudo systemctl start uwsgi_django
sudo systemctl enable uwsgi_django  # 开机自启

检查服务状态:

sudo systemctl status uwsgi_django

控制台输出:

● uwsgi_django.service - uWSGI daemon for Django Ecommerce
     Loaded: loaded (/etc/systemd/system/uwsgi_django.service; enabled)
     Active: active (running) since Wed 2026-05-27 10:30:00 UTC; 1min ago
   Main PID: 12345 (uwsgi)
      Tasks: 5 (limit: 1137)
     Memory: 120.0M
     CGroup: /system.slice/uwsgi_django.service
             ├─12345 /var/www/django_ecommerce/venv/bin/uwsgi --ini ...
             ├─12346 /var/www/django_ecommerce/venv/bin/uwsgi --ini ...
             ├─12347 /var/www/django_ecommerce/venv/bin/uwsgi --ini ...
             ├─12348 /var/www/django_ecommerce/venv/bin/uwsgi --ini ...
             └─12349 /var/www/django_ecommerce/venv/bin/uwsgi --ini ...

Active: active (running) 表示一切正常。


八、初始化生产数据库

cd /var/www/django_ecommerce
source venv/bin/activate

# 执行迁移
python manage.py migrate --settings=django_ecommerce.settings_production

# 创建超级管理员
python manage.py createsuperuser --settings=django_ecommerce.settings_production

# 初始化商品数据
python manage.py init_product_data --settings=django_ecommerce.settings_production

控制台输出:

Operations to perform:
  Apply all migrations: admin, auth, cart, contenttypes, orders, payment, products, sessions, users
Running migrations:
  Applying contenttypes.0001_initial... OK
  ...
  Applying users.0001_initial... OK
Superuser created successfully.
开始初始化数据...
分类创建完成
SPU 创建完成
SKU 创建完成
初始化完成!

九、启动 Celery Worker(后台运行)

生产环境的 Celery 也需要使用 systemd 管理。

9.1 创建 Celery 服务文件
sudo nano /etc/systemd/system/celery_django.service

内容:

[Unit]
Description=Celery Worker for Django Ecommerce
After=network.target redis-server.service

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/django_ecommerce
Environment="DJANGO_SETTINGS_MODULE=django_ecommerce.settings_production"
ExecStart=/var/www/django_ecommerce/venv/bin/celery -A django_ecommerce worker -l info -Q celery
ExecStop=/bin/kill -s TERM $MAINPID
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

启动:

sudo systemctl daemon-reload
sudo systemctl start celery_django
sudo systemctl enable celery_django

十、测试完整部署

10.1 确认所有服务运行
sudo systemctl status nginx
sudo systemctl status uwsgi_django
sudo systemctl status celery_django
sudo systemctl status redis-server

都应该是 active (running)

10.2 浏览器访问

在浏览器输入服务器 IP 地址 http://123.456.789.0/,你将看到电商平台首页,样式、图片正常加载。

10.3 测试静态文件

访问 http://123.456.789.0/static/css/bootstrap.min.css,应返回 Bootstrap CSS 文件内容。

终端日志(Nginx access log):

sudo tail -f /var/log/nginx/django_ecommerce_access.log

输出:

123.456.789.0 - - [27/May/2026:10:35:20 +0000] "GET / HTTP/1.1" 200 4567
123.456.789.0 - - [27/May/2026:10:35:20 +0000] "GET /static/css/bootstrap.min.css HTTP/1.1" 200 232148
123.456.789.0 - - [27/May/2026:10:35:20 +0000] "GET /static/js/bootstrap.bundle.min.js HTTP/1.1" 200 80245
10.4 测试动态请求

登录、浏览商品、下单、支付(沙箱),功能应与本地开发环境一致。


十一、常见问题与排查

11.1 502 Bad Gateway

原因:Nginx 无法连接到 uWSGI。

排查步骤:

# 检查 uWSGI 是否运行
sudo systemctl status uwsgi_django

# 检查 socket 文件是否存在
ls -la /var/www/django_ecommerce/django_ecommerce.sock

# 查看 uWSGI 日志
tail -f /var/www/django_ecommerce/logs/uwsgi.log
11.2 静态文件 404

原因:Nginx 没有正确配置静态文件路径。

排查步骤:

# 检查静态文件目录是否存在
ls /var/www/django_ecommerce/staticfiles/

# 检查 Nginx 配置中 alias 路径
sudo nginx -t
11.3 503 Service Unavailable

原因:uWSGI worker 崩溃或请求超时。

解决办法:增加 processesharakiri 值,检查 Django 日志是否有异常。


十二、总结与下集预告

今天我们成功将电商项目部署到了生产环境:

  • 理解了 Nginx + uWSGI 的部署架构和各自角色;

  • 准备了 Linux 服务器环境,安装了 Python 虚拟环境;

  • 创建了生产配置文件,收集了静态文件;

  • 编写了 uWSGI 和 Nginx 配置文件,通过 Unix socket 通信;

  • 使用 systemd 管理 uWSGI 和 Celery 进程,实现开机自启和崩溃重启;

  • 完成了生产数据库初始化和功能测试。

现在,世界各地的用户都可以访问你的电商平台了!但还有一个问题:访问地址是 HTTP 明文传输,数据和支付信息不够安全。第 28 篇,我将带大家用 Docker 容器化电商项目,让部署更加标准化、可移植。而 HTTPS 安全证书和域名绑定将在 第 29 篇 详细讲解。

想了解更多也可以任意平台搜索「IT策士」,一起升级 IT 思维 !


本文为《Django 从 0 到 1 打造完整电商平台》系列第 27 篇,作者:IT策士,未经授权禁止转载。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐