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 --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/下。
注意:上传项目文件后把 /项目名/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
提示:出现错误,那就是配置文件写错了,自己检查一下,没有就直接启动!
关于检查错误,需要查看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开启,得到的错误消息如下:
我怎么解决的:
思路:我们都知道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,没问题了。
参考文章:
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 - 昨、夜星辰 - 博客园
......