最近学习 Python 时接触到了项目部署的问题,之前已经写过一篇使用 Apache 进行部署的笔记,这一篇对更加常用的 uwsgi + Nginx 方案进行部署,同时使用 Fabric 进行服务端的自动更新重载,避免了每次更新代码之后都要手动上传的麻烦。
一. 使用 uwsgi + Nginx 部署 Django 项目
关于 uwsgi 与 Nginx 的安装资料已经很多了,这里不再赘述。这里只讲述在部署项目时的配置。
首先是 uwsgi 的配置文件,uwsgi支持多种类型的配置文件,如xml,ini等,这里我们使用 ini 格式的文件,项目根目录下创建 you_project.ini 文件,然后指定配置。
[uwsgi]
socket=:8010 # 协议类型与端口号
chdir=/home/yourname/project/Shop # 指定的运行目录
module=Shop.wsgi # 指定 wsgi.file, 也就是我们 Django 项目中 的 wsgi.py 文件
master=true # 允许主进程存在
processes=4 # 开启的进程数量
vacuum=true # 当服务器退出的时候自动清理环境,删除 unix socket 文件和 pid 文件
pidfile=/tmp/shop.pid # 指定 pid 文件位置,记录主进程的 pid 号
py-autoreload=1 # 允许代码更新后自动重启 uwsgi
上面就是项目的 uwsgi 配置和一些常用选项的解析,关于更详细的配置说明可以参阅官方文档
接下来就是对 Nginx 的配置文件进行修改,在配置文件中添加如下配置:
server {
listen 8099; #指定 Nginx 代理对外的端口号,也就是我们从浏览器访问时的端口号
server_name 127.0.0.1; # 设置申请的域名,此处没有所以写了 本机地址
charset UTF-8;
client_max_body_size 75M;
location /{
# 配置 uwsgi,注意这里指定的端口号一定要与我们项目的 ini 文件中的端口号一致
include uwsgi_params
uwsgi_pass 127.0.0.1:8010;
uwsgi_read_timeout 2;
}
# 指定静态文件路径
location /static {
expires 30d;
autoindex on;
add_header Cache-Control private;
alias /home/yourname/project/Shop/static/;
}
}
再次强调一下,这里需要特别注意的是 include 必须指定为uwsgi_params,而 uwsgi_pass 指定的本机 IP 端口必须与我们项目的 ini配置文件中的 socket 指定的端口必须一致。 这个配置应该就是 Nginx 可以与 uwsgi 发生关联的原因。至于其关联的具体过程与原理这里先不做过深入的研究。
配置完成后,首先启动 uwsgi 服务,然后在启动 Nginx,就可以通过 Nginx 服务器中配置的对外端口号访问到我们 Django 项目中的 url 了。命令如下:
uwsgi you_project.ini
nginx
二. 编写 Fabric 文件自动化更新代码
当我们部署完项目之后,在后面的开发中,如果修改了代码,如果使用传统的手动上传方式将会非常的麻烦,而且在多人协作时也会造成代码覆盖等很严重的问题,因此这里使用了 Git 进行项目代码管理,同时使用 Fabric 来更新运行环境代码。Fabric 是基于 Python 实现的 SSH 命令行工具,简化了项目的部署和系统管理任务。可以用来实现我们对代码的自动化更新部署操作。
关于自动化更新代码的方案的过程如下:
- 创建 git 代码管理服务器,统一管理项目中的代码
- 在服务端创建运行环境,首次部署时从代码管理服务器中 clone 代码,并按照上面的操作配置服务器文件
- 之后每次代码更新,使用 Fabric 来运行代码更新与静态文件、软件包更新操作
关于 git 服务器的创建这里不作赘述,只对 fabric 的操作文件作简要说明
from fabric.api import env, run, cd
from fabric.operations import sudo
# 设置登录远程主机的用户名和密码
env.user = 'your user'
env.password = 'your password;'
# 填写你自己的主机对应的域名
env.hosts = ['your roots']
# 一般情况下为 22 端口,如果非 22 端口请查看你的主机服务提供商提供的信息
# env.port = '22'
def deploy():
# project_folder = '/home/myname/project/Shop'
# 这里一定要用 with 语句,使后面命令的运行环境处于我们的项目目录下
# 否则会运行在 /root 路径下,会在运行 git 命令时因为找不到 git 仓库而报错
with cd('/home/yingjie/project/Shop'):
# 运行 git pull 从代码管理仓库中拉取最新的代码
run('git pull')
# 执行静态文件和项目需求包的安装
run('python3.5 manage.py migrate')
run('pip3.5 install -r requirements.txt')
run("python3.5 manage.py collectstatic --noinput")
# 这里是当代码更新后自动重启 uwsgi 服务,如果在 ini 文件中
# 配置了 py-autoreload=1 使其代码更新后自动重启的话可以不运行这条命令
# run('uwsgi --reload /tmp/shop.pid')
现在当代码更新后,只需要在本地执行 fab 命令来运行该文件就可以实现运行环境上的代码更新,命令如下:
fab -f project_deploy.py deploy