不轻松,服务器部署nginx+uwsgi+djangorestfremework+react
一、前言
需要在阿里云服务器部署Django-restframework框架,一开始不清楚情况,网上找了很多的文章和办法,东拼西凑也没有能够完全实现nginx和uwsgi的互通。
参考过的文章有
-视频:Nginx + uWsgi 部署 Django + Mezzanine 生产服务器
-文章:uWSGI+django+nginx的工作原理流程与部署历程
-文章:centos7 下通过nginx+uwsgi部署django应用
二、网上文章的遗漏
因为是东拼西凑,所以无论是网上的文章还是自己拼凑的配置,都是没有办法打通的。后来红包求助,才了解到有这几个地方:
1、nginx执行权限
2、uwsgi配置
3、uwsgi设置虚拟环境
4、uwsgi安装问题及插件安装问题
5、django静态文件收集处理
6、
三、部署安装记录
1、创建非管理员账户
由于安全需求,还是配置一个非管理员(自己操作,增加sudo授权)账户操作,通过命令创建用户名密码
adduser quinns # 新增用户 passwd quinns # 为quinns设置密码 复制代码
设置好之后,还需要开启sudo权限,通过命令:
vi /etc/sudoers 复制代码
然后找到有 root ALL=(ALL)那一行,然后在下面增加一行:
quinns ALL=(ALL) ALL 复制代码
保存即可。
下面的操作,用新用户quinns登录来操作。
2、安装依赖
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 复制代码
3、安装软件
通过quinns账户登录,然后到quinns用户目录(/home/quinns)下新建一个utils目录,把一些软件下载在utils目录下。
3.1安装anaconda
通过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 复制代码
这样的话安装软件都是国内源,速度比较快(听说是)
3.2验证是anaconda否成功安装
通过命令:
conda list 复制代码
来验证是否成功安装并加入环境变量,如果出现list列表则代表成功,如果出现报错提示信息则需要用命令:
source ~/.bashrc 复制代码
来添加,然后重复conda list命令。如果还是不行,则编辑/etc/profile文件,在底部添加环境变量及指向:
export PATH=/home/quinns/anaconda3/bin:$PATH 复制代码
通过文件添加的环境变量需重启服务器才能生效 sudo reboot
3.3安装uwsgi
在确认安装好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 复制代码
来确认是否成功安装。
3.4创建虚拟环境
通过anaconda来创建python虚拟环境:
conda create --name envname python=3.6.3 (亲身经历 3.6.5无法启动uwsgi,最好还是3.6.3) 复制代码
观察过程,无报错即完成安装。
3.5安装nginx
直接通过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服务。
3.6安装mysql
先下载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 复制代码
3.7重置mysql密码
先授权
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 # 然后再重启一次服务 复制代码
3.8重点说明
重点:在实际的应用当中,我们一般不推荐使用root账户,而是新增用户并对其进行授权。
所以,这里我要加上删除线
mysql默认是不开启远程访问的,想要在本地连接服务器的mysql,必须开启:
mysql -u root -p
mysql> use mysql;
mysql> update user set host = '%' where user = 'root';
service mysqld restart # 这里也要重启一次服务
(过30秒或者1分钟再测试远程连接)如果不行的话,接着重启服务一次。
3.9 新增用户并授权
a.创建用户
CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 复制代码
命令含义说明:
username:你将创建的用户名 host:指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost,如果想让该用户可以从任意远程主机登陆,可以使用通配符% password:该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登陆服务器 复制代码
比如这里我可以把命令改成:
CREATE USER 'quinns'@'%' IDENTIFIED BY '123456'; 复制代码
意味着我新建了一个名为quinns且密码为123456的用户,并给它开启了所有ip地址远程连接(当然也可以指定某个ip)
b.用户授权
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'@'%'; 复制代码
c.置与更改用户密码
命令:
SET PASSWORD FOR 'username'@'host' = PASSWORD('newpassword'); 复制代码
如果是当前登陆用户用:
SET PASSWORD = PASSWORD("newpassword"); 复制代码
例子:
SET PASSWORD FOR 'pig'@'%' = PASSWORD("123456"); 复制代码
d撤销用户权限
命令:
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'@'%'; 复制代码
查看。
e删除用户
命令:
DROP USER 'username'@'host'; 复制代码
参考来源:传送门
四、uwsgi服务测试
安装好这些软件后,需要确保独立服务都是正常运行的。
在/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单独服务是可以正常运行的。如果没有,根据报错找原因。
五、上传django-rest项目
可以在本地,通过ssh对服务器进行连接,其中也包括上传下载服务。
本地打开终端后输入:
scp -r djangoName quinns@47.98.212.01:/home/quinns/wwwroot 复制代码
将当前目录的djangoName文件夹通过quinns账户上传到/home/quinns/wwwroot目录内。回车执行后输入quinns的密码即可看到上传到指定的wwwroot目录内。
六、配置django
本地开发环境下的django和服务器的设置有些许不一样。
首先要开放ALLOWED_HOSTS,使得程序可以远程访问,然后再设置静态文件,最后再通过命令来测试是否可以顺利启动。
开启drf远程访问及静态设置
找到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配置
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的配置。
八、单项目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的配置文件也写好了。那就可以启动服务了。
nginx的服务启停
通过linux命令来进行启停
sudo service nginx restart/start/stop 复制代码
如果之前启动过,就不用重启了。
uwsgi启动项目
找到刚才编写的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》
十、nginx配置静态
后端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服务,打开浏览器访问,就可以看正常的页面了。
心中一阵窃喜,这个坑终于是填上了。
作者:asyncins
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- 点赞
- 收藏
- 关注作者
评论(0)