由于第一次尝试将python的Django项目部署到服务器上,采用较为简单的Apache服务器,由于网络上的信息良莠不齐,也遇到了不少坑,因此记录如下,以供大家参考。
Refer to: Django2:Web项目开发入门笔记(13)
环境搭建的内容包括:
操作系统:Ubuntu16.04 (在Linux系统中可以使用命令sudo lsb_release -a查询)
Web服务器:Apache2.4(在Linux系统中可以使用命令apachectl -v查询)
解释器:Python3.6
框架:Django3.0.5 (在Linux系统中可以使用命令python3 -m django --version查询)
虽然网络上已经有不少参考教程,但或者过时或者缺漏,或者情况不尽相同,导致遇到不少坑,前前后后搞了两三天才终于调通。特此记录下一些心得与经验供有需要的同进参考。
接下来,我们分三个步骤来完成Django的部署:
由于我用的是空闲的电脑,因此直接在电脑上安装Linux系统,使用的是启动盘安装。制作启动盘的方法网上颇多,而且较为简单,在此不赘述。
在Ubuntu系统下打开命令行,输入如下命令:
sudo apt-get install openssh-server
sudo service sshd start
启动SSH服务后,我们就可以通过自己的电脑远程登录服务器了。在此,土豪可以选择Xshell更为方便快捷,对于一般用户,可以下载安装putty进行登录,如下图所示,在Host Name中输入Linux电脑的IP地址,点击Open按钮进行登录。
我们后面再需要使用到的Python3.6-dev并不在已集成的程序中,所以我们需要添加软件更新源的地址。
执行命令:
sudo vi /etc/apt/sources.list
此时会在命令行终端通过vi编辑器打开文件“sources.list”,我们按“i”键(注意别按多了)进入编辑模式,在文件的开始我们添加一行软件源的地址:deb http://cz.archive.ubuntu.com/ubuntu bionic main
添加完毕后,按“ESC”键退出编辑模式,然后输入“:wq”(屏幕左下角会出现输入的内容)保存退出。
接着,同步一下更新源:
sudo apt-get update
sudo apt install openssl
sudo apt install libssl.dev
sudo apt install zlib*
注意1:
如果不安装“openssl”和“libssl.dev”,在线安装一些第三方库(例如Django)时,“https://”开头的下载地址无法连接,提示“SSL”相关的错误。
如果不安装“zlib*”,在安装之后的一些软件包时,软件包中的一些文件无法解压释放,导致安装失败。
注意2:
如果不先安装Sqlite3,而是先安装Python3.6,会导致找不到“_sqlite3”模块的错误。
sudo apt install sqlite3
sudo apt install libsqlite3-dev
如果不安装Sqlite3的依赖包“libsqlite3-dev”,在Python代码中导入“sqlite3”模块,会出现错误“ModuleNotFoundError: No module named ‘_sqlite3’”。特别注意软件包名称是“libsqlite3-dev”不是“libsqlite-dev”,后者也能安装,但不支持Python3.6。
sudo apt install apache2
sudo apt install apache2-dev
注意3:
如果不安装Apache2的依赖包“apache2-dev”,后面安装“mod_wsgi”时会出现“apxs: not found”的错误。
首先,下载Python3.6的安装包(这里是Python-3.6.5.tgz),使用软件WinSCP上传到Ubuntu系统的/home/ubuntu/Downloads/目录中。
下载路径:python3.6.5
在打开的网页中,找到如下内容,可以点击下图中任意一个链接下载。
执行如下命令进行解压:
cd /home/test/Downloads/
sudo tar xfz Python-3.6.5.tgz
释放完成后,进入解压后的文件夹。
执行命令:
cd /home/test/Downloads/Python-3.6.5
首先,进行安装配置。
执行命令:
sudo ./configure --enable-shared --with-ssl=openssl
注意4:
此命令后面的参数一定要带上,如果不带“–enable-shared”参数,将导致“mod_wsgi”安装失败,如果不带“–with-ssl=openssl”,会导致使用pip命令在线安装下载地址为“https://”开头的第三方库时,无法连接的错误(SSL错误)。
然后,创建安装文件。
执行命令:
sudo make
注意5:
如果之前已经进行过安装过程,这里可能会提示错误,可以通过执行“sudo make clean”先清空之前的安装残留,再执行“sudo make”命令。
最后,开始执行安装。
执行命令:
sudo make install
接下来,安装依赖。
执行命令:
sudo apt install python3.6-dev
注意6:
如果没有安装这个依赖,下一步安装“mod_wdgi”,会出现“src/server/wsgi_python.h:24:20: fatal error: Python.h: No such file or directory”的错误。
注意7:
不能用pip命令安装mod_wdgi,wsgi会连接系统默认的python2.7。
下载安装包mod_wsgi-4.7.1.tar.gz,这个版本支持Python3.6,解压后进入文件夹。
下载路径:mod_wsgi-4.7.1
在打开的页面中点击Download files进行下载,同样使用软件WinSCP上传到Ubuntu系统的/home/test/Downloads/目录中。
执行命令:
cd /home/test/Downloads/mod_wsgi-4.7.1
然后,进行安装配置。
执行命令:
sudo ./configure --with-python=python3.6
注意8:
如果不加参数“–with-python=python3.6”,后果就是wsgi会连接系统默认的python2.7,导致错误,错误提示中有“include python2.7”的内容。这是最大的一个坑,网上很难查到资料,我是尝试使用“./configure --with-python3.6”产生的帮助提示中找到的答案。
接下来,创建安装文件并进行安装。
执行命令:
sudo make
sudo make install
注意9:
可以使用pip命令安装。
但是不能直接执行pip命令,因为系统中自带Python2.7和Python3.5分别占用了“python”和“python3”这两个命令,如果想给Python3.6安装Django(也只有Python3.6才能装Django2),必须先进入Python3.6的“site-packages”目录。
执行命令:
cd /usr/local/lib/python3.6/site-packages/
sudo pip3 install django
注意10:
pytz是Django的依赖,在执行Django的安装时也会自动在线安装,但是有可能导致安装停止。此时需要先安装pytz。
最后,我们做一下测试,看一下是否一切正常。
执行命令:
python3.6
import django
import sqlite3
如果没有任何错误出现,我们就完成了所需软件包的安装。
接下来,我们通过命令先给文件夹/var/www赋予可读写的权限。
执行命令:
sudo chmod 777 /var/www
然后,通过WinSCP将项目文件夹以及里面的内容上传到/var/www这个文件夹中。
接着,在创建配置文件之前,有个非常重要的步骤需要先进行。即测试一下拷贝到服务器上的项目是否能够正常运行。
输入如下命令:
cd /var/www/xx # xx为你的项目文件夹名字
python manage.py runserver
通常情况下项目能够正常跑起来,但有时候会出现一些module not found的错误,此时需要进入/var/local/lib/python3.6文件夹下使用命令sudo pip3 install xxx安装对应模块。
注意11:
如果No module named ‘captcha.fields’
这个错误不能安装 captcha
而是这样解决:
sudo pip3 install django-simple-captcha
执行命令:
sudo vi /etc/apache2/sites-available/xx.conf
xx为你的项目名
配置文件极为重要,一个项目能否部署成功,配置文件占了90%。
在vi编辑器中写入配置文件内容:
<VirtualHost *:80>
ServerAdmin webmaster@localhost # 这个邮箱不重要
WSGIScriptAlias / /var/www/MMTestCarManagement/MMTestCarManagement/wsgi.py # 这是项目的wsgi.py的绝对路径,非常重要,是apache链接django项目的纽带
Alias /login/media/image/ /var/www/MMTestCarManagement/login/media/image/ # 这是项目的media文件绝对路径,非常重要
Alias /static/ /var/www/MMTestCarManagement/static/ # 这是项目的静态文件绝对路径,非常重要
<Directory /var/www/MMTestCarManagement/login/media/image>
Require all granted
</Directory>
<Directory /var/www/MMTestCarManagement>
Require all granted
</Directory>
<Directory /var/www/MMTestCarManagement/static>
Require all granted
</Directory>
<Directory /var/www/MMTestCarManagement/MMTestCarManagement>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log # 这是错误日志,出现问题时可以查看问题所在,非常重要,一般在/var/log/apache2/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
完成编辑后,按“ESC”键退出编辑模式,并输入“:wq”后按回车键保存退出。
接下来,我们添加“wsgi.load”文件。
执行命令:
sudo vi /etc/apache2/mods-available/wsgi.load
在vi编辑器中,我们添加如下内容:
LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so
添加完毕之后,我们保存退出。
然后,打开/etc/apache2/mods-available/文件夹,使用如下命令创建wsgi.load文件的桌面快捷方式:
ln -s /etc/apache2/mods-available/wsgi.load /home/test/Desktop
回到命令行,我们把这个快捷方式放入/etc/apache2/mods-enabled/文件夹中。
执行命令:
cd /home/ubuntu/Desktop
sudo mv wsgi.load /etc/apache2/mods-enabled/wsgi.load
完成快捷方式的创建,接下来,我们让配置文件生效。
在目录/var/www/中默认有一个html文件夹,里面有一个文件“index.html”。
此时,我们通过域名或者ip地址访问站点,能够看到打开的是“Apache2 Ubuntu Default Page”这个页面,也就是“index.html”的文件内容。
那么,如何让我们的项目能够访问呢?
在/etc/apache2/sites-available/文件夹中包含了一个名为“000-default.conf”的配置文件,就是这个文件在起作用,所以访问时打开了“html”文件夹中的页面。
我们需要让我们刚刚添加的配置文件生效,并且禁用默认的配置文件。
执行命令:
sudo service apache2 reload
sudo a2dissite 000-default.conf && sudo a2ensite xx.conf
然后,在项目目录下执行python命令:
python manage.py collectstatic
最后,执行如下命令:
sudo service apache2 start
执行完上述命令,我们就可以在浏览器输入服务器的IP地址进行访问啦。
此时可能遇到一些问题,例如 attempt to write a readonly database
这说明sqlite3所在的文件夹没有读写权限,或者权限不足,可以进入项目文件夹下,输入如下命令:
chmod 777 db.sqlite3
如有其它问题,请参考如下路径:
Django部署的方法和常见的问题