将django2.1.7部署到华为云centos7.2+Nginx+uwsgi+python3.7
首先参考下边的三篇文章,结合自己实操(有临时问题当然通过百度解决),有些有改动。
详细记录下来,供大家参考,也便于以后自己重新部署。
1、Django2.0+CentOS7.2+Nginx+uwsgi部署过程
2、CentOS7下部署Django项目详细操作步骤
3、Django项目windows开发后部署到Nginx+uwsgi服务器全过程,以及那些坑!!!
经过几天的折腾,终于部署成功:其中的艰辛你懂得。
其中不同文章教程来回折腾,经过几次的修改,云服务器都被我切换几次版本重新安装,centos7.5,centos7.2,ubuntu16,饶了一圈,最终成功的版本centos7.5(应该centos7都可以吧)。
刚开始都不能成功,真的让人怀疑人生。教程坑也太多,填不完啊!!!
郑重宣布,以下步骤是实操,不是直接复制别人的。个别语句可能会有差异,毕竟是在执行完以后写的文章,不过绝大部分语句是我从终端语句的记录复制过来。
部署及启动的心得记录下来,也大概说一下部署操作流程,可以提高大家安装效率:
1、Nginx是必须在root权限下安装,uwsgi在非root权限下启动(root下会有警告)。
2、先安装数据库,我是安装的mysql,其实这个不用像某文章说的在非root账户安装,可以root。
3、新建用户,及在该用户下安装python3及虚拟环境。
4、安装nginx,及设置开机启动等 (下边的操作4和5颠倒的,也是按照别人的教程弄的,不过通过后期我启动项目的情况看,其实应该是先5后4更合适。不过顺序也不影响安装)
5、安装及启动uwsgi (启动的时候是在虚拟环境下,最好启动后再执行以下systemctl start nginx,反正有时我操作的时候,不执行这个,会连接失败;
如果出现bind(): Address already in use [core/socket.c line 769] ,也就是端口占用, 就用后边的方法kill。)
6、修改django中settings.py的参数
(CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
这两项得注释掉,否则会报错CSRF问题,还有就是在xadmin登录界面输入账号密码没反映,一致显示登录界面)
Django的部分setting设置项解释:
设置SECURE_HSTS_SECONDS开启HSTS头,强制HTTPS访问
设置SECURE_CONTENT_TYPE_NOSNIFF输出nosniff头,防止类型混淆类漏洞
设置SECURE_BROWSER_XSS_FILTER输出x-xss-protection头,让浏览器强制开启XSS过滤
设置SECURE_SSL_REDIRECT让HTTP的请求强制跳转到HTTPS
设置SESSION_COOKIE_SECURE使Cookie为Secure,不允许在HTTP中传输
设置CSRF_COOKIE_SECURE使CSRF Token Cookie设置为Secure,不允许在HTTP中传输
设置CSRF_COOKIE_HTTPONLY为HTTP ONLY
设置X_FRAME_OPTIONS返回X-FRAME-OPTIONS: DENY头,以防止被其他页面作为框架加载导致ClickJacking
部署前运行安全性检测 django-admin.py checksecure --settings=production_settings
如果你的服务可以正常使用了,那下次直接切换到非root账户,workon env_name。切换到uwsgi.ini路径,直接运行uwsgi --ini uwsgi.ini就正常启动项目了。
新建非root账户
参考这篇:CentOS 7 中添加新用户并授权
切换到新用户后,操作过程中运行提示权限不够的,一般只要在命令前加上 sudo即可
安装mysql
1、CentOS7 安装mysql(YUM方式)
上边的YUM安装简单,但是太慢了,显示要8个小时左右。
2、rpm方式安装,先从国内镜像下载(速度快多了,可以直接百度mysql8.0 国内镜像下载)
方法一:Centos7 安装mysql-8.0.13(rpm)
方法二:Centos7.4+Mysql8.0详细安装教程附安装包 #此方法亲测可行
3、启动
启动MySQL服务
shell> systemctl start mysqld
开机启动
shell> systemctl enable mysqld
重启
shell> systemctl daemon-reload
3、重置密码
vim /var/log/mysqld.log #查看初始化密码
mysql -uroot -p #登录Mysql
ALTER USER 'root'@'localhost' IDENTIFIED BY 'yourpassword'; # 重置密码
# 开启远程连接权限
CREATE USER 'admin'@'%' IDENTIFIED BY 'a123456'; #创建用户
grant all on *.* to 'admin'@'%';
flush PRIVILEGES;
4、新建一个数据库(跟django本地项目的名称一致)(这里暂时不考通过数据库拷贝方式)
mysql -u root -p
>>> create database your_database;
新建的用户下安装python3
切换用户 :
su - new_name
下载python3.7及安装
a、先安装相关包:
# 注意yum安装调用的是usr/bin/python,所以在创建python3的软连接前,先不要rm语句修改名称
sudo yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel
b、下载
wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz
c、解压缩
tar -xvf Python-3.7.0.tgz
d、编译
先切换到解压缩后的包: cd Python-3.7.0
–prefix参数:指定编译后的文件安放路径
./configure --prefix=/usr/local/python3
e、安装
make && make install #如果用make 再make instal ,貌似make 检测的太多,有点慢
#由于系统自带的python2已经调用 /usr/bin/python,先修改名字
mv python python.bak #这个语句先cd 到 /usr/bin
#创建python3的软连接
ln -s /usr/local/python3/bin/python3 /usr/bin/python
ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3
f、配置
因为执行yum需要python2版本,所以我们还要修改yum的配置,执行:
vi /usr/bin/yum
把#! /usr/bin/python修改为#! /usr/bin/python2
同理 vi /usr/libexec/urlgrabber-ext-down
文件里面的#! /usr/bin/python 也要修改为#! /usr/bin/python2
有一篇文章的另一种安装方法,备案下:
# 本文以/home/software作为主目录,所有软件都安装于此
mkdir -p /home/software
cd /home/software
wget https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tar.xz
tar -xf Python-3.6.0.tar.xz
mv Python-3.6.0 python3.6.0
cd python3.6.0
./configure prefix=/home/software/python3
make
make install
安装virtualenvwrapper
安装库
sudo pip3 install virtualenv virtualenvwrapper -i https://pypi.douban.com/simple
#查找virtualenvwrapper.sh路径
sudo find / -name virtualenvwrapper.sh
# /usr/local/python3/bin/virtualenvwrapper.sh
#建立一个软连接,否则mkvirtualenv会报错
sudo ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv
1.创建目录用来存放虚拟环境
mkdir $HOME/.virtualenvs
2.在~/.bashrc中添加行:
#加上下边的,防止运行source ~/.bashrc 的报错:No module named virtualenvwrapper
virtualenvwrapper.sh: There was a problem running the initialization hooks.
# 新增
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/python3/bin/virtualenvwrapper.sh #根据上边查找到的路径调整export
export VIRTUALENVWRAPPER_PYTHON=/usr/local/python3/bin/python3
export VIRTUALENVWRAPPER_VIRTUALENV=/usr/local/python3/bin/virtualenv
source /usr/local/python3/bin/virtualenvwrapper.sh
3.运行:
source ~/.bashrc
mkvirtualenv [-p 上边查到的python3路径] name_virtual # 也可以手工指定python版本
deactivate #退出环境
mvvirtualenv #删除环境
安装项目中的依赖库
1、收集静态文件
类似 startapp, 换成:
collectstatic # 先在本地环境下执行,把所有静态文件自动搜集到制定路径
2、部署前的自我检测本地项目
类似 startapp, 换成:
check --deploy
可以根据提示,把一些设置项增添上去,但是如果你的服务器还没有认证的,涉及SSL的项就不要设置了,要不后边不能通过http来测试。
3、导出本地项目中已安装的库文件(txt)
在本地项目的虚拟环境下:
pip freeze > requirements.txt
4、将requirements.txt文件传到云服务器中
如果是windows系统的可以参考:
使用PyCharm部署Django项目到云服务器
但是要注意,如果通过这个传整个项目,后期在服务端修改过的,会被覆盖,所以,上传项目的文件还是通过APP文件同步,这样不会把设置及配置类文件覆盖。
5、切换到your_project.txt路径:
先安装mysql-devel:
否则报错:OSError: mysql_config not found
或者报错:Command “python setup.py egg_info” failed with error code 1 in /tmp/pip-install-fwot3_uw/mysqlclient/
sudo yum install mysql-devel # 有次没有启动mysql服务,会报错
sudo apt-get install libmysqlclient-dev # ubuntu系统才用这个
#安装myPackage.txt中记录的所有包
#cd到your_project.txt所在的路径
pip install -r your_project.txt
安装和配置uwsgi
安装uwsgi
有教程说要在虚拟环境和非虚拟环境都执行一下下边的这个安装,我也没检验了,都安装了:
pip install uwsgi
建立测试文档
#test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"] #请注意这里,有些教程是python2格式的,到时就不会显示结果
检验测试
uwsgi --http :8000--wsgi-file test.py #反正我的服务器80端口是被占用了,自己换
#假定你的工程在/home/username下,project_name是你的项目名称,chdir 就是我们的根目录路径
#如果前边本地部署前做了colllectstatic的,静态文件现在会自动加载了
uwsgi --http :8080 --chdir /home/username/project_name/ --module project_name.wsgi --static-map=/static=static
前边几天不知道那出问题,折腾好久,终于测试成功了!!!
配置uwsgi.ini(暂时不与Ngnix结合考虑)
#自己配置的时候,最好把注释语句删除或者注释单独一行
[uwsgi]
http=0.0.0.0:8000 # 如果单独使用uwsgi来部署Django项目时,就用这一行。
# socket=0.0.0.0:8001 # 如果使用nginx+uwsgi来部署Django项目时,就用这行。其中,8001端口用来跟nginx通信。也要在阿里云防火墙中添加8001端口。
chdir=/home/user_name/Project_name/ # 你项目的完整路径。
# chmod-socket=664 # 给socket文件赋权限,这里不用管。
master=true # 启用主线程。
processes=4
threads=2
#logto=uwsgi.log # 经过实际检验,这一条语句不能保留,否则报错
#pidfile=uwsgi.pid # 经过实际检验,这一条语句不能保留,否则报错
module=Project_name.wsgi:application # 指定wsgi文件。在与settings.py同级目录中会有一个wsgi.py文件。
```
### 启动uwsgi
```linux
#注意cd到 uwsgi.ini目录
uwsgi --ini uwsgi.ini
安装及配置Nginx
1、安装
yum -y install nginx
2、检验安装及初始设置
# 注意得在root账户下执行
systemctl enable nginx
systemctl start nginx
可能会出现如下报错:
# systemctl start nginx
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
这种情况按照提示执行:
systemctl status nginx.service
就可以查看到很详尽的问题。我的一半提示是端口占用问题,
结束端口程序:
sudo fuser -k 8000/tcp #8000就是端口号,自行修正
3、nginx.conf配置
user root; #默认是nginx ,改成root,否则static文件加载失败
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
upstream django {
server 127.0.0.1:8009; #nginx转uwsgi桥接,端口号跟uwsgi配置里边的一致
}
server {
listen 8000 default_server;
listen [::]:8000 default_server; #注意修改端口号
server_name your_IP; #修改IP
root /home/hawk/project_name; #修改你的项目路径
include /etc/nginx/default.d/*.conf;
location / {
include uwsgi_params;
uwsgi_pass django;
}
location /static/ {
autoindex on;
alias /home/hawk/plan/static/; #修改成你静态文件路径
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
4、切换用户同时激活虚拟环境
# 切换用户
su - username
# 激活虚拟环境
workon env_name
cd 到 uwsgi.ini的路径
# 再切换回root
su
如果不切回root,
则会报错:nginx: [alert] could not open error log file: open() “/var/log/nginx/error.log” failed (13: Permission denied)
5、uwsgi配置调整(uwsgi与Nginx联动)
[uwsgi]
#http=0.0.0.0:8000
socket=127.0.0.1:8009 #更改这两行,定义自己端口,同时在云服务器策略中开启
6、启动服务
uwsgi --ini uwsgi.ini & nginx
如果端口被占用的报错,同上终止端口运行:
sudo fuser -k 8000/tcp
静态文件失效问题
1、在settings中设置
STATIC_ROOT = os.path.join(BASE_DIR, "static")
2、urls.py设置
import xadmin
from django.urls import path, include, re_path
from django.conf import settings
from django.conf.urls import url
from django.views import static
urlpatterns = [
path('xadmin/', xadmin.site.urls),
re_path('static/', static.serve,
{'document_root': settings.STATIC_ROOT}, name='static'),
]
补充知识
settings:file:返回文件名(含后缀名)。
https://www.jianshu.com/p/e60a6c4762ee
##安装python3
移动文件操作
vim /etc/nginx/nginx.conf
nginx -t
sudo fuser -k 8000/tcp #关闭制定的端口程序
uwsgi --ini uwsgi.ini #启动uwsgi
# 检查nginx安装是否成功
nginx -t
# 设置开机启动
[root@localhost ~]# systemctl enable nginx
# 停止开机自动启动
[root@localhost ~]# systemctl disable nginx
# 启动nginx服务
[root@localhost ~]# systemctl start nginx
# 查看服务当前状态
[root@localhost ~]# systemctl status nginx
# 重启nginx服务
[root@localhost ~]# systemctl restart nginx.service
# 查看所有已经启动的服务
[root@localhost ~]# systemctl list-units --type=service
killall -9 nginx