图片 2

CentOS 7 + Apache + mod_wsgi 部署Django项目

至此,大功告成,我们直接可以通过80端口访问我们的项目,虽然上面的步骤简单,但是网上查的资料并没有特别详细完整的,中间还是走了不少的弯路,所以特意将配置步骤记录下来,方便后续再次配置!

 

安装完成之后,mod_wsgi.so会在Apache的modules目录中

1. 安装Django

Linux上我们可以直接使用pip安装Django

 

1.1  安装python(使用CentOS
7.5自带的python即可)

[root@localhost ~]# python --version
Python 2.7.5

 

1.2 
网上下载get-pip.py文件安装pip:

wget https://bootstrap.pypa.io/get-pip.py

 

1.3  pip安装django

[root@localhost ~]# pip install django
[root@localhost ~]# python
Python 2.7.5 (default, Jul 13 2018, 13:06:57)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django.get_version()
'1.11.14'

 

#服务器根目录ServerRoot "/etc/httpd"#端口#Listen 12.34.56.78:80Listen 80#域名+端口来标识服务器,没有域名用ip也可以#ServerName www.example.com:80#不许访问根目录<Directory /> AllowOverride none Require all denied</Directory># 文档目录DocumentRoot "/var/www/html"# 对 /var/www目录访问限制<Directory "/var/www"> AllowOverride None # Allow open access: Require all granted</Directory># 对/var/www/html目录访问限制<Directory "/var/www/html"> Options Indexes FollowSymLinks AllowOverride None Require all granted</Directory># 默认编码AddDefaultCharset UTF-8#EnableMMAP offEnableSendfile on# include进来其它配置文件IncludeOptional conf.d/*.conf

 

本文将介绍如何在Linux上部署Django + Mysql + Apache环境。我们知道,Django内置的http服务器只能工作在单线程下,做开发和调试时候是可以的,但是生产环境通常都会有多用户并发,而且django的simple HTTP server处理大量静态文件的性能太差,所以要用apache做前端。Django自带的SQLite数据库权限只依赖于文件系统,没有用户帐户的概念,这里我们使用典型的关系型数据库Mysql。看似简单的环境搭建,在实际操作过程中还是遇到了不少的大坑,所以特地将过程记录下来,也希望对大家有小小的帮助。

CentOS 7.5  +  python 2.7.5  + Django 1.11.14  +  Apache 2.4.6  +  Mysql 5.7.23

  • 启动Apache服务

 

项目根目录中新建wsgi文件夹,在wsgi文件夹中新建文件 django.wsgi

3. 安装Mysql

我们使用yum安装Mysql,需要先更新yum源

 

[root@localhost ~]# wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm
[root@localhost ~]# rpm -ivh mysql57-community-release-el7-8.noarch.rpm
[root@localhost ~]# yum install mysql-community-server
[root@localhost ~]# yum install mysql-community-devel

 

注意:yum安装的Mysql其文件目录如下

  • 配置文件:/etc/my.cnf
  • 日志文件:/var/log/mysqld.log
  • 服务启动脚本:/usr/lib/systemd/system/mysqld.service
  • socket文件:/var/run/mysqld/mysqld.pid

 

主配置文件是/etc/httpd/conf/httpd.conf其他配置文件存储在/etc/httpd/conf.d/目录

4. 配置(重点)

以上三步都非常容易,但是将这三个环境配置好,还是费了我不少的时间…

4.1  配置Mysql

 

[root@localhost ~]# systemctl start mysqld
# 开启Mysql服务后,会为root设置一个默认密码,我们首先重置密码
# 获得默认密码
[root@localhost ~]# cat /var/log/mysqld.log | grep -i password
[root@localhost ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.23 MySQL Community Server (GPL)

mysql>ALTER USER 'root'@'localhost' IDENTIFIED BY 'Sam_tech_0912';

# 重置密码后,我们创建一个数据库,因为后续django连接Mysql时需要输入数据库名称
mysql> create database Platform default charset=utf8;
Query OK, 1 row affected (0.00 sec)

mysql> quit
Bye

  

4.2  django中配置Mysql

 

django中关于Mysql的配置:

DATABASES = {
    'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'Platform',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'USER': 'root',
        'PASSWORD': 'Sam_tech_0912',
    }
}

 

django中其他的部分的配置:

DEBUG = True

ALLOWED_HOSTS = ["*",]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates"),],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = True

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]

MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

补充:

关于 Error loading MySQLdb module: No module named MySQLdb

–> yum install MySQL-python

 

4.3  配置Apache

 

重点:安装mod_wsgi

[root@localhost ~]# yum install mod_wsgi
[root@localhost ~]# rpm -qa | grep wsgi
mod_wsgi-3.4-12.el7_0.x86_64

 

编辑配置文件 /etc/httpd/conf/httpd.conf

ServerRoot "/etc/httpd"

# 设定Apache监听的端口号,可以设定多个
Listen 80

# 重点:这句是加载刚刚安装的wsgi模块,有了它django才能部署到Apache上,切记!!!
LoadModule wsgi_module modules/mod_wsgi.so


Include conf.modules.d/*.conf

User apache
Group apache

ServerAdmin root@localhost

ServerName localhost:80

<Directory />
    AllowOverride none
    Require all denied
</Directory>

    DocumentRoot "/var/www/html"

<Directory "/var/www">
    AllowOverride None
    Require all granted
</Directory>

<Directory "/var/www/html">
    Options Indexes FollowSymLinks

    AllowOverride None

    Require all granted
</Directory>

<IfModule dir_module>
    DirectoryIndex index.html
</IfModule>

<Files ".ht*">
    Require all denied
</Files>

ErrorLog "logs/error_log"

LogLevel warn

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>

    CustomLog "logs/access_log" combined
</IfModule>

<IfModule alias_module>

    ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

</IfModule>

<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options None
    Require all granted
</Directory>

<IfModule mime_module>
    TypesConfig /etc/mime.types

    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz



    AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml
</IfModule>

AddDefaultCharset UTF-8

<IfModule mime_magic_module>
    MIMEMagicFile conf/magic
</IfModule>


EnableSendfile on

IncludeOptional conf.d/*.conf

# 我们在/etc/httpd/conf/下新建httpd-vhosts.conf虚拟主机配置文件,完成对80端口的配置
# 这句是告诉Apache去调用httpd-vhosts.conf
# 虚拟主机中的配置参数将覆盖httpd.conf主配置文件中的设定
Include conf/httpd-vhosts.conf

 

虚拟主机配置文件(关键一步

<VirtualHost *:80>
    ServerAdmin samliuming@aliyun.com
    DocumentRoot "/home/python_projects/Platform"
    ServerName samlinux01-platform.com
    ServerAlias sam-platform.com
    ErrorLog "logs/platform_error.log"
    CustomLog "logs/platform_access.log" common


    WSGIScriptAlias / "/home/python_projects/Platform/Platform/wsgi.py"
    # 一定要定义python-path到项目目录,否则会报出相关模块无法找到的错误,切记!!!
    WSGIDaemonProcess samlinux01-platform.com python-path=/home/python_projects/Platform:/usr/lib64/python2.7/site-packages
    WSGIProcessGroup samlinux01-platform.com
    WSGIScriptReloading On

    # 设定Apache访问django的项目目录

    Alias /static /home/python_projects/Platform/static
    Alias /media /home/python_projects/Platform/media
  # 注意:将python中django admin的静态文件链接到static目录下,否则会出现登录django admin静态文件404的问题
  # ln -s /usr/lib64/python2.7/site-packages/django/contrib/admin/static/admin admin


    <Directory /home/python_projects/Platform/media>
        AllowOverride None
        Options Indexes FollowSymLinks
        Require all granted
    </Directory>
    <Directory /home/python_projects/Platform/static>
        AllowOverride None
        Options Indexes FollowSymLinks
        Require all granted
    </Directory>
    <Directory /home/python_projects/Platform/Platform>
        <Files wsgi.py>
            AllowOverride None
            Require all granted
        </Files>
    </Directory>
</VirtualHost>

注意:每次编辑完成后都需要重启httpd服务使配置生效

[root@localhost ~]# httpd -t
[Thu Aug 16 20:35:06.439115 2018] [so:warn] [pid 1520] AH01574: module wsgi_module is already loaded, skipping
Syntax OK
[root@localhost ~]# systemctl restart httpd.service

 

编辑django中的 wsgi.py文件

"""
WSGI config for Platform project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Platform.settings")

application = get_wsgi_application()

# 添加项目路径到python的环境变量中
# For Apache server
import sys
project_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, project_dir)

 

在httpd.conf中添加目录权限,否则会报错:Apache: access denied because
search permissions are missing

2. 安装Apache

Linux上使用yum安装Apache即可

[root@localhost ~]# yum install httpd
[root@localhost ~]# httpd -V
[Thu Aug 16 20:57:04.487586 2018] [so:warn] [pid 1605] AH01574: module wsgi_module is already loaded, skipping
Server version: Apache/2.4.6 (CentOS)
Server built:   Jun 27 2018 13:48:59
Server's Module Magic Number: 20120211:24
Server loaded:  APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture:   64-bit
Server MPM:     prefork
  threaded:     no
    forked:     yes (variable process count)

注意:使用yum安装的httpd,其安装目录位于/etc/httpd/,我们只需要配置/etc/httpd/conf/httpd.conf即可

 

访问本机的80端口:http://localhost出现以下界面说明安装成功(apache端口被我更改过成81)

安装使用Apache作为应用代理服务器

下一步改进方法

import osimport sysfrom django.core.wsgi import get_wsgi_application# Add this file path to sys.path in order to import settingssys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath), '..'))os.environ['DJANGO_SETTINGS_MODULE'] = 'projectname.settings'sys.stdout = sys.stderrDEBUG = Trueapplication = get_wsgi_application()
  • 在httpd.conf中添加一行
  • 设置Apache服务开机自启动(可选,不过设置自启动方便)
LoadModule wsgi_module modules/mod_wsgi.so
# python>>> import django>>> django.VERSION(1,9,7,'final',0)

<VirtualHost 192.168.10.81:80>ServerAdmin rocdk890@gmail.comdirectoryIndex index.html index.php index.htm index.shtml login.phpServerName 192.168.10.81DocumentRoot /var/www/vhosts/wwwroot<Directory "/var/www/vhosts/wwwroot"> Options -Indexes AllowOverride All Require all granted</Directory></VirtualHost>

  • 安装mod__wsgi

图片 1访问Apache服务

变动地方主要有:

设置项目目录访问权限

使用mod_wsgi拓展作为Django的应用容器

使用Docker技术,把Django部署环境制作成镜像,然后在生产服务器上安装Docker环境,项目的更新直接更新镜像即可,了解Docker技术到https://www.gitbook.com/book/yeasy/docker\_practice/details,生产环境使用镜像的部署方式,就可以避免环境重复部署的问题,而且很多服务器使用的CentOS版本还是6.x,然后自带的python版本较低,升级python版本又比较麻烦,Docker在生产环境已经在广泛应用了。

# yum install httpd
  • 在httpd.conf文件中添加以下内容

安装Django

如:WSGIScriptAlias /python /usr/local/testProject/wsgi/django.wsgi

系统环境

  • Apache服务的配置说明

该配置用来连接django.wsgi,使工程被Apache加载

Apache2.2.x的配置文件(IP地址以192.168.10.81为例)

  • 配置需要注意的点
WSGIScriptAlias /python "/path/to/docRoot/django.wsgi" 
  • 验证Django安装是否完成

Apache2.4.x的配置文件

主配置文件内容为:

# yum install python-devel# yum install mysql-devel# pip install MySQL-python
  • 首先安装httpd-devel
<VirtualHost 192.168.10.81:80>ServerAdmin rocdk890@gmail.comdirectoryIndex index.html index.php index.htm index.shtml login.phpServerName 192.168.10.81DocumentRoot /var/www/vhosts/wwwroot<Directory "/var/www/vhosts/wwwroot"> Options -Indexes AllowOverride All Order allow,deny Allow from all</Directory></VirtualHost>

# wget https://bootstrap.pypa.io/get-pip.py# python get-pip.py

必须配置项目路径到系统路径中,因为要通过项目路径找到settings.py配置文件。也就是sys.path.insert(0,
os.path.join(os.path……巴拉巴拉,DJANGO_SETTINGS_MODULE必须指向项目的settings.py文件,projectname指的就是项目的名称。修改了wsgi的配置后必须重启httpd服务。

# /sbin/service httpd start
# yum install -y httpd-devel
# wget https://www.djangoproject.com/m/releases/1.9/Django-1.9.7.tar.gz# cd Django-1.9.7/# python setup.py install

图片 2部署完成之后访问项目

网上有很多这种方式部署的博客,可是细致讲的并没有发现,而且很多方式都已经比较陈旧,所以自己用比较新的环境配置了一番,中间遇到的一些问题都有详细描述,希望有同学受益。

# yum install mod_wsgi

安装pip

在Apache中配置wsgi

<Directory "/usr/local/testProject"> AllowOverride All Require all granted</Directory>
  • 系统:CentOS 7 x64
  • Python版本:2.7.5
  • Apache版本:2.4.6
  • Django版本:1.9.7
  • pip版本:8.1.2(官网get-pip.py方式安装)
  • 安装Apache

最后访问项目的效果(之前做的一个小项目哈,表介意界面)

删除了 Order deny,allow 和 Order allow,deny把 Deny from all 替换成了 Require all denied把Allow from all 替换成了 Require all granted然后还把 Allow from 192.168.10.21 这样的语句给替换成了 Require host 192.168.10.21

注意:对于1.3和1.4及之后的版本,此文件的代码内容是不同的,详情区别参考
http://django.readthedocs.io/en/latest/releases/1.7.html\#standalone-scripts

# /sbin/chkconfig httpd on

配置wsgi时,

  • 验证安装
  • django.wsgi文件内容如下:

安装MySQLdb模块

Apache2.2.x版本和Apache2.4.x版本对于Directory标签中的配置方式并不一样,如果配置方式错误会导致
client denied by server configuration错误