×

虚拟机中安装CentOS并通过nginx+uwsgi部署django应用

96
小明是个饭盒
2016.12.12 21:05* 字数 3049

在虚拟机中安装CentOS并通过nginx+uwsgi部署django应用

virtualbox的安装

首先搜索并下载deb包,注意下载本机对应的版本。这里推荐一下deb安装包的软件gdebi,安装及使用:

~$ sudo apt install gdebi
~$ gdebi package.deb

CentOS安装及配置

CentOS安装及网络配置

在bash中运行:

~$ virtualbox

在界面中点击新建

  1. 虚拟电脑名称和系统类型,输入名称,系统Linux,版本选择Red Hat;
  2. 内存大小,不要少于1G;
  3. 虚拟硬盘,建议创建
  4. 虚拟硬盘文件类型,默认的VDI即可;
  5. 存储在物理硬盘,根据需求选择容量,点击创建

点击显示,选择下载好的iso文件,点击启动,选择install即可安装。选择刚才分配的硬盘,进行新建用户、密码等操作,等待安装,完成后点击reboot重启进入系统。
为了实现主机对虚拟机的访问,需要修改网络类型为“桥接网卡(Bridged Adapter)”。(也可以选择Host-only Adapter模式,具体配置请自行搜索。)在进入系统之后如果无法上网,进入以下目录:

~$ /etc/sysconfig/network-scripts

然后修改ifcfg文件中的ONBOOT为yes即可。

更新及修改yum源

墙内访问yum源的速度很慢,我们来修改下yum源。这里直接用网易镜像站点中的配置文件。

  1. 进入yum配置文件目录

~$ cd /etc/yum.repos.d/

  1. 为防止出意外,先将原来的源文件备份

~$ mv CentOS-Base.repo CentOS-Base.repo.bak

  1. 下载163的配置

~$ wget http://mirrors.163.com/.help/CentOS7-Base-163.repo

  1. 改名

~$ mv CentOS6-Base-163.repo CentOS-Base.repo

  1. 更新数据库

~$ 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

日记本
Web note ad 1