在虚拟机中安装CentOS并通过nginx+uwsgi部署django应用
virtualbox的安装
首先搜索并下载deb包,注意下载本机对应的版本。这里推荐一下deb安装包的软件gdebi,安装及使用:
~$ sudo apt install gdebi
~$ gdebi package.deb
CentOS安装及配置
CentOS安装及网络配置
在bash中运行:
~$ virtualbox
在界面中点击新建
- 虚拟电脑名称和系统类型,输入名称,系统Linux,版本选择Red Hat;
- 内存大小,不要少于1G;
- 虚拟硬盘,建议
创建
; - 虚拟硬盘文件类型,默认的VDI即可;
- 存储在物理硬盘,根据需求选择容量,点击
创建
。
点击显示
,选择下载好的iso文件,点击启动
,选择install即可安装。选择刚才分配的硬盘,进行新建用户、密码等操作,等待安装,完成后点击reboot重启进入系统。
为了实现主机对虚拟机的访问,需要修改网络类型为“桥接网卡(Bridged Adapter)”。(也可以选择Host-only Adapter模式,具体配置请自行搜索。)在进入系统之后如果无法上网,进入以下目录:
~$ /etc/sysconfig/network-scripts
然后修改ifcfg文件中的ONBOOT为yes即可。
更新及修改yum源
墙内访问yum源的速度很慢,我们来修改下yum源。这里直接用网易镜像站点中的配置文件。
- 进入yum配置文件目录
~$ cd /etc/yum.repos.d/
- 为防止出意外,先将原来的源文件备份
~$ mv CentOS-Base.repo CentOS-Base.repo.bak
- 下载163的配置
- 改名
~$ mv CentOS6-Base-163.repo CentOS-Base.repo
- 更新数据库
~$ yum update
这样就可以访问到163镜像了。
系统升级及安装基础软件包(部分可省略)
系统升级,以下命令按顺序执行
~$ yum clean all && yum makecache
~$ yum -y install epel-release # 此命令是安装yum源的扩展,必选
~$ yum -y update
安装基础包
~$ yum -y install sudo vim
~$ yum -y install zlib-devel bzip2-devel ncurses-devel openssl-devel
~$ yum -y install make gcc-c++ cmake bison-devel swig patch sqlite-devel
~$ yum -y install readline readline-devel rsync nload ntp ntpdate wget
~$ yum -y install net-tools telnet libjpeg-devel
配置django运行环境
安装pip
运行命令:
~$ yum install python-pip
~$ pip install --upgrade pip #直接安装的pip版本较旧,应该先升级一下
如果提示找不到pip源,需要首先安装源扩展包epel-release
~$ yum install epel-release
跟yum一样的问题,最好更新一下pip的源,提升下载速度,我这里更改为douban的镜像。首先在主目录下新建 .pip目录:
~$ mkdir /etc/.pip
在此目录下新建pip.conf文件并写入以下内容:
[global]
trusted-host = pypi.douban.com
index-url = http://pypi.douban.com/simple
保存重启bash即可。
安装django、扩展及MariaDB数据库
如果要在虚拟环境中运行,应当先安装virtualenv然后启动相应环境,我这里直接安装在系统中了。
~$ yum install python-devel #python开发依赖包,大家熟悉的python-dev在centOS上的的马甲 - -
~$ pip install django
运行
~$ pip install MySQL-python #连接python与mysql的工具
出现错误提示mysql_config不存在,所以要先安装MariaDB才可以。
运行以下命令:
~$ yum install mariadb-server mariadb-client
然后就出现错误了,提示找不到mariadb-client。谷歌原因,是因为yum源的问题,需要手动添加。
~$ cd /etc/yum.repos.d/
~$ vim MariaDB.repo
然后写入以下内容:
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.1/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
根据系统的不同,或者要安装选定版本MariaDB,具体内容会有区别。可以访问MariaDB官网,根据自己的情况选择然后就可以自动生成了。
然后运行:
~$ yum install MariaDB-server MariaDB-client
就会成功安装了。接着设置root用户密码:
~$ mysql_secure_installation
又报错。。。can't connect to local mysql server through socket '/var/run/mysql/mysql.sock',检索发现是mysql服务未开启,囧
~$ service mysql start
然后就可以重复上一条命令来设置root密码了。
然后安装mysqldb:
~$ pip install MySQL-python
结果还是报错。。继续检索,发现是没有安装MariaDB开发环境:
~$ yum install MariaDB-devel # mysql-dev在MariaDB的马甲
然后再运行,问题解决。总结一下,正确的安装顺序应当是python-devel> django > MariaDB(包括sever,client,devel缺一不可)> MySQL-python。
新建django项目并连接MariaDB数据库
首先进入MariaDB中新建好数据库(注意编码格式),可以采用如下sql语句:
~$ CREATE DATABASE your_database_name DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
接着新建一个django项目,并用来尝试连接MariaDB。
~$ django-admin startproject mysite
然后在mysite>mysite目录下setting.py中修改DATABASES部分为刚才创建的数据库。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'your_database_name',
'USER': 'root',
'PASSWORD': 'your_password',
'HOST': 'localhost',
'PORT': '',
}
}
然后启动查看是否连接成功。可以通过alt+fn命令另行启动一个窗口,然后登录同用户,再用w3m访问端口。
安装uwsgi并测试django项目
安装uwsgi:
~$ pip install uwsgi
然后cd到mysite主目录下执行:
~$ uwsgi --http :8000 --module mysite.wsgi
如果未看到报错信息,并且可以通过127.0.0.1:8000访问说明我们打通了这个环节:
~$ the web client <-> uWSGI <-> Django
接下来先让我们安装nginx。
nginx安装与配置
~$ yum install nginx
~$ service nginx start
然后我们访问127.0.0.1:80,如果显示nginx的默认页面,就说明nginx运行成功,我们打通了以下环节:
~$ the web client <-> the web server
接着我们就可以在nginx的conf中配置我们的网站了。首先我们查看nginx默认设置文件:
~$ vim /etc/nginx/nginx.conf
可以看到这么一行:
~$ include /etc/nginx/conf.d/*.conf
说明nginx能够读取在此目录下的conf文件,所以我们选择把配置文件放到这里。(这里不同的版本可能有所不同,请自己查看nginx能够自动读取的配置方式。)
所以我们在此目录下新建一个文件,就叫他mysite_nginx.conf好了,内容这么填:
~$ upstream django {
server 127.0.0.1:8001; # 作为nginx与uwsgi的socket通信端口
}
server {
listen 8000; #监听端口
server_name your_ip; #本机ip;
charset utf-8;
client_max_body_size 75M;
location /staic {
alias /path/to/your/mysite/static;
}
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params;
}
}
然后重启nginx服务,接着遇到错误,查看错误日志(需要管理员权限):
~$ vim /var/log/nginx/error.log
内容为无法bind到0.0.0.0:8000端口,谷歌之,原来是因为SELinux未关闭
~$ setenforce 0 # 临时关闭
重启nginx服务,成功。所以我们可以将接其设为永久关闭:
修改/etc/selinux/config 文件
将SELINUX=enforcing改为SELINUX=disabled
重启机器即可
还碰到一个坑就是在重启nginx服务的时候会碰到:找不到nginx.service的错误,手动添加一份即可,具体内容可以谷歌。
接下来我们就可以用socket的方式启动uwsgi啦:
~$ uwsgi --socket :8001 --module mysite.wsgi
如果不提示错误,然后访问127.0.0.1:8000能出现熟悉的It worked
页面,那我们就打通了如下环节:
~$ the web client <-> the web server <-> the socket <-> uWSGI <-> django
胜利就在眼前了,接下来我们把socket连接方式由端口变为文件形式,首先编辑我们创建的mysite_nginx.conf文件:
删除掉:server 127.0.0.1:8001;
然后修改为: server unix:///path/to/your/mysite/mysite.sock;
mysite.sock文件需要我们手动创建,内容为空即可。然后访问127.0.0.1:8000,不出意外的话。。。会得到一个502错误。查看nginx错误日志,会发现这么一句:
~$ connect() to unix:///path/to/your/mysite/mysite.sock failed (13: Permission
denied)
这条错误的意思是我们的nginx应用没有访问这个sock文件的权限,运行命令:
~$ uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=664
然后应该就可以从127.0.0.1:8000访问到我们的应用啦。
接着我们把相关设置写到一个ini文件里然后运行就可以了。新建mysite_uwsgi.ini,内容如下:
~$ [uwsgi]
chdir = /path/to/your/project
module = project.wsgi
master = true
processes = 4
socket = /path/to/your/project/mysite.sock
chmod-socket = 664
vacuum = true
然后运行:
~$ uwsgi --ini mysite_uwsgi.ini
然后访问本机的8000端口检查是否成功。
防火墙设置及外网访问
首先,我们要把本机ip(或者域名)添加到django中settings.py文件ALLOWED_HOSTS里面。
接着,我们需要关闭防火墙,键入以下命令:
~$ systemctl stop firewalld.service
如果我们要关闭主机的firewalld.service自启,可以这么做:
~$ systemctl disabled firewalld.service
然后就可以在虚拟机外通过 http://your_ip:8000 访问到了。
番外篇
将nginx及uwsgi服务设置为开机自启动
当我们试图用systemctl命令管理nginx或者uwsgi程序的时候,会提示类似错误:
Failed to nginx.service: Unit nginx.service failed to load: No such file or directory.
这条错误信息的意思是systemctl在目录下面找不到 *.service 文件,所以就无法管理啦。(这样的错误是由于我们是用pip安装的nginx或者uwsgi,如果用yum安装就不会有这样的问题……但是却有其他地方需要配置,本文就不说啦。)我们可以手动创建一个:
~$ vim /etc/systemd/system/nginx.service
输入:
[Unit]
Description = The NGINX HTTP and reverse proxy server
After = syslog.target network.target remotes-fs.target nss-lookup.target
[Service]
Type = forking
PIDFile = /run/nginx.pid
ExecStartPre = /usr/sbin/nginx -t # 在程序启动前做conf的语法检查
ExecStart = /usr/sbin/nginx #程序启动命令
ExecReload = /bin/kill -s HUP $MAINPID
ExecStop = /bin/kill -s QUIT $MAINPID
PrivateTmp = true
[Install]
WantedBy = multi-user.target
再创建uwsgi.service:
~$ vim /etc/systemd/system/nginx.service
[Unit]
Description=uWSGI
after=syslog.target
[Service]
ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/your_uwsgi.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
然后就可以通过systemctl命令管理了,启动:
~$ sudo systemctl start nginx
~$ sudo systemctl start uwsgi
开启自启:
~$ sudo systemctl enable nginx
~$ sudo systemctl enable uwsgi
uwsgi的emperor模式
uwsgi还有一个emperor模式,能够‘监控’uwsgi配置文件中的设置。首先创建目录:
~$ mkdir /etc/uwsgi
~$ mkdir /etc/uwsgi/vassals
然后在目录下新建文件emperor.ini,内容如下:
[uwsgi]
emperor = /etc/uwsgi/vassals
uid = root
logto = /tmp/uwsgi.log
这时候记得把/etc/systemd/system/uwsgi.service文件中ExecStart修改为emperor.ini文件。然后我们可以创建超链接到vassals文件夹中,‘皇帝’就会给我们把各个配置管理起来了。
~$ ln -s /path/to/your/mysite_uwsgi.ini /etc/uwsgi/vassals/
最后,可以用命令:
~$ systemctl status uwsgi
查看运行状况。
nginx的权限管理
我们知道,nginx会直接访问系统中的静态文件等,所以需要给其访问系统资源的权限。要实现这一点,我们之前的做法是修改nginx.conf文件中的user选项,把当前用户或者root用户添加进去:
~$ vim /etc/nginx/nginx.conf
然后在首行添加当前用户:
user your_user nginx;
然而这样存在一定的安全隐患。最安全的做法是把nginx用户添加到当前用户的附加群组中,然后修改相应文件的权限:
~$ usermod -a -G your_user nginx
~$ chmod 710 /home/your_user