Django部署的正确打开方式 v2.0

2017年12月4日教程更新,请移步至最终版本:Django快速部署简约版 v3.0

以下部分仅作为参考。


2017-05-17网站重写-博客地址:http://nocmt.com
更换环境为:Python 3.6.1 + Django 1.11.1 + MySQL 5.7.18

一周前试用了一下腾讯云的服务器,默认创建的账号不是管理员,导致上传文件失败,升级权限后却远程连接服务器都不行了,而且网速比乌龟的速度都慢,所谓的1m也只是玩笑,所以放弃使用!还是大阿里云好!这次部署的环境依旧是阿里云的Ubuntu 16.04 ,废话不多说,教程开始!

2018-04-03:发现还是有人收藏本文,所以我就修正一些错误,写的不够清楚的地方,建议看第三版教程。


1. 环境准备

1.1 更新系统:

sudo apt-get update
sudo apt-get upgrade

提示:安装时出现的选择项按自己实际情况选择。

1.2 安装SSH:

apt-get install ssh

提示:本人的项目是通过FileZilla Client直接上传的,其实Pycharm也可以直接上传项目。
有兴趣的可以看看教程:FTP使用教程之Filezilla使用教程

1.3 配置默认的Python环境:

提示:一般默认自带python2.7+3.5,我们使用的环境是python3.6.1

1.3.1 安装python-dev包:
apt-get install python-dev
1.3.2 安装或升级pip :

安装:

apt-get install python-pip

升级:

pip install --upgrade pip
1.3.3 更换pip源:

提示:因为国内使用默认的pip源速度很慢,所以需要更换,在用户根目录下新建 .pip 目录,在该目录下新建pip.conf文件。

mkdir ~/.pip
vi ~/.pip/pip.conf

填入:

[global]
index-url = http://mirrors.aliyun.com/pypi/simple/

[install]
trusted-host=mirrors.aliyun.com

[list]
format=columns

2. 数据库安装

2.1 安装MySQL:

apt-get install mysql-server

提示:安装过程中会提示让你设置MySQL密码 ,输入两次密码,回车即可,然后等待安装完成,见下图。

设置MySQL密码

提示:查看MySQL版本命令:

mysql --version

2.2 运行数据库Mysql安全配置向导:

  mysql_secure_installation

选择说明:

  • Enter password for user root:输入root用户密码并回车。
  • VALIDATE PASSWORD......Press y|Y for Yes, any other key for No:是否设置验证密码,直接回车选择不。
  • Change the password for root? :是否更改root用户的密码?由于之前设置过,所以这里不更改,直接回车选择不。
  • Remove anonymous users?:是否删除匿名用户?输入y并回车。
  • Disallow root login remotely?: 是否禁止root登录远程?输入y并回车。
  • Remove test database and access to it?: 删除测试数据库并访问它?输入y并回车。
  • Reload privilege tables now?:现在重新加载权限表?输入y并回车。

如果出现这种错误:

[error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)']

它表明你的Mysql服务,并没有开启!输入下列命令开启即可:

service mysql start 

sudo表明以管理员权限执行:如何启动/停止/重启MySQL

2.3 配置Mysql默认字符集

提示:此时当前目录为根目录,进入 /etc/mysql/,打开 my.cnf。

不太熟悉vi命令的同学看这里:linux下vi命令大全

cd /etc/mysql/
vi my.cnf

按一下 i 代表输入操作,填入以下代码(如果数据库版本不是5.7.11+,里面的配置可能很乱,那就不要动它了。):

[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
default-character-set=utf8

[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
character-set-server=utf8

[mysql]
no-auto-rehash
default-character-set=utf8

提示:编辑完成后按一下键盘 ESC 输入:wq,代表保存退出,然后重启mysql服务使其生效:

service mysql restart

2.4 创建网站的数据库:

提示:进入mysql shell:

mysql -uroot -p

提示:接下来创建数据库并指定编码方式为UTF-8(其中dataname 为数据库名称,保证与Django连接数据库名称一致,否则连接会出错):

 CREATE DATABASE `dataname` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

提示:数据库操作基本命令:

SHOW DATABASES; #显示所有数据库
USE <NAME>;   #进入某数据库 
SHOW TABLES; #显示所有数据表
SELECT * FROM <NAME>; #查询表内容

多余的不说了,忘记的看看:mysql基本操作命令汇总

退出命令:quit 退回根目录 :cd

3. 关于Django项目静态文件的说明:

一般在开发环境中: 即settings.py中的DEBUG = True 时 , Django 会自动帮助我们处理静态文件,所以不用操心静态文件不加载的问题,但是在部署时,出于安全考虑,我们必须关闭DEBUG!保证自己网站的信息不泄露。只是当DEBUG关闭后,Djang就不会帮我们处理静态文件了,所以会出现样式丢失,静态文件404问题。

3.1 文件说明:

  • MEDIA_ROOT:媒体文件收集路径,所有上传的文件存储路径。示例:图像,文件。
  • STATIC_ROOT:静态文件收集路径, 在开发中,STATIC_ROOT什么都不做。你甚至不需要设置它。
  • STATICFILES_DIRS :静态文件的额外目录,STATICFILES_DIRS用于包含要查找的其他静态文件目录。比如你自己新建的一个静态文件文件夹。

说明:Django在每个应用程序目录(项目/Apps/static)中自动查找静态文件。当你的项目部署时,事情有所不同,Django处理静态文件能力并不强,于是在实际生产环境时它将这个任务交给了Nginx。

而为什么要收集到一个文件夹内呢?这是因为如果你项目存在很多APP,每个APP下又有不同的静态文件,Nginx可不会自动寻找,它的配置文件中只能指定一个静态文件路径,于是有了这个命令:python manage.py collectstatic,后面你会了解它的用法。

3.2 部署前Django项目settings.py中的设置:

提醒:首先DEBUG设置为False,ALLOWED_HOSTS里面填入你的域名或者IP。

DEBUG = False
ALLOWED_HOSTS = ['nocmt.com', 'www.nocmt.com']

提醒:时区+语言+收集静态文件目录设置

LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
STATICFILES_FINDERS = (
  'django.contrib.staticfiles.finders.FileSystemFinder',
  'django.contrib.staticfiles.finders.AppDirectoriesFinder',)

4. 安装Python 3.6.1

4.1 教程:

点击这个:Ubtuntu16.04 安装 python3.6.1 教程

提示:如果下载速度太慢,就看上面的 FileZilla 教程,自己下载好压缩包上传上去,再解压安装。CTRL+Z退出。

4.2 安装虚拟环境,我们在这里淘汰virtualenv。

提示:因Python3+自带虚拟环境,更简单好用,所以没必要再装一个。
在home目录下创建名称为vcmt的虚拟环境。

python3.6 -m venv /home/vcmt

激活虚拟环境:

source /home/vcmt/bin/activate  

记住退出命令为:deactivate

4.3 快速安装原开发环境中的所有第三方库:

提示:首先在开发机上中的控制台输入(当然是你项目依赖的python环境下):

pip freeze > requirements.txt

这会在当前目录生成一个第三方库列表。

把生成的requirements.txt文件复制到服务器上,随便一个目录都可以。

在服务器上执行:

pip install -r requirements.txt

它会自动读取requirements.txt中的扩展库信息并在本机进行安装。

这里我们利用 FileZilla Client把文件上传上去,并且把Django项目丢上去。

我的目录一般在/home/下。

教程:阿里云服务器ECS连接 Linux 实例

注意:上传项目文件后把 /项目名/app名/migrations/ 下的类似00.. 的记录文件删除,有几个删除几个,但是不要删除别的文件。

删除记录文件

这是在本地进行数据同步时产生的记录文件,由于我们并不是转移的数据库,所以要删除旧的记录!

5. Django数据库配置+静态文件收集+管理员建立

5.1 进入Django项目下,同步并创建数据库,执行:

cd /home/suly/
python manage.py makemigrations
python manage.py migrate

注意:如果出错了,首先检查models.py 里面是不是有什么错误,包括在第一行设置UTF-8编码方式,因为我发现它有时也会出现这种问题!再检查settings.py 关于连接部分的设置对不对,最后检查是不是3306端口没打开!一般都是这几个问题。

5.2 建立后台超级用户:

python manage.py createsuperuser

启动自带的服务器,测试是否可以正常运行!(此时settings.py 中的DEBUG = False)输入:

python manage.py runserver 0.0.0.0:8000

提醒:如果无法访问,是因为默认8000端口关闭了,打开它是在阿里云配置安全组里面,自己去找找。

而打开端口后出现:Bad Request (400),是因为我们之前ALLOWED_HOSTS里面只添加了域名,不过如果按照教程一步一步来的,没有必要测试,我这边启动时也没报错,所以判断是完美的。不管它,CTRL+Z 强制退出!并清理8000端口相关联的进程。

fuser -k 8000/tcp

5.3 同步静态文件:

python manage.py collectstatic

此时项目下的settings.py 中的STATIC_ROOT 后面的文件夹应该是'static' .

6. uWSGI的安装

6.1 安装:

pip install uwsgi

正常启动测试(suly为项目名称):

uwsgi --http :8000  --chdir /home/suly/ -w suly.wsgi

提醒:访问地址为(http://ip:8000)同时确保你的8000端口已经开启。

注意:这里有些朋友访问测试时会出现502错误,这个时候控制台会详细输出日志,按照上面的提示修改代码。

如果修改好以后启动没有问题,但还是访问不了,那么你需要将Django的settings.py 里面的DEBUG=True,ALLOW_HOST=['*'],保存重新开启并调试!大部分人会卡在这个步骤,如果确认你的代码没有问题,你就不要管这里了,直接往下部署,把所有文件全部弄好后,再来调试!后面我有时间也可以远程帮你!

记住部署完成后你需要恢复原来的样子!

6.2 uWSGI的配置:

首先建立一个配置目录及文件:

mkdir -p /etc/uwsgi/sites
cd /etc/uwsgi/sites

在里面建立以自己项目名命名的配置文件:

vi suly.ini

填入以下内容:你只需要改project和Base,一个项目名称,一个项目路径。

[uwsgi]
project = suly
base = /home

chdir = %(base)/%(project)
module = %(project).wsgi:application

master = true
processes = 5

socket = %(base)/%(project)/%(project).sock
chmod-socket = 666
vacuum = true

现在建立一个自启脚本:

vi /etc/init/uwsgi.conf

内容如下 setuid的值改为你的项目名:

description "uWSGI application server in Emperor mode"

start on runlevel [2345]
stop on runlevel [!2345]

setuid suly
setgid www-data

exec /usr/local/bin/uwsgi --emperor /etc/uwsgi/sites

最后一个问题,www-data 用户组没有创建。

7. Nginx的安装和配置

7.1 安装

apt-get install nginx

7.2 创建配置文件

vi /etc/nginx/sites-available/suly

提示:填写内容如下(server_name为被解析域名,如果暂时没有域名那就填公网IP,Django项目settings.py中的,静态文件夹地址一定要填对,否则样式会出错!):

基础版:

server {

    listen 80;
    server_name nocmt.com;

    location /static/ {
        root /home/suly;
        }

    location /media/ {
        root /home/suly;
    }

    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/home/suly/suly.sock;
        }
    }

日志版:

server {
    listen 80;
    server_name nocmt.com;
    access_log /home/suly/nginx.access.log;
    error_log /home/suly/nginx.error.log;

    location / {
            include         uwsgi_params;
            uwsgi_pass      unix:/home/suly/suly.sock;
        }
    location /static/ {
            root /home/suly;
        }
    location /media/ {
        root /home/suly;
    }
    location /favico.ico  {
        root /home/suly/static/img/favico.ico;
        }
}

保存退出!

多站点多域名看这里:Nginx多站点+301重定向的配置

然后链接文件:

ln -s /etc/nginx/sites-available/suly /etc/nginx/sites-enabled/

检查是否有错误的命令:

service nginx configtest
提示ok才是正确的

提示:出现错误,那就是配置文件写错了,自己检查一下,没有就直接启动!

关于检查错误,需要查看Nginx的错误日志,/etc/nginx/nginx.conf文件内最下面会有路径代码。
这里不做过多阐述。后续更新教程再说。

重启命令:

service nginx restart

启动uwsgi :

uwsgi /etc/uwsgi/sites/suly.ini -d /home/suly/suly.log

访问你的网站,试试看!如果有问题可以评论或者简信我!


以下的错误,是因为我之前安装uwsgi时是使用的sudo方式,导致安装到Python2.7上面去了,后面我已经全部修正错误了,这种情况就没有再出现过。

我在后台提交数据时总是出现500错误,于是我把Debug开启,得到的错误消息如下:

默认还是调用的2.7,然后出现编码问题

我怎么解决的:

思路:我们都知道python2.7默认编码方式是ascil,而中文是需要utf-8支持的,于是我们只要修改python默认的字符编码为utf-8就可以了,经过查询,我得到ubuntu的python2.7安装目录 为:/usr/lib/python2.7,在它的目录下打开一个叫sitecustomize.py的文件,如果没有就建立一个,它的作用就是在python启动时就会执行一次该脚本。我们在最前面写入下面几行代码(里面会有几行代码,不要管它):

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

测试,命令行输入python2.7,启动shell,输入:

import sys
sys.getdefaultencoding()

返回'utf-8'!退出shell重启uwsgi,没问题了。


参考文章:

1.基于Django框架的网站部署

2.Django+Nginx+uwsgi部署

3.在 Ubuntu 16.04 LTS 上安装 Python 3.6.0

4.Linux下MySQL 5.5/5.6的修改字符集编码为UTF8

5.STATICFILES_DIR,STATIC_ROOT和MEDIA_ROOT之间的差异

6.Ubuntu+Django+Nginx+uWSGI+Mysql搭建Python Web服务器

7.五步教你实现使用Nginx+uWSGI+Django方法部署Django程序(上)

8.五步教你实现使用Nginx+uWSGI+Django方法部署Django程序(下)

9.Django + uwsgi + nginx + bootstrap 创建自己的博客 -- 13.部署

10.CentOS+Apache+mod_wsgi+Python+Django - 昨、夜星辰 - 博客园

......

推荐阅读更多精彩内容