阿里云Linux云服务器使用Nginx+uWSGI部署Django项目全攻略

apphuang2026年06月16日 20:40:0311

前言:为什么选择Nginx+uWSGI部署Django

Django框架自带的开发服务器`python manage.py runserver`仅适用于开发和调试阶段,它性能有限、不具备并发处理能力,且存在安全风险。在生产环境中,需要将Django应用部署到专业的应用服务器上,并配合反向代理服务器实现动静分离、负载均衡和高并发处理。

Nginx与uWSGI的组合是目前部署Django项目的主流方案之一。Nginx作为高性能的HTTP服务器和反向代理服务器,负责处理静态资源请求、负载均衡和SSL终止等任务。uWSGI则是一个实现了WSGI协议的应用服务器,作为Nginx与Django应用之间的桥梁,负责运行Python代码并处理动态请求。这种分层架构能够充分发挥各自优势,提升服务的整体性能和稳定性。

本文将以阿里云ECS(Elastic Compute Service)为例,详细讲解从零开始部署Django项目的全过程。无论你是刚接触云部署的新手,还是希望系统梳理部署流程的开发者,本文都能提供可落地的操作指南。

一、整体架构与工作原理

在开始动手之前,先理解整个架构的请求流转过程。

用户通过浏览器访问网站,请求到达服务器后,首先由Nginx接收。Nginx会判断请求类型:如果请求的是静态资源(如CSS样式表、JavaScript脚本、图片等),Nginx直接从服务器本地文件系统中读取并返回,这一过程不经过Django应用,因此响应速度极快。如果请求的是动态内容(如API接口、页面渲染等),Nginx则将请求通过uWSGI协议转发给uWSGI服务器。uWSGI接收到请求后,将其传递给Django应用进行处理——Django执行相应的业务逻辑(如数据库查询、模板渲染等),生成响应数据后返回给uWSGI,再由uWSGI回传给Nginx,最终由Nginx将响应返回给用户浏览器。

这一架构的核心优势在于“动静分离”。Nginx处理静态文件的能力极为出色,而Django只需专注于动态业务逻辑,两者各司其职,互不干扰,大大降低了Django应用的负载,提升了整体并发处理能力。

二、准备工作:创建阿里云ECS实例

2.1 购买ECS实例

需要先登录阿里云控制台,点击:阿里云控制台,进入ECS产品页面购买实例。

实例配置方面,官方推荐至少选择2 vCPU和4 GiB内存的规格。如果项目规模较小或仅用于测试,1核2GB的配置也可运行,但生产环境建议不低于上述推荐配置。操作系统建议选择Alibaba Cloud Linux 3、CentOS 7.x或Ubuntu 20.04/22.04。本文以Alibaba Cloud Linux 3为例进行演示。

网络配置方面,需为实例分配公网IPv4地址。如果实例创建时未分配公网IP,后续也可绑定弹性公网IP(EIP)。安全组方面,建议新建安全组并至少放行以下端口:22(SSH)、80(HTTP)、443(HTTPS,如需启用)、以及uWSGI与Nginx通信所需的端口(本文使用Unix Socket方式,无需额外开放端口)。如果使用TCP端口通信方式,则需放行对应端口。

2.2 安全组配置要点

安全组是阿里云的重要网络安全隔离机制,相当于云服务器的“虚拟防火墙”。在ECS控制台 → 实例 → 安全组 → 配置规则中,可以添加入方向规则。安全建议:22端口的授权对象尽量限制为个人的IP地址范围,避免暴露给全网。80和443端口根据实际需要开放。如果使用了弹性公网IP,还需确保安全组规则与网络ACL配置协调一致。

三、服务器端环境搭建

3.1 连接服务器

使用SSH客户端(如终端、Putty、MobaXterm等)连接ECS实例:

ssh root@你的服务器公网IP

如果使用的是非root用户,请确保该用户具有sudo权限。

3.2 更新系统与安装基础依赖

连接成功后,首先更新系统软件包并安装基础开发工具:

# Alibaba Cloud Linux / CentOS 系统
yum update -y
yum groupinstall -y "Development tools"
yum install -y zlib-devel bzip2-devel pcre-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make

对于Ubuntu系统,使用apt命令:

apt update -y
apt install -y build-essential libssl-dev libffi-dev libbz2-dev libreadline-dev libsqlite3-dev zlib1g-dev

3.3 安装Python环境

Alibaba Cloud Linux 3默认已安装Python 3,可通过以下命令确认版本:

which python3
python3 --version

如果系统未安装Python 3或版本过低,建议从源码编译安装Python 3.10或更高版本:

cd /usr/local/src
wget https://www.python.org/ftp/python/3.10.13/Python-3.10.13.tgz
tar -xzf Python-3.10.13.tgz
cd Python-3.10.13
./configure --enable-optimizations --prefix=/usr/local/python3
make -j $(nproc)
make altinstall

安装完成后,创建软链接以便全局使用:

ln -s /usr/local/python3/bin/python3.10 /usr/bin/python3
ln -s /usr/local/python3/bin/pip3.10 /usr/bin/pip3

3.4 安装Nginx

默认软件源的Nginx版本可能较旧,存在安全风险。建议添加Nginx官方源以安装最新稳定版本:

# 添加Nginx官方源(适用于CentOS/Alibaba Cloud Linux)
sudo tee /etc/yum.repos.d/nginx.repo

Ubuntu系统可直接使用apt安装,或添加官方源后安装。安装完成后启动Nginx并设置开机自启:

sudo systemctl start nginx
sudo systemctl enable nginx

访问服务器公网IP的80端口,如果看到Nginx欢迎页面,说明安装成功。

3.5 安装uWSGI

使用pip安装uWSGI:

pip3 install uwsgi

如果编译过程中出现错误,可能需要先安装Python开发头文件:

yum install -y python3-devel  # CentOS/Alibaba Cloud Linux
apt install -y python3-dev     # Ubuntu

验证uWSGI是否安装成功:

uwsgi --version

四、部署Django项目

4.1 创建项目目录与虚拟环境

良好的项目目录结构有助于后续管理和维护:

sudo mkdir -p /srv/django-app/{logs,static,media}
sudo mkdir -p /run/uwsgi
sudo chown -R $USER:$USER /srv/django-app /run/uwsgi

推荐使用Python虚拟环境来隔离项目依赖,避免不同项目间的包版本冲突。安装virtualenv并创建虚拟环境:

pip3 install virtualenv
cd /srv/django-app
virtualenv venv --python=python3
source venv/bin/activate

进入虚拟环境后,后续的pip安装都将隔离在该环境中。

4.2 创建Django项目(或上传已有项目)

如果是全新项目,可使用django-admin创建示例项目:

django-admin startproject myproject /srv/django-app/

如果已有本地开发完成的Django项目,可通过scp、rsync或Git等方式将项目文件上传至服务器的`/srv/django-app/`目录。上传前建议排除虚拟环境、pyc文件等不必要的文件。

4.3 安装项目依赖

在虚拟环境中安装项目所需的所有依赖包。如果项目根目录下有`requirements.txt`文件:

pip install -r requirements.txt

如果没有,可手动安装Django和uWSGI(uWSGI已在全局安装,但虚拟环境中也建议安装以便统一管理):

pip install django uwsgi

建议使用阿里云PyPI镜像加速下载:

pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple

4.4 配置Django生产环境设置

编辑项目的`settings.py`文件,进行生产环境配置:

vim /srv/django-app/myproject/settings.py

关键配置项如下:

# 关闭调试模式,防止泄露敏感信息
DEBUG = False

# 设置允许访问的主机名或IP,务必包含你的域名或公网IP
ALLOWED_HOSTS = ['你的域名或公网IP']

# 指定静态文件收集目录
STATIC_ROOT = BASE_DIR / 'static'

# 如果使用MySQL/PostgreSQL等生产数据库,替换默认的SQLite配置
# Django默认使用SQLite3,该配置不适用于生产环境
# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.postgresql',
#         'NAME': 'your_db_name',
#         'USER': 'your_db_user',
#         'PASSWORD': 'your_db_password',
#         'HOST': 'localhost',
#         'PORT': '5432',
#     }
# }

需要注意,当`DEBUG = False`时,Django必须配置`ALLOWED_HOSTS`,否则应用将无法启动。这是Django的内置安全机制,用于防范CSRF等攻击。

4.5 收集静态文件与数据库迁移

执行静态文件收集命令,将项目中的静态文件集中到`STATIC_ROOT`目录,供Nginx直接提供服务:

python /srv/django-app/manage.py collectstatic --noinput

执行数据库迁移,初始化数据库表结构:

python /srv/django-app/manage.py migrate

如果项目使用了自定义数据库,请确保数据库服务已安装并运行,且数据库连接信息配置正确。

五、配置uWSGI应用服务器

5.1 创建uWSGI配置文件

在项目目录下创建uWSGI配置文件,例如`uwsgi.ini`:

vim /srv/django-app/uwsgi.ini

以下是一个完整的uWSGI配置示例:

[uwsgi]
# 项目根目录(包含manage.py的目录)
chdir = /srv/django-app

# Django项目的WSGI模块(项目名.wsgi)
module = myproject.wsgi

# 虚拟环境路径
home = /srv/django-app/venv

# 使用Unix Socket与Nginx通信(推荐,性能优于TCP端口)
socket = /run/uwsgi/django.sock

# Socket文件权限
chmod-socket = 666

# 主进程模式
master = true

# 工作进程数量(通常为CPU核心数)
workers = 4

# 每个工作进程的线程数
threads = 2

# 请求上限,防止内存泄漏
max-requests = 5000

# 优雅退出时清理socket文件
vacuum = true

# 后台运行并指定日志文件
daemonize = /srv/django-app/logs/uwsgi.log

# 进程ID文件
pidfile = /srv/django-app/logs/uwsgi.pid

# 设置环境变量
env = DJANGO_SETTINGS_MODULE=myproject.settings

# 缓冲区大小(适用于大请求)
buffer-size = 32768

上述配置中,`chdir`指定项目根目录,`module`指定WSGI模块。如果项目虚拟环境不在默认位置,需通过`home`参数指定。`socket`指定了与Nginx通信的Unix Socket文件路径。

关于`lazy-apps`参数:如果设置为true,uWSGI会在每个工作进程启动后再加载应用程序,这有助于避免一些内存共享问题,但会增加启动时间。根据项目实际情况决定是否启用。

5.2 测试uWSGI是否能正常运行

可以先通过命令行测试uWSGI能否正常启动Django项目:

cd /srv/django-app
source venv/bin/activate
uwsgi --ini uwsgi.ini

查看日志文件确认是否有错误:

tail -f /srv/django-app/logs/uwsgi.log

如果日志中没有报错信息,说明uWSGI配置正确。可以通过`netstat -an | grep .sock`或`ls -la /run/uwsgi/`确认socket文件是否已生成。

六、配置Nginx反向代理

6.1 创建Nginx站点配置文件

Nginx的配置文件通常位于`/etc/nginx/conf.d/`或`/etc/nginx/sites-available/`目录下。在`/etc/nginx/conf.d/`中创建Django项目的配置文件:

vim /etc/nginx/conf.d/django.conf

以下是一个完整的Nginx配置示例:

server {
    listen 80;
    server_name 你的域名或公网IP;

    # 字符集
    charset utf-8;

    # 客户端上传文件大小限制
    client_max_body_size 75M;

    # 日志配置
    access_log /srv/django-app/logs/nginx_access.log;
    error_log /srv/django-app/logs/nginx_error.log;

    # 静态文件路径(由Django的collectstatic收集)
    location /static/ {
        alias /srv/django-app/static/;
        expires 30d;
    }

    # 媒体文件路径(用户上传的文件)
    location /media/ {
        alias /srv/django-app/media/;
        expires 30d;
    }

    # 动态请求转发给uWSGI
    location / {
        include uwsgi_params;
        uwsgi_pass unix:/run/uwsgi/django.sock;
        uwsgi_read_timeout 300;
        uwsgi_send_timeout 300;
        uwsgi_connect_timeout 60;
    }

    # 健康检查路径(可选)
    location /health/ {
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}

关键配置说明:

  • `location /static/`和`location /media/`分别映射Django的静态文件和用户上传的媒体文件,由Nginx直接提供服务。

  • `location /`中的`uwsgi_pass`必须与uWSGI配置文件中的`socket`路径保持一致。

  • `include uwsgi_params`引入Nginx自带的uWSGI参数文件,其中定义了标准的uWSGI协议参数。

  • `server_name`应替换为实际的域名或公网IP。

6.2 测试并重启Nginx

检查Nginx配置文件语法是否正确:

nginx -t

如果显示`Syntax is OK`和`test is successful`,则配置无误。重启Nginx使配置生效:

systemctl restart nginx

七、启动服务与验证

7.1 启动uWSGI

以守护进程方式启动uWSGI(使用`-d`参数或配置文件中已设置`daemonize`):

cd /srv/django-app
source venv/bin/activate
uwsgi --ini uwsgi.ini

查看uWSGI是否正常运行:

ps aux | grep uwsgi

7.2 访问验证

在浏览器中输入服务器的公网IP或已解析的域名,应该能看到Django应用的首页。如果页面无法访问,按以下顺序排查:

  • 检查安全组是否放行了80端口。

  • 检查Nginx和uWSGI服务是否都在运行。

  • 查看Nginx错误日志(`/srv/django-app/logs/nginx_error.log`)和uWSGI日志(`/srv/django-app/logs/uwsgi.log`)。

  • 检查`ALLOWED_HOSTS`是否包含当前访问的域名或IP。

八、进程管理与开机自启

8.1 使用Supervisor管理uWSGI进程

在生产环境中,建议使用进程管理工具(如Supervisor)来管理uWSGI进程,实现自动重启和开机自启。

安装Supervisor:

pip3 install supervisor

生成默认配置文件:

echo_supervisord_conf > /etc/supervisord.conf

在配置文件末尾添加uWSGI的程序配置:

[program:django]
command=/srv/django-app/venv/bin/uwsgi --ini /srv/django-app/uwsgi.ini
directory=/srv/django-app
autostart=true
autorestart=true
stderr_logfile=/srv/django-app/logs/supervisor_err.log
stdout_logfile=/srv/django-app/logs/supervisor_out.log
user=root
stopasgroup=true
killasgroup=true

启动Supervisor:

supervisord -c /etc/supervisord.conf
supervisorctl start django
supervisorctl status

8.2 设置Supervisor开机自启

创建systemd服务文件`/etc/systemd/system/supervisord.service`:

[Unit]
Description=Supervisor process control system
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/supervisord -c /etc/supervisord.conf
ExecStop=/usr/local/bin/supervisorctl shutdown
ExecReload=/usr/local/bin/supervisorctl reload
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

启用开机自启:

systemctl enable supervisord
systemctl start supervisord

九、域名绑定与SSL证书配置

9.1 域名解析

在阿里云控制台的域名解析服务中,添加A记录将域名指向ECS实例的公网IP。解析生效后,即可通过域名访问Django应用。

9.2 申请SSL证书

阿里云提供免费的DV SSL证书。在控制台搜索“SSL证书”,进入证书管理页面,点击“免费证书”进行申请。填写需要绑定的域名,完成域名验证后即可下载证书文件。

9.3 配置Nginx支持HTTPS

将证书文件上传到服务器(如`/etc/nginx/ssl/`目录),修改Nginx配置文件启用HTTPS:

server {
    listen 443 ssl http2;
    server_name 你的域名;

    ssl_certificate /etc/nginx/ssl/your_domain.pem;
    ssl_certificate_key /etc/nginx/ssl/your_domain.key;

    # SSL优化配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # 其余配置与HTTP版本相同
    location /static/ {
        alias /srv/django-app/static/;
    }
    location /media/ {
        alias /srv/django-app/media/;
    }
    location / {
        include uwsgi_params;
        uwsgi_pass unix:/run/uwsgi/django.sock;
    }
}

# HTTP自动跳转HTTPS
server {
    listen 80;
    server_name 你的域名;
    return 301 https://$server_name$request_uri;
}

配置完成后,重启Nginx使HTTPS生效。同时,在Django的`settings.py`中启用安全相关配置:

SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True

十、常见问题排查

10.1 502 Bad Gateway

这是Nginx无法连接uWSGI时最常见的错误。排查步骤:

  • 确认uWSGI服务是否正在运行。

  • 检查uWSGI的socket文件是否存在且权限正确。

  • 检查Nginx配置中的`uwsgi_pass`路径是否与uWSGI配置文件中的`socket`路径一致。

  • 查看uWSGI日志中的具体错误信息。

10.2 静态文件无法加载

如果页面可以访问但样式和图片丢失:

  • 确认是否已执行`collectstatic`命令。

  • 检查Nginx配置中`location /static/`的`alias`路径是否指向`STATIC_ROOT`目录。

  • 检查静态文件目录的读取权限。

10.3 400 Bad Request

这通常是由于`ALLOWED_HOSTS`配置不当引起的。确保`ALLOWED_HOSTS`中包含了当前访问的域名或IP地址。当`DEBUG = False`时,Django对`ALLOWED_HOSTS`的校验非常严格。

10.4 no python application found

uWSGI启动时报“no python application found”错误。可能原因:

  • uWSGI配置中的`module`路径不正确。

  • 虚拟环境未正确激活或`home`路径配置错误。

  • 项目代码存在语法错误,导致应用无法加载。

10.5 Socket文件权限问题

Nginx无法访问uWSGI的socket文件时,会出现连接拒绝错误。确保`chmod-socket`设置为666或Nginx运行用户(通常为www-data或nginx)有读写权限。

10.6 修改代码后不生效

uWSGI默认不会自动重载代码。如需每次修改代码后自动生效,可在uWSGI配置中添加:

py-autoreload = 1

但生产环境不建议开启此功能,应通过重启uWSGI来加载新代码。

十一、性能优化建议

11.1 uWSGI参数调优

  • `workers`:通常设置为CPU核心数的2-4倍,可根据实际负载调整。

  • `threads`:每个工作进程的线程数,建议2-4之间。

  • `max-requests`:设置每个工作进程处理的最大请求数,达到后重启进程,有助于防止内存泄漏。

  • `buffer-size`:如果请求体较大(如文件上传),适当增大此值。

11.2 Nginx优化

  • 启用Gzip压缩:在Nginx配置中添加`gzip on;`和相关指令,减少传输数据量。

  • 配置静态文件缓存:通过`expires`指令设置缓存时间,减少重复请求。

  • 调整`worker_processes`和`worker_connections`以匹配服务器资源。

11.3 数据库优化

  • 生产环境务必使用MySQL、PostgreSQL等专业数据库,而非SQLite。

  • 配置数据库连接池,减少连接开销。

  • 为高频查询字段建立索引。

总结

本文系统介绍了在阿里云Linux云服务器上使用Nginx+uWSGI部署Django项目的完整流程。从架构原理、ECS实例创建、环境搭建、Django配置、uWSGI与Nginx的详细配置,到进程管理、域名SSL、问题排查和性能优化,涵盖了生产环境部署的各个环节。掌握这套部署方案后,开发者可以快速、稳定地将Django应用部署到云端,为用户提供高效可靠的Web服务。

Nginx和uWSGI的组合能够高效处理高并发请求,实现动静分离,是Django生产部署的成熟方案。希望本文能帮助读者顺利完成从开发到生产的跨越。


常见问题问答

问1:为什么要用Nginx+uWSGI部署Django,而不是直接用runserver?
答:Django自带的runserver是单进程开发服务器,不具备并发处理能力,且存在安全风险。Nginx+uWSGI组合能实现动静分离、负载均衡和高并发处理,是生产环境的标准部署方案。

问2:uWSGI使用Unix Socket和TCP端口通信有什么区别?
答:Unix Socket在同一台服务器上性能优于TCP端口,因为它避免了网络协议栈的开销。但如果Nginx和uWSGI部署在不同服务器上,则必须使用TCP端口通信。

问3:部署后访问页面出现502 Bad Gateway错误,如何解决?
答:502错误表示Nginx无法连接到uWSGI。首先检查uWSGI服务是否运行,然后确认socket文件路径在Nginx和uWSGI配置中一致,最后查看uWSGI日志获取详细错误信息。

问4:为什么修改了Django代码后页面没有变化?
答:uWSGI默认不会自动重载代码。修改代码后需要重启uWSGI服务才能生效。如需开发环境自动重载,可在uWSGI配置中添加`py-autoreload = 1`。

问5:静态文件(CSS/JS/图片)无法加载怎么办?
答:首先确认已执行`python manage.py collectstatic`收集静态文件。然后检查Nginx配置中`location /static/`的路径是否指向`STATIC_ROOT`目录。最后确认静态文件目录的读取权限是否正确。

问6:如何为Django项目配置HTTPS?
答:在阿里云申请免费SSL证书,将证书文件上传到服务器,修改Nginx配置文件添加443端口的server块,配置SSL证书路径,并设置HTTP自动跳转HTTPS。同时,在Django的settings.py中启用安全相关配置。

相关文章

阿里云返点返佣简介

阿里云返点返佣简介

我们是做阿里云,腾讯云,华为云,天翼云代理业务,如果你想购买这几朵云,想更加优惠,可以加我们微信;791201210开启云计算成本优化与收益增长的新机遇在当今数字化时代,云计算已经成为企业和个人发展的…

买阿里云服务器能便宜吗?十年代理揭秘 3 大省钱攻略!

买阿里云服务器能便宜吗?十年代理揭秘 3 大省钱攻略!

作为深耕阿里云代理领域 10 年的 “老司机”,经常被问到:“买阿里云服务器能便宜吗?有没有优惠价格?” 今天就用实打实的行业经验告诉你:不仅能便宜,选对渠道还能省一大笔! 这篇文章带你解锁阿里云服务…

做了 10 年腾讯云代理,我想跟你聊聊返佣那些事儿​

做了 10 年腾讯云代理,我想跟你聊聊返佣那些事儿​

最近总有朋友问我:“腾讯云有返点吗?腾讯云服务器能拿佣金不?返佣比例到底有多少?” 作为一个在腾讯云代理行业摸爬滚打了 10 年的 “老人”,今天就来跟大家好好…

阿里云代理商返佣机制深度解析:头部代理优势与企业合作策略

阿里云代理商返佣机制深度解析:头部代理优势与企业合作策略

阿里云代理商的核心价值定位1. 代理商的角色与职责阿里云代理商作为阿里云生态的核心合作伙伴,承担着双重核心职能:• 产品销售:负责推广销售阿里云全系列云产品,包括云服务器ECS、云数据库RDS、对象存…

阿里云代理商返佣机制深度解析:头部代理优势与企业合作策略

阿里云代理商返佣机制深度解析:头部代理优势与企业合作策略

01一、阿里云代理商的核心价值定位1. 代理商的角色与职责阿里云代理商作为阿里云生态的核心合作伙伴,承担着双重核心职能:• 产品销售:负责推广销售阿里云全系列云产品,包括云服务器ECS、云数据库RDS…

阿里云代理商有哪些?阿里云代理返点是真的么?

阿里云代理商有哪些?阿里云代理返点是真的么?

一,阿里云代理商基本介绍阿里云代理商通俗一点,就是指从事阿里云云服务器,云数据库等阿里云公有云产品销售的代理商,每销售一件阿里云公有云产品出去,阿里云给予该代理商一定比例的提成。在阿里云官方定义中,这…