须要在阿里云服务器部署Django-restframework框架,一开始不清楚状况,网上找了不少的文章和办法,东拼西凑也没有可以彻底实现nginx和uwsgi的互通。html
参考过的文章有前端
-视频:Nginx + uWsgi 部署 Django + Mezzanine 生产服务器python
-文章:uWSGI+django+nginx的工做原理流程与部署历程mysql
-文章:uwsgi官方文档linux
-文章:Django Nginx+uwsgi 安装配置nginx
-文章:centos7 下经过nginx+uwsgi部署django应用 c++
由于是东拼西凑,因此不管是网上的文章仍是本身拼凑的配置,都是没有办法打通的。后来红包求助,才了解到有这几个地方:git
一、nginx执行权限sql
二、uwsgi配置数据库
三、uwsgi设置虚拟环境
四、uwsgi安装问题及插件安装问题
五、django静态文件收集处理
六、
因为安全需求,仍是配置一个非管理员(本身操做,增长sudo受权)帐户操做,经过命令建立用户名密码
adduser quinns # 新增用户
passwd quinns # 为quinns设置密码
复制代码
设置好以后,还须要开启sudo权限,经过命令:
vi /etc/sudoers
复制代码
而后找到有 root ALL=(ALL)那一行,而后在下面增长一行:
quinns ALL=(ALL) ALL
复制代码
保存便可。
下面的操做,用新用户quinns登陆来操做。
uwsgi和nginx以及anaconda的安装会存在一些报错问题,这里为了不出现这状况,因此先安装好依赖。
sudo yum install gcc-c++
sudo yum install wget openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel libxml* pcre-devel python-devel bzip2
复制代码
经过quinns帐户登陆,而后到quinns用户目录(/home/quinns)下新建一个utils目录,把一些软件下载在utils目录下。
经过wget方式下载anaconda(官网)
wget https://repo.continuum.io/archive/Anaconda3-5.0.1-Linux-x86_64.sh
复制代码
若是想更快,就安装国内源(清华镜像):
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.1.0-Linux-x86_64.sh
复制代码
下载好以后sh安装
sh Anaconda3-5.0.1-Linux-x86_64.sh
复制代码
一路默认,到以后面安装完的时候会提示是否添加环境变量,输入yes便可。
若是想要后面使用更快,能够更改仓库镜像(我没试过):
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes
复制代码
这样的话安装软件都是国内源,速度比较快(据说是)
经过命令:
conda list
复制代码
来验证是否成功安装并加入环境变量,若是出现list列表则表明成功,若是出现报错提示信息则须要用命令:
source ~/.bashrc
复制代码
来添加,而后重复conda list命令。若是仍是不行,则编辑/etc/profile文件,在底部添加环境变量及指向:
export PATH=/home/quinns/anaconda3/bin:$PATH
复制代码
经过文件添加的环境变量需重启服务器才能生效 sudo reboot
在确认安装好anaconda以后,先不着急新建虚拟环境,直接在linux下输入python,检查默认python是否已自动替换为python3.6。接着经过pip安装uwsgi:
pip install uwsgi
复制代码
若是不成功则尝试使用aliyun的源 阿里云的源我复制下来了,是:
http://mirrors.aliyun.com/pypi/packages/a2/c9/a2d5737f63cd9df4317a4acc15d1ddf4952e28398601d8d7d706c16381e0/uwsgi-2.0.17.1.tar.gz
复制代码
待有安装成功的提示出来,再经过命令:
uwsgi --version
复制代码
来确认是否成功安装。
经过anaconda来建立python虚拟环境:
conda create --name envname python=3.6.3
(亲身经历 3.6.5没法启动uwsgi,最好仍是3.6.3)
复制代码
观察过程,无报错即完成安装。
直接经过yum来安装nginx便可,若是想安装新版,能够在网上寻找新方法。
sudo yum install nginx
复制代码
若是是centos7 是默认没有Nginx源的,须要给它添加源,才能使用Yum install 安装
sudo rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
复制代码
安装完成后应该是自动启动服务,在浏览器输入ip便可访问nginx的欢迎页面。若是没有,经过命令:
sudo service nginx start/restart
复制代码
来启动或者重启nginx服务。
先下载mysql的repo源
wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
复制代码
接着安装mysql-community-release-el7-5.noarch.rpm包
sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm
复制代码
安装这个包后,会得到两个mysql的yum repo源:/etc/yum.repos.d/mysql-community.repo,/etc/yum.repos.d/mysql-community-source.repo。
最后执行安装
sudo yum install mysql-server
复制代码
先受权
sudo chown -R root:root /var/lib/mysql
service mysqld restart # 而后重启
复制代码
接着重置密码
mysql -u root //直接回车进入mysql控制台
mysql > use mysql;
mysql > update user set password=password('quinns') where user='root';
mysql > exit;
service mysqld restart # 而后再重启一次服务
复制代码
重点:在实际的应用当中,咱们通常不推荐使用root帐户,而是新增用户并对其进行受权。
因此,这里我要加上删除线
mysql默认是不开启远程访问的,想要在本地链接服务器的mysql,必须开启:
mysql -u root -p
mysql> use mysql;
mysql> update user set host = '%' where user = 'root';
service mysqld restart # 这里也要重启一次服务
(过30秒或者1分钟再测试远程链接)若是不行的话,接着重启服务一次。
CREATE USER 'username'@'host' IDENTIFIED BY 'password';
复制代码
命令含义说明:
username:你将建立的用户名
host:指定该用户在哪一个主机上能够登录,若是是本地用户可用localhost,若是想让该用户能够从任意远程主机登录,可使用通配符%
password:该用户的登录密码,密码能够为空,若是为空则该用户能够不须要密码登录服务器
复制代码
好比这里我能够把命令改为:
CREATE USER 'quinns'@'%' IDENTIFIED BY '123456';
复制代码
意味着我新建了一个名为quinns且密码为123456的用户,并给它开启了全部ip地址远程链接(固然也能够指定某个ip)
GRANT privileges ON databasename.tablename TO 'username'@'host'
复制代码
命令含义说明:
privileges:用户的操做权限,如SELECT,INSERT,UPDATE等,若是要授予全部则使用ALL
databasename:数据库名
tablename:表名,若是要授予该用户对全部数据库和表的相应操做权限则可用*表示,如*.*
复制代码
受权命令示例:
GRANT SELECT, INSERT ON test.user TO 'pig'@'%';
GRANT ALL ON *.* TO 'pig'@'%';
GRANT ALL ON maindataplus.* TO 'pig'@'%';
复制代码
命令:
SET PASSWORD FOR 'username'@'host' = PASSWORD('newpassword');
复制代码
若是是当前登录用户用:
SET PASSWORD = PASSWORD("newpassword");
复制代码
例子:
SET PASSWORD FOR 'pig'@'%' = PASSWORD("123456");
复制代码
命令:
REVOKE privilege ON databasename.tablename FROM 'username'@'host';
复制代码
说明:
privilege, databasename, tablename:同受权部分
复制代码
例子:
REVOKE SELECT ON *.* FROM 'pig'@'%';
复制代码
注意:
假如你在给用户'pig'@'%'受权的时候是这样的(或相似的):GRANT SELECT ON test.user TO 'pig'@'%',则在使用REVOKE SELECT ON *.* FROM 'pig'@'%';命令并不能撤销该用户对test数据库中user表的SELECT 操做。相反,若是受权使用的是GRANT SELECT ON *.* TO 'pig'@'%';则REVOKE SELECT ON test.user FROM 'pig'@'%';命令也不能撤销该用户对test数据库中user表的Select权限。
复制代码
具体信息能够用命令
SHOW GRANTS FOR 'pig'@'%';
复制代码
查看。
命令:
DROP USER 'username'@'host';
复制代码
参考来源:传送门
安装好这些软件后,须要确保独立服务都是正常运行的。
在/home/quinns目录下新建wwwroot目录,而后在里面新建一个测试文件uwsgitest.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World, This uwsgi server is running"]
复制代码
保存后经过命令来启动
uwsgi --http :8000 --wsgi-file uwsgitest.py
复制代码
看到服务启动后,就能够在浏览器访问8080端口,若是可以正常显示文字内容,则表明uwsgi单独服务是能够正常运行的。若是没有,根据报错找缘由。
能够在本地,经过ssh对服务器进行链接,其中也包括上传下载服务。
本地打开终端后输入:
scp -r djangoName quinns@47.98.212.01:/home/quinns/wwwroot
复制代码
将当前目录的djangoName文件夹经过quinns帐户上传到/home/quinns/wwwroot目录内。回车执行后输入quinns的密码便可看到上传到指定的wwwroot目录内。
本地开发环境下的django和服务器的设置有些许不同。
首先要开放ALLOWED_HOSTS,使得程序能够远程访问,而后再设置静态文件,最后再经过命令来测试是否能够顺利启动。
找到django项目的settings.py文件,里面有个ALLOWED_HOSTS,是接收一个空列表,如今要将服务器地址或者域名添加进去(也能够放*号,表明全部均可以指向这里,可是不推荐这么作):
ALLOWED_HOSTS = ['47.98.209.107']
复制代码
上面就算是开启了远程访问,接着设置静态(drf有一些样式,若是不设置,经过uwsgi启动是没法加载的)。一样是在settings.py文件中,下部分代码中有个STATIC_URL = '/static/',在它下面新增一行:
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
复制代码
保存文件,而后在虚拟环境下执行命令:
python manage.py collectstatic
复制代码
这样django就会收集静态文件,放到指定目录内,也就是(static目录内)
uwsgi能够经过命令来启动django项目,也能够经过配置文件ini或者xml来启动。这里已ini为例。
在项目根目录(manage.py同目录,其实哪一个目录均可以,这里是方便寻找)新建文件夹conf,而后再在conf下新建uwsgi文件夹(这俩文件夹什么名字无所谓)。接着新建uwsgi的配置文件,这里暂且叫作lagou_uwsgi.ini 里面写上uwsgi与项目的配置信息:
ite_uwsgi.ini file`
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /home/quinns/wwwroot/GamesAPI
# Django's wsgi file
module = GamesAPI.wsgi
# the virtualenv (full path)
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 4
threads = 2
# the socket (use the full path to be safe
socket = 127.0.0.1:8001
# ... with appropriate permissions - may be needed
# chmod-socket = 664
# clear environment on exit
vacuum = true
virtualenv = /home/quinns/anaconda3/envs/envgames
python-autoreload=1
logto = /home/quinns/wwwroot/GamesAPI/uwsgilog.log
stats = %(chdir)/conf/uwsgi/uwsgi.status
pidfile = %(chdir)/conf/uwsgi/uwsgi.pid
复制代码
具体的含义在uwsgi文档都有,这里记录一下:
chdir # 项目绝对路径
module # 项目内的uwsgi.py文件,其实与项目同名便可
master
processes
threads
socket # 服务启动地址及端口
vacuum
virtualenv # 这个就很重要了,python虚拟环境地址
python-autoreload=1 # python自启动
logto # 自动生成日志文件及存放路径
stats
pidfile
复制代码
这就算是编写好uwsgi的配置文件了,接着编写nginx的配置。
最好不要改动原有的ningx,来新建一个新的.conf配置文件吧。一样在项目目录的conf目录内新建nginx文件夹,而后再在nginx文件夹里新建lagou.conf配置文件,里面写上nginx的配置:
upstream games {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8001; # uwsgi的端口
}
# configuration of the server
error_log /home/quinns/wwwroot/nginxerror.log;#错误日志
server {
# the port your site will be served on
listen 8080;
# 端口
server_name 47.98.209.107 ; # 服务器ip或者域名
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /home/quinns/wwwroot/GamesAPI/media; # 指向django的media目录
}
# Django static
location /static {
alias /home/quinns/wwwroot/GamesAPI/static; # 指向django的static目录
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass games;
include uwsgi_params; # uwsgi服务
}
}
复制代码
里面都有说明了,我就不写了。其的upstream games中的games是自定义名称,可是要与下面的uwsgi_pass games中games名称相同。
注意: .conf文件创建好后,要与让nginx知道并认可,因此须要经过软链接来连接到/etc/nginx/conf.d/目录下,若是不知道软链接怎么作,能够把这个文件copy到这个目录下。
而后重启服务器
sudo service nginx restart
复制代码
有些版本的命令是:
sudo systemctl restart nginx.service
复制代码
若是没有报错,应该就是能够了。
若是有报错,没有重启ng服务器,那确定是配置文件写错了,得去看一下。
既然uwsgi也配置好了,django项目的虚拟环境也pip install -r requirements.txt过了,ng的配置文件也写好了。那就能够启动服务了。
经过linux命令来进行启停
sudo service nginx restart/start/stop
复制代码
若是以前启动过,就不用重启了。
找到刚才编写的lagou_uwsgi.ini配置文件目录,经过命令来启动:
uwsgi -i lagou_uwsgi.ini &
复制代码
若是没有报错,就表明启动了。就能够在浏览器访问以前.conf配置文件配置的8080端口了。
后期部署发现,不一样版本的Centos对权限的设定是不同的。
好比:
不能在自定义的nginx.conf文件中填写erro_log的配置
须要在/etc/nginx/nginx.conf里面将user改为root
若是发现502 bad getway,就须要查看uwsgi日志和nginx日志,若是在nginx日志(默认/var/log/nginx/error.log)看到以下提示
2018/08/19 21:06:37 [crit] 967#967: *1 connect() to 127.0.0.1:8001 failed (13: Permission denied) while connecting to upstream, client: 192.168.0.103, server: 192.168.0.61, request: "GET / HTTP/1.1", upstream: "uwsgi://127.0.0.1:8001", host: "192.168.0.61:8080"
复制代码
就表明是权限方面的问题,通过网上文章搜索,找到缘由SeLinux的致使的。
解决办法有两种,比较直接的是运行命令:
setsebool -P httpd_can_network_connect 1
复制代码
后来又产生新的问题,Django的静态文件没法正常加载,nginx返回的是403.
解决这种问题的办法是经过配置文件,长期关闭SeLinux,怎么关:《烦人的linux权限问题-SeLinux》
后端api没有问题后,前端也要部署。
前端经过npm run build打包以后,将build文件经过ssh上传到wwwroot目录下:
scp -r build quinns@xx.xx.xx.xx:/home/quinns/wwwroot
复制代码
等到上传完成后,就到nginx那里进行静态的部属配置
cd /etc/nginx
复制代码
而后打开nginx.conf文件进行编辑。
首先要给nginx文件进行访问受权,不然有些目录是会报错403的。其配置文件中有:
user nginx;
复制代码
这里得给他改为用户的权限,如quinns或者root
user quinns;
复制代码
看到server部分的代码:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
# 配置这个,才能正确跳转路由,如47.98.110.67/detail/1
add_header Cache-Control "no-cache, no-store";
index index.html;
try_files $uri /index.html;
}
……
……
}
复制代码
是这样的,访问网址80端口默认指向/usr/share/nginx/html目录下的index.html
由于静态打包后build也是由index.html来做为主入口的。因此这里只须要把root的指向改过来便可:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
#root /usr/share/nginx/html;
root /home/quinns/wwwroot/build;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
# 配置这个,才能正确跳转路由,如47.98.110.67/detail/1
add_header Cache-Control "no-cache, no-store";
index index.html;
try_files $uri /index.html;
}
……
……
}
复制代码
将原来的root指向注释掉,增长build文件夹的指向
而后重启nginx服务,打开浏览器访问,就能够看正常的页面了。
心中一阵窃喜,这个坑终因而填上了。