Django2+uwsgi+nginx部署详解(Ubuntu18.04)

(欢迎访问我的博客: yicheng's site)(目前采用hugo,django是上个版本的反感)

Django项目写好了,最后一步就是部署(deployment)了,部署十分关键,只有部署在服务器上,别人才能从互联网上通过ip地址或域名直接访问到你的网页。

第一步是购买vps(Virtual Private Server 虚拟服务器),这个很简单而且网上教程一大把,这里就不详述,我在vultr购买的海外服务器,这样不用浪费时间去备案了,vultr的一大特色就是按时长收费,如果你的vps出了什么问题,可以随时关停,并且它还支持微信支付宝,价格也很便宜。(vultr官网:https://vultr.com)

Django的本地预览十分方便,一行python manage.py runserver就能搞定,但部署上线可没有这么简单。因为网上关于Django部署的教程都很杂乱,当时部署的时候就踩了很多很多坑,为了给之后一个参考,我又重新部署了一次,来记录详细的过程。

相关软件版本:

Django 2.1.3
Python 3.6.6
nginx 1.14.0
uwsgi 2.0.17.1

服务器:
Ubuntu-server 18.04


准备工作

首先打开ssh软件,Xshell、Putty什么的都行,通过vultr上vps详情页上给的ip和root密码连接到这台vps。

刚拿到的船新Linux,第一步先给它来个更新:

sudo apt-get update
sudo apt-get upgrade

建议使用非root用户,部署时最好使用python虚拟环境,具体操作不是本文的重点,便不赘述了

系统自带Python3.6、vim和git,所以不用装

安装python3-pip、python3-setuptools、gcc、python3-dev、wheel:
(缺一不可,不然之后用pip安装uwsgi会有各种各样的报错)

sudo apt-get install python3-pip python-setuptools python3-dev wheel


放置Django项目

直接在服务器端用vim什么的写Django当然可取(虽然会很酸爽),但更多的时候我们是在本地写好了Django项目,要把它挪到服务器上。

在传输之前,要做一些工作:

先更改一下setting.py里的ALLOWED_HOSTS,把服务器的ip加进去,有域名的话顺便把域名也加进去,要不然之后会无法加载Django项目

在本地的Python虚拟环境上使用pip freeze > requirements.txt,生成一个txt文件,里面是需要的Python库以及其版本,之后一并传给服务器

传输文件到服务器的方法非常之多:可以使用Xshell自带的文件传输,也可以使用linux命令scp或安装更直观的lrzsz,或者使用本地的FileZilla、Winscp等软件,当然万能的git也很不错。

不过考虑到之后这个web项目之后也要修改,用上面的方法感觉都不是特别方便,介绍一个非常好用的方法,那就是使用Pycharm自带的deployment功能,可以实现实时上传以及下载文件,很是方便。

Tools->Deployment->Configuration中配置好与自己服务器的连接,IP地址、用户名、密码以及对应项目路径

image
image

Settings->Project Interpreter里把项目解释器更改为服务器里的Python,mappings里填写两边项目的目录,再加一条manage.py的映射

image

apply之后Pycharm右下角会出现上传进度条,会有点慢,喝杯茶等一段时间即可

传输完毕后会发现本地的项目已经全部上传到服务器了

但这个毕竟不是这篇文章的重点,不重点介绍,遇到了什么问题可以留言或者私信我。

最后别忘了把requirements.txt上传到服务器,用pycharm的话只要直接把文件拖进本地项目目录,Pycharm就会自动帮我们上传到服务器。

在服务器上使用pip install -r requirements.txt来安装必要的Python packages

安装与配置uwsgi

使用pip3安装uwsgi(注意是pip安装,不是apt-get,否则之后会各种报错)

pip3 install uwsgi

下面来试一下uwsgi是否好使:
找个位置新建一个py文件,就叫uwsgi_test.py好了,然后用vim打开

touch uwsgi_test.py
vim uwsgi_test.py

写入以下内容:

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello Uwsgi"]

wq保存退出(vim的基本操作不赘述,网上教程一大把)

然后输入以下命令启动uwsgi,把这个部署到某个端口,以9090端口为例

uwsgi --http :9090 --wsgi-file uwsgi_test.py

这时会出现spawned uWSGI worker 1 (and the only) (pid: 11812, cores: 1)
找个浏览器,访问http://<你的服务器ip>:9090/,不出意外的话你会看到Hello Uwsgi的字样,说明uwsgi能正常运行。

在项目目录下新建uwsgi.ini文件并编辑加入以下内容:

[uwsgi]
# 直接访问uwsgi的端口号,绕过nginx
http = :8010
# 转发给nginx的端口号
socket = 127.0.0.1:8001
# 是否使用主线程
master = true
# 项目的绝对路径
chdir = /var/www/<PROJECT_NAME>/
# Django项目wsgi.py文件的相对路径
wsgi-file = <PROJECT_NAME>/wsgi.py
# 进程数
processes = 4
# 每个进程的线程数
threads = 2
# 监听端口
stats = 127.0.0.1:9191
# 每次退出时是否清理环境配置
vacuum = true
# 目录中一旦有文件被改动就自动重启
touch-reload = /var/www/my_site
# 存放日志
daemonize = /var/www/my_site/uWSGI.log

加入uwsgi.ini的目的是使让uwsgi对接Django项目的启动变得更简便,否则就得在终端敲很长的代码

有了uwsgi.ini我们只需要输入uwsgi --ini uwsgi.ini就可以运行,浏览器输入ip地址加:8010端口(先绕过nginx因为还没配置呢),发现可以显示我们的项目了,这时css等静态文件可能没获取到,别急

安装和配置nginx

sudo apt-get install nginx安装nginx,安装后nginx会自动启动,默认端口为80端口,浏览器输入ip地址加:80,可以看到"Welcome to nginx"的欢迎界面

把/etc/nginx/目录下的uwsgi_params复制到项目目录下,也可以直接项目目录下新建uwsgi_params文件,写入以下内容:

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

前往/etc/nginx/目录,查看nginx.conf(nginx基础配置),发现里面有这么两行,意思就是包含conf.d文件夹中所有以conf后缀的配置和site-enabled文件夹中的内容

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

我们不更改nginx.conf基础配置,只需要修改conf.d目录下的conf文件即可,进入conf.d文件夹,修改default.conf文件,没有的话就新建一个

然后写入以下内容:(务必根据自己的情况做相应更改)

upstream django {
   server 127.0.0.1:8001;
}

server {
    # 监听端口,可改
    listen       80;
    # 修改为你的ip或者域名
    server_name  1.2.3.4;
    # 编码方式
    charset utf-8;

    # 日志记录,可选
    access_log      /var/www/<PROJECT_NAME>/nginx_access.log;
    error_log       /var/www/<PROJECT_NAME>/nginx_error.log;

    # 静态文件所在目录(自行修改)
    location /static {
        alias /var/www/my_site/blog/static;
    }
    # 媒体文件所在目录(自行修改)
    #location /media  {
    #    alias /home/www/djangotest/Hello/media; # 媒体文件所在文件夹
    #}
    location / {
        include /var/www/<PROJECT_NAME>/uwsgi_params;
        uwsgi_pass django;
    }
}

运行service nginx restart

如果报错nginx.service failed because the control process exited with error code,那么运行一下nginx -t -c /etc/nginx/nginx.conf,可以很容易的找到问题在哪。

浏览器输入ip地址,发现看到的还是"Welcome to nginx",这个是因为在nginx.conf中还include了一个sites-enabled/*,它覆盖了我们在default.conf中的配置,可以干脆直接去nginx.conf里把include /etc/nginx/sites-enabled/*;这一行删掉,或者调换两行位置。

这时再访问我们的ip,就能看到自己在本地搭建的Django项目了,因为在配置nginx的时候写入了static的路径,所以css什么的都加载进来了。

至此nginx配置完毕

后续工作

服务器上的Django还没有执行数据库迁移与管理员创建,所以记得执行

python manage.py makemigrations
python manage.py migrate

以及

python manage.py createsuperuser

每次有更新时都要重载uwsgi与nginx才能生效,为了方便uwsgi的重载,在项目目录下新建一个uwsgi文件夹,然后在里面新建两个文件:uwsgi.pid(用于重载停止等操作)和uwsgi.status(用于查看状态)

修改uwsgi.ini,把原先的stats那行删掉,下面加上这两行:

stats=%(chdir)/uwsgi/uwsgi.status
pidfile=%(chdir)/uwsgi/uwsgi.pid

这样如果项目有更新,就可以使用这两个命令来分别重载uwsgi和nginx了

uwsgi --reload uwsgi/uwsgi.pid
systemctl reload nginx.service

至此我们的Django项目就部署完成了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容