Django项目部署经历(CentOS 7+Python3+Django2.0+Apache)

时间:2022-12-21 00:26:37

一、背景

      最近在学习Python和Django,并且把以前用java做过的一个后台管理系统改造成了Python3.6+Django2.0的版本,做完了当然是要把它部署到自己的服务器上才像样嘛!想到自己正好有个VPS服务器(用来VPN*的~~),这个服务器以前部署过java应用,所以mysql都已经安装好了的,省了好大一件事~~(Mysql安装详见我之前的博客阿里云服务器搭建经历),所以我们只需要搞好Django应用部署相关的东西就好啦。

二、安装相关软件

1、安装Python3

      由于我使用的服务器发行版本是CestOS7,其他Linux发行版本都是类似的安装模式,只是命令有稍微的区别而已,稍微百度一下就可以了。

      首先,我们要安装Python,一般Linux服务器都会有个默认的Python,我的VPS里面安装的是Python2.7,由于我使用的是Python3,所以需要重新安装,各位可以根据自己具体需求选择安装。安装Python也很简单,直接使用命令:

1 yum install python36u

     安装Python3完成后的shell命令为python3.6,为了使用方便,创建一个到python3的符号链接

1 sudo ln -s /bin/python3.6 /bin/python3

2、安装pip3

    Python3安装完成后并没有安装Python的包管理工具pip3,所以我们需要安装一下,直接使用命令安装:

1 yum install python36u-pip

    安装pip完成后的shell命令为pip3.6,为了使用方便,创建一个到pip3的符号链接

1 ln -s /bin/pip3.6 /bin/pip3

    如有提示pip版本过低,可以使用以下命令更新pip版本

1 pip3 install --upgrade pip

3、虚拟环境安装和使用

    直接使用命令安装虚拟环境

1 pip3 install virtualenv

    安装完成后,需要创建一个虚拟环境

1 virtualenv weiyaqi_env

    启动虚拟环境

1 source bin/activate

   退出虚拟环境

1 deactivate

   在虚拟环境将本项目需要的python包安装进去,使用命令生成requirements.txt

1 pip freeze > requirements.txt

   使用requirements.txt安装该虚拟环境所有需要的包

1 pip install -r requirements.txt

    其中有个包比较特殊,通过requirements.txt安装不了,需要特殊处理,那就是mysqlclient(会报GCC相关的错误),所以只能通过以下方式进行安装

1 yum install python36u python36u-devel
2 yum install gcc mariadb-devel
3 pip3 install mysqlclient

4、git安装与使用

   安装git也直接使用命令安装

1 yum install git

   安装完成后便可以克隆代码到服务器了

git clone https://github.com/xxx/xxProject.git

   如果代码有更新,可以使用命令拉取最新代码

1 git pull

5、Apache相关环境搭建

1 yum install httpd

   设置Apache服务开机自启动(可选,不过设置自启动方便)

1 /sbin/chkconfig httpd on

   启动Apache服务

1 /sbin/service httpd start

   安装httpd-devel

1 yum install -y httpd-devel

   安装mod__wsgi

1 wget https://codeload.github.com/GrahamDumpleton/mod_wsgi/tar.gz/4.6.4
2 tar zxvf 4.6.4
3 cd mod_wsgi-4.6.4
4 ./configure --with-apxs=/usr/bin/apxs --with-python=/usr/bin/python3.6
5 make
6 make install

     从github下载下来的文件是4.6.4,解压后就是mod_wsgi-4.6.4

     在apache配置文件最后追加一行

1 vim /etc/httpd/conf/httpd.conf
2 # 追加一行
3 LoadModule wsgi_module /usr/lib64/httpd/modules/mod_wsgi.so

    重启Apache服务

1 systemctl restart httpd

    清理编译后的源代码

1 make clean

    Apache配置应用相关配置(新建一个.conf文件)

1 cd /etc/httpd/conf.d/
2 vim weiyaqi.conf

    文件内容如下

 1 <VirtualHost *:80>
 2     WSGIScriptAlias /weiyaqi /home/pythonSources/content_manage/content_manage/wsgi.py
 3     WSGIDaemonProcess weiyaqi python-home=/home/weiyaqi_env python-path=/home/pythonSources/content_manage
 4     WSGIProcessGroup weiyaqi
 5 
 6     <Directory /home/pythonSources/content_manage/content_manage>
 7         <Files wsgi.py>
 8             Require all granted
 9         </Files>
10     </Directory>
11     # 开放静态目录
12     Alias /static/ /home/pythonSources/content_manage/static/
13     Alias /media/ /home/pythonSources/content_manage/media/
14     <Directory /home/pythonSources/content_manage/static>  #设置静态文件目录访问权限
15         Require all granted
16     </Directory>
17     <Directory /home/pythonSources/content_manage/media>   #设置媒体文件访问权限
18         Require all granted
19     </Directory>
20 </VirtualHost>

     重启Apache服务即可

     然而这样应用可以访问,但是很多静态文件都找不到,所以需要对静态文件进行收集到一个文件夹中,并且在该项目的.conf文件中指定这个收集到的静态文件夹。

     setting.py添加:

1 STATIC_ROOT = os.path.join(BASE_DIR, 'static_collected')

     进入到虚拟环境中对静态文件进行收集

1 python3.6 manage.py collectstatic

    修改apache配置中静态文件目录

 1 <VirtualHost *:80>
 2     WSGIScriptAlias /weiyaqi /home/pythonSources/content_manage/content_manage/wsgi.py
 3     WSGIDaemonProcess weiyaqi python-home=/home/weiyaqi_env python-path=/home/pythonSources/content_manage
 4     WSGIProcessGroup weiyaqi
 5 
 6     <Directory /home/pythonSources/content_manage/content_manage>
 7         <Files wsgi.py>
 8             Require all granted
 9         </Files>
10     </Directory>
11     # 开放静态目录
12     Alias /static/ /home/pythonSources/content_manage/static_collected/
13     Alias /media/ /home/pythonSources/content_manage/media/
14     <Directory /home/pythonSources/content_manage/static_collected>  #设置静态文件目录访问权限
15         Require all granted
16     </Directory>
17     <Directory /home/pythonSources/content_manage/media>   #设置媒体文件访问权限
18         Require all granted
19     </Directory>
20 </VirtualHost>

       另外,服务器可能会存在端口未开放的问题,可以在/var/log/httpd/error.log查看Apache的错误日志,通过修改iptables可以对部分端口进行开放,如果是阿里云的服务器,可以直接通过控制台修改(方法百度应该会有很多,这里就不再赘述了!)使用iptables设置端口访问

1 vim /etc/sysconfig/iptables
2 # 开放80端口
3 -A INPUT -p tcp --dport 80 -j ACCEPT

 

三、部署多个应用的问题

1、多个应用部署配置

      上面说到了,部署一个应用的时候,我们在配置里面新增了一个.conf的配置文件。所以,部署第二个应用的时候同样可以再新增一个.conf的配置文件,配置是类似的,只是在VirtualHost *:80这个地方后面跟的端口要配置的不一样,并且在Apache的主配置文件/etc/httpd/conf/httpd.conf中新添加一个监听端口,并且还需要在iptables配置中开放此端口

Django项目部署经历(CentOS 7+Python3+Django2.0+Apache)

2、两个应用同时登录的问题

      如果我们有两个django应用site1和site2同时跑在同一个server的不同端口,同时我们在同一个浏览器的不同tab登录。那么这时就出出现这种情况,当我们登录site2时就会将site1上登录的用户踢下来。为什么会出现这种情况呢?这跟django的session框架有关,这里做一个简单介绍:当我们第一次访问一个django网站时,django会生成一个session来保存当前会话的一些信息。同时会生成一个哈希值。

      为什么会出现这种情况呢?这跟django的session框架有关,这里做一个简单介绍:当我们第一次访问一个django网站时,django会生成一个session来保存当前会话的一些信息。同时会生成一个哈希值session_key并生成一个cookie发送给客户端,这个cookie的名字根据setting中SESSION_COOKIE_NAME设置,默认为“sessionid”(划重点)。这样下次请示session_key就会跟随cookie发送到server。server根据session_key查找对应session对象,获取当前会话的信息,当然也包括登录信息。我们登录site1是得到一个叫sessionid的cookie,里面存储session_key1。当我们登录site2时会更新那个叫sessionid的cookie,现在它的值为session_key2(浏览器存储cookies是基于ip而不是端口,所以会更新同一个名字的cookie)。

      所以现在用新的session_key访问site1时就会拿不到原来的登录信息,需要我们重新登录。那么怎么解决呢,了解上面机制后,只需要在setting中设置SESSION_COOKIE_NAME即可。比如可以在site2中设置SESSION_COOKIE_NAME = ‘site2’,site1中用默认。当然同时设置site1和site2。

3、安全问题

    在将Django应用部署到服务器上时,为了安全,最好是重新生成一个secret_key, 生成方式如下

1 from django.core.management import utils
2 utils.get_random_secret_key()

    啊!码字好累,自己都感觉好乱,希望大家能够看懂~~~