阿里云部署Django项目
环境
基于Ubuntu16.04 + Python3(虚拟环境) + nginx + mysql + Django
一、安装必要的软件,配置python环境
1.安装python:
阿里云Ubuntu 16.04服务器自带python版本是2.7的,PIP版本也非常落户,到手后一定要升级Python和PIP, 命令如下。
sudo apt-get install python3.5
sudo apt-get update
sudo apt-get install python3-pip
pip3 --version
升级pip:
pip3 install --upgrade pip
2.安装pillow
pip3 install pillow
图像处理库
3.安装virtualenv和virtualenvwrapper虚拟环境
Virtaulenvwrapper是virtualenv的扩展包,用于更方便管理虚拟环境,它可以方便实现以下功能:
①将所有虚拟环境整合在一个目录下
②管理(新增,删除,复制)虚拟环境
③切换虚拟环境
推荐使用pip安装
pip3 install virtualenv
pip3 install virtualenvwrapper
创建虚拟环境:virtualenv MyDjango
激活环境source MyDjango/bin/activate
4.安装django
pip3 install django
5.查看linux的ip,方便连接到Xftp传输文件
建立会话输入云服务器的公网ip和root账户密码
采用root登录,密码需要去网站设置。
6.安装mysql
输入以下安装命令:sudo apt-get install mysql-server mysql-client
注:Ubuntu自带的版本是5.07的,如果本地是8.0以上的,在数据迁移的时候,会出现编码的问题,下面会提及到,
所以最好服务器上的版本和本地的版本一直。下载方法,通过本地下载安装包,然后通过Xftp上传到服务器,进行安装。
记住输入的密码
安装完后,输入 mysql -u root -p
输入密码create database ***
注:创建数据库,这里我为了部署django项目,所以要和django项目采用的数据库名相同
接下来进行数据的迁移:
数据的迁移:把本地数据库中的数据复制到阿里云上的数据库中。先在本地生成备份文件,syz_user是要备份的数据库,mysqls.sql是生成的备份文件。然后用Xftp把mysqls.sql文件上传到阿里云。
mysqldump -u root -p syz_user> mysqls.sql
用来生成迁移文件
数据还原:阿里云终端 cd到mysqls.sql所在目录,输入以下命令
mysql -u root -p syz_user < mysqls.sql
注:
在我部署的时候出现了一下几个问题:
错误1:
如果两个数据库的mysql版本不一致,例如mysql8和mysql5,那么就会错:'utf8mb4_0900_ai_ci'
问题的原因是两个数据库待转移的表的字符格式不能被被转移数据库识别。
例如mysql8的utf8mb4_0900_ai_ci格式再mysql5中就不支持。就需要更改数据库字符编码和各个varchar等字段的编码方式。
在云服务器上打开导入的sql文件
解决方法:
• 把文件中的所有的utf8mb4_0900_ai_ci替换为utf8_general_ci
• 以及utf8mb4替换为utf8
最后找到mysqld.cnf文件注释掉bind-address
这一行
命令:/etc/mysql/mysql.conf.d/mysqld.cnf
#配置文件路径
#bind-address = 127.0.0.1
#注释掉这一行
这样做让mysql可以绑定云服务器ip
错误2:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
连接mysql时出错,由于linux特性,window没有
解决方法:
cd /ect/mysql
sudo vim my.cnf
会发现文件被重定向到其他地方了
因此 cd /ect/mysql/mysql.conf.d
sudo vim mysqld.cnf
增加protocol = tcp
之后重启mysql服务可能又会遇到问题
错误原因:Job for mysql.service failed because the control process exited with error code. See "systemctl status mysql.service" and "journalctl -xe" for details.
服务mysql启动失败,可能是端口被占用
解决方案:
sudo vim mysqld.cnf
将bind-address的注释去掉
或者可能端口被占用,修改为3307,原来端口号是3306
最后
systemctl enable mysql.service
确保mysql服务开启
启动mysql
systemctl start mysql
可以看到 ps -ef|grep mysql
mysql已经正常运行
注意:在生产环境中千万不要有rm -rf /var/lib/mysql的想法。
博主我就试过结果gameover,很多配置都没了,需要重装数据库,泪奔~
6.收集本地上项目的安装包清单
进入本地虚拟环境中
pip freeze > list.txt
将list.txt通过Xftp上传到服务器,然后进入服务器
pip install -r list.txt
按照清单上一个一个装,不过如果报错无非是版本不对,自己调整版本就行了。
7.修改Django的settings
将DEBUG = False
取消DEBUG模式,否则会暴露源码出去
ALLOW_HOST = ['*****']
这个改成阿里云服务器主机,所有的主机访问项目会访问这个ip
到此为止,项目文件迁移,环境搭建,数据库数据迁移完成,启动python manage.py runserver 观察项目是否能够启动,如果能启动则说明配置正确。
接下来就通过uwsgi,wsgi和nginx来实现浏览器ip或域名访问
注:Permission denied: ‘/home/admin/mblog/mainsite/info_login.log’
可能在启动python3 manage.py runserver时会报错,只要给它权限,采用sudo启动,即sudo python manage.py runserver就可以了
8.安装nginx反向代理服务器 (用户不需要知道目标服务器的地址,通过反向代理服务器作为目的地址)
pip3 install nginx
去阿里云查看自己IP地址
在浏览器输入IP地址:查看是否成功安装nginx
正向代理:
正向代理(forward proxy) ,一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并制定目标(原始服务器),然后代理向原始服务器转发请求并将获得的内容返回给客户端,客户端才能使用正向代理。我们平时说的代理就是指正向代理。
简单一点:A向C借钱,由于一些情况不能直接向C借钱,于是A想了一个办法,他让B去向C借钱,这样B就代替A向C借钱,A就得到了C的钱,C并不知道A的存在,B就充当了A的代理人的角色。
反向代理:
反向代理(Reverse Proxy),以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求的客户端,此时代理服务器对外表现为一个反向代理服务器。
理解起来有些抽象,可以这么说:A向B借钱,B没有拿自己的钱,而是悄悄地向C借钱,拿到钱之后再交给A,A以为是B的钱,他并不知道C的存在。
本项目中的nginx就是反向代理,原始服务器就是遵循wsgi协议的uwsgi服务器。
9.安装uwsgi
在你的本地电脑访问https://uwsgi-docs.readthedocs.io/en/latest/Download.html,下载Stable/LTS版本的源文件。
本地下解压这个源文件,然后用xftp把文件拖放到阿里云的Ubuntu的家目录(home)下,使用cd命令进入到该文件夹下,按顺序依次输入下面三条命令:
sudo apt-get install python3-setuptools
apt-get install build-essential python3
sudo apt-get install python3-dev
sudo python3 setup.py install
上面四条命令为uwsgi的依赖环境
pip3 install uwsgi
注:
①如果安装不小心中途退出,会出现另一个进程锁死的结果,因此需要手动杀死进程
这是因为有另外一个程序在运行,导致锁不可用。原因可能是上次运行更新或安装没有正常完
sudo rm -rf/var/cache/apt/archives/lock
sudo rm -rf/var/lib/dpkg/lock
②安装uwsgi时可能会报错:plugins/python/uwsgi_python.h:2:20: fatal error: Python.h: No such file or directory
原因为python版本错误
解决方法:sudo apt-get install libpython3.6-dev
然后再次执行pip3 install uwsgi
10.配置nginx
部署到服务器的静态文件不会携带Django自带的static静态文件,因此需要先收集静态文件。
在settings.py
中添加
STATIC_ROOT = 'd:/syz/virtualenvs/MyDjango/mblog/nginx/static/'
然后输入python manage.py collectstatic
注:STATIC_ROOT 用于部署时候将项目所有的静态文件全部集中存放,根目录从盘区开始,所以要绝对路径
将项目文件通过Xftp传输到服务器上
然后配置nginx文件
cd /etc/nginx/sites-available
sudo vim default
nginx配置:打开配置文件default,路径/etc/nginx/sites-available/default
,设置以下内容。一个是server_name后面换成你的阿里云公网IP,有的文章说不换也行。关键是下面2个location,第一个location是设置的和uWSGI的关联。第二个location /static是设置的静态文件的路径。如果你的项目还有media文件夹,那还要加一个location /media,把路径设置上。注意:location 和alias后面有空格。
注:如果没有加sudo执行vim,则保存时会报该文件为只读文件,因此将:wq改为:wq!强制保存就行了
添加修改内容如下:
server_name 你的服务器IP地址;
配置自己的static静态文件和media媒体文件路径
1 |
|
注:alias:用于设置指令的别名
alias[别名]=[指令名称]
注意:location后面是有空格的,必须要有!alias后面也是有空格的;include上面那句话也是要注释掉的!
最后重启nginx服务service nginx start
#启动service nginx stop
#停止service nginx reload
#重启
重启服务: service nginx restart
1.快速停止或关闭Nginx:nginx -s stop
2.正常停止或关闭Nginx:nginx -s quit
3.配置文件修改重装载命令:nginx -s reload
当然直接杀死进程也可以
sudo kill -9 pid
sudo killall -s INT processname
注:上传图片时可能会出现上传文件报413 Request Entity Too Large
错误。
因为业务客户端请求是走HTTP的post方法提交数据,而提交请求数据nginx是有限制客户端请求主体大小,“content-length”,如果超过了设定值,则客户端会收到报错 413 Request Entity Too Large,导致前端浏览器不能正常显示数据。
解决方法:
进入nginx.conf
cd /etc/nginx
sudo vim nginx.conf
加入这段代码:client_max_body_size 20M;
然后重启nginx。
额外增加点知识:
可以选择在http{ }中设置:client_max_body_size 20m;
也可以选择在server{ }中设置:client_max_body_size 20m;
还可以选择在location{ }中设置:client_max_body_size 20m;
三者有区别
设置到http{}内,控制全局nginx所有请求报文大小
设置到server{}内,控制该server的所有请求报文大小
设置到location{}内,控制满足该路由规则或目录下的请求报文大小
这里之前查看端口占用时用到了提一下:netstat -ltunp
指令查看端口号使用详情
11 配置uwsgi:
安装完成后,配置uWSGI:在django项目的根目录下,新建两个文件,uwsgi.ini和run.log
。第一个是uWSGI的配置文件,第二个是日志记录文件。设置uwsgi.ini文件如下:
这地方真的卡了好久,一定要写processes和threads,不然一直报找不到应用的错误!!
1 |
|
解释:
①chdir是django项目所在目录。
②socket后面的地址是和上面nginx配置文件中的地址uwsgi_pass 127.0.0.1:8002对应的,规定nginx和uWSGI之间的通信端口。
③daemonize就是日志文件的路径。
④disable-logging = true 表示不记录正常信息,只记录错误信息。
⑤wsgi-file是你django项目根目录下项目同名目录中有一个wsgi.py文件的路径。
⑥pidfile是记录uwsgi.pid文件的路径,这个文件是uWSGI运行后自动生成的,里面记录了uWSGI的进程号,可以用来重启uWSGI。
uWSGI基本命令:
启动:uwsgi --ini uwsgi.ini
停止:uwsgi --stop uwsgi.pid
重启:uwsgi --reload uwsgi.pid
启动后
[uWSGI] getting INI configuration from uwsgi.ini
表示启动成功
通过ps -ef|grep uwsgi
可以查看进程,判断uwsgi是否成功启动
杀死进程的方式:
killall -s INT uwsgi
(最后一个为进程名)
查看了run.log发现许多错误,这里记录一下
注:当运行uwsgi时, !!! no internal routing support, rebuild with pcre support !!!的解决方法
报错意思是:! ! !没有内部路由支持,使用pcre支持重新构建!!
pip uninstall uwsgi
sudo apt-get install libpcre3 libpcre3-dev
pip install uwsgi
12.将celery作为后台守护进程运行:
①首先安装进程管理工具supervisord
pip install supervisor
②cd 我的项目
③然后创建 管理celery的配置文件
mkdir /etc/supervisor
echo_supervisord_conf > /etc/supervisor/supervisord.conf
注:一定要将配置文件放在/etc目录下,也就是存放系统配置文件的地方
否则会报错:
错误:
supervisorctl status
报错
error: <class 'socket.error'>, [Errno 110] Connection timed out: file: /usr/local/lib/python2.7/socket.py line: 571
发现启动的方式是usr/local/bin/supervisord -c /usr/local/supervisor/supervisord.conf
配置文件不在默认的/etc/supervisor/supervisord.conf
那么要指定配置文件路径后正常
supervisorctl -c /usr/local/supervisor/supervisord.conf status
运行supervisorctl
时指定配置文件才可以正常运行supervisorctl
,否则supervisorctl默认去/etc/supervisord.conf去读取配置,导致错误,因此最好放在/etc/中
④编辑.conf配置文件
linux中:
1 |
|
⑤启动supervisord
在配置文件目录输入以下指令:
supervisord -c + .conf
⑥ 关闭重启supervisord
关闭supervisord需要通过supervisor控制器
supervisorctl -c supervisord.conf shutdown
重启supervisord也需要supervisor控制器
supervisortl -c supervisord.conf restart
⑦查看进程是否启动成功
ps -ef|grep supervisord
③supervisorctl 操作
supervisorctl
是 supervisord
的命令行客户端工具,使用的配置和 supervisord 一样,这里就不再说了。下面,主要介绍 supervisorctl 操作的常用命令:
输入命令 supervisorctl
进入 supervisorctl
的 shell 交互界面,就可以在下面输入命令了。:
help
# 查看帮助
status
# 查看程序状态
stop program_name
# 关闭 指定的程序
start program_name
# 启动 指定的程序
restart program_name
# 重启 指定的程序
tail -f program_name
# 查看 该程序的日志
update # 重启配置文件修改过的程序(修改了配置,通过这个命令加载新的配置)
也可以直接通过 shell 命令操作:
supervisorctl status
supervisorctl update
错误:
①.INFO spawnerr: unknown error making dispatchers for 'celery': EACCES(supervisord.log)
主要是没有权限操作日志文件
解决方案:
1 |
|
注:chown时修改日志文件的权限从文件的拥有者到指定的用户或组,这个权限一般为用户管理者root使用。
也可以采用Xftp的方法将日志文件权限修改:
注:
①sudo supervisorctl tail programname stdout
//查看programname的日志)该命令是动态的输出启动进程时的输出,主要用于动态差错
②tail -f filename
会把 filename 文件里的最尾部的内容显示在屏幕上,并且不断刷新,只要 filename 更新就可以看到最新的文件内容,再改错时很有用。
其实如果使用命令行的方式 只需要设定–logfile,一切的运行log都会放在一个log文件里,而使用子进程托管的方式,执行的log也只会放在一个log中,我的是放在celery_worker_err.log中,前提是设置了redirect_stderr=false ,来监听错误。
部署成功后,如果安装了ufw防火墙管理工具,那么需要手动允许端口号80的的访问
sudo ufw allow 80
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!