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

在虚拟机中安装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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容