【绝对详细!不好使你顺着网线敲我!】Django3.1在Ubuntu16.04上的部署

前言

转眼间Django版本更新已经到了3.1.7,在使用Django3.1时,使用以往版本的Django部署方法进行部署时许多已经都不起作用,但也能搜索到许多有帮助的技术性文章。于是特将整个部署过程整理于此以供参考。

部署架构

目前依旧流行的Python3.7配合 uWSGI + Nginx + 阿里云的Ubuntu 16.04 + Django3.1 +Mysql 5.7.33

辅助工具

Pycharm 2020.1.3 专业版 + XShell6 + Xftp6

总体流程

Created with Raphaël 2.3.0 开始 安装python 安装并配置nginx 创建一个虚拟环境 在虚拟环境下? 安装并配置uWSGI 安装Django以及相应的python模块 结束 yes no

零、准备工作

购买服务器(雾)、使用xshell成功连接上服务器,新建一个/data文件夹用以存放项目的相关文件,方便后续管理。建议使用命令

$ sudo apt-get update #更新获取软件源提供的软件列表;
$ sudo apt-get upgrade #更新软件;

预备一下。

一、安装Python

安装Python时推荐进入Python官网下载Python源码进行安装,在这个网址里找到你想要的Python版本
在这里插入图片描述
本文以Python3.7.5为例,选择第一个链接进行下载,下载完之后会得到一个**.tgz**文件,使用xftp6将文件上传到/data文件夹内。也可以在/data目录下直接输入命令
wget https://www.python.org/ftp/python/3.7.5/Python-3.7.5.tgz将文件直接下到/data目录下。
执行tar -zxvf Python-3.7.5.tgz解压文件,解压完毕后进入Python-3.7.5/目录中,执行./configure -perfix=/usr/local这里通过指定prefix参数为/usr/local将python3.7.5的安装文件全集中在这个目录下,方便我们以后的删除和修改。如果安装时遇到问题,可以尝试以下命令,之后再切回到Python目录下执行./configure -perfix=/usr/local

$ apt-get update  #更新软件源
$ apt install build-essential bzip2 gcc libbz2-1.0 libbz2-dev libc6-dev libdb-dev libexpat1 libexpat1-dev libffi-dev libgdbm-dev libgdbm3 liblzma-dev libncurses5-dev libncursesw5-dev libpcap-dev libreadline-dev libreadline5 libreadline6 libreadline6-dev libsqlite0 libsqlite0-dev libsqlite3-0 libsqlite3-dev libssl-dev libssl1.0.0 libxml2-dev libxslt1-dev make openssl python-dev python-pip python-setuptools python-smbus python3-dev sqlite sqlite3 tcl tk tk-dev uuid-dev xz-utils zlib1g zlib1g-dev #安装依赖软件

安装完成后会出现
在这里插入图片描述
此时直接执行make && make install,编译时间一般会很长,可以趁此机会做一些其他事情
在这里插入图片描述
如果出现上图类似结果表明安装完成,可以尝试使用下列命令进行检测

$ python3 --version
$ pip3 --version

在这里插入图片描述

也可以使用命令/usr/local/bin/python3进行检测
在这里插入图片描述
至此Python3.7.5的安装过程就结束了
注意:在安装高版本的python3时不要删除ubuntu中原先存在的python3的软连接,否则后续会出问题!

二、安装Mysql

在现行的linux开发版上,大部分都使用了MariaDB以代替MySQL,所以这里使用了MySQL5.7。
如果使用的是阿里云的服务器的话首先需要打开3306这一端口,再进行后续操作。
使用命令

$ sudo apt-get install mysql-server
$ sudo apt install mysql-client
$ sudo apt install libmysqlclient-dev

进行安装,安装完成后输入一下命令进行检验

sudo netstat -tap | grep mysql

出现如下图就代表安装成功
在这里插入图片描述
注:如果在安装过程中没有提示让你设置密码的吗,在安装成功后可以参考下面博客进行修改。
Ubuntu安装mysql后无初始密码解决方法

(可跳过)安装好之后设置mysql的远程连接,使用命令

$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

进入配置文件注释掉bind-address = 127.0.0.1之后保存退出
这一步之后进入MySQL

$ mysql -uroot -p密码

在这里插入图片描述
在MySQL命令行界面下输入命令

mysql> GRANT ALL PRIVILEGES ON *.* TO  'root'@'%'  IDENTIFIED BY  '你的密码'  WITH GRANT OPTION;

在这里以我使用的密码为root为例
在这里插入图片描述
完成之后使用命令flush privileges;刷新配置命名,使用exit命令退出MySQL服务。
最后在ubuntu命令行内执行命令service mysql restart重启mysql
重启之后可以使用Navicat进行检验,在新建连接中
在这里插入图片描述
在对应位置分别填入服务器的IP地址,数据库用户名和密码,点击连接测试,若出现连接成功则证明配置成功。

三、将工程文件上传到服务器

由于我使用的是Pycharm进行项目的编写,所以在上传方面就比较方便,如果不是使用Pycharm进行编写的话,就需要按照你的项目部署清单收集全部的静态文件和媒体文件,将DEBUG设置为False之后将项目上传到服务器上(比如把所有文件打包扔到虚拟机之后再解包23333)。
这里以Pycharm为主进行项目文件的上传。
首先在/data目录下新建一个存放项目文件的目录
在这里插入图片描述
完成之后在Pycharm的Terminal中输入pip freeze > requirements.txt得到当前开发项目的包的信息,方便后续在服务器上安装相关的Python模块。
在这里插入图片描述
在Pycharm中进入如图中所示的界面
在这里插入图片描述
在弹出的窗口中创建一个新的连接
在这里插入图片描述

命名时可以随意命名,之后填入要连接的Host和要连接的用户和密码之后测试连接,若连接成功则可以使用
在这里插入图片描述
在这里插入图片描述
接着在Deployment这个窗口上填写项目的root path(自己设置)和web server URL(一般为服务器的公网ip地址)
在这里插入图片描述
接着点击Mappings,在这里设置项目部署相关的目录映射,如果在前一页设置了Root path的话这里的Deployment path选择的就是在Root path下的目录。点击右侧的小文件夹符号选择,这里我选择的就是开头新建的mywebsite目录
在这里插入图片描述
配置完之后点击OK结束配置,如果之前选择了下图所示的Automatic Upload按钮的话,当前面一系列配置都配置完成了之后,Pycharm会自动向服务器中上传项目文件,同时选择这一按钮的话,之后再主机的Pycharm进行的任何修改都会自动上传到服务器上(只要服务器处于工作状态)。
在这里插入图片描述
如果没有选择的话,就需要先选择项目的根目录,再在右击之后弹出的选项框中选择Deployment标签中的Upload to…(这个快捷键太反人类了于是就没按,当然使用快捷键更方便)
在这里插入图片描述
在弹出的窗口中选择刚刚设置好的要上传的服务器,点击之后就可以观察到,pycharm为我们自动收集了静态文件和媒体文件并且向服务器上进行了上传,简直是非常省心啊。
在这里插入图片描述
在这里插入图片描述
传送完毕后进入/mywebsite目录,使用ls -l命令就可以查看到所有的项目文件。
在这里插入图片描述

四、安装Nginx

由于Ubuntu默认源里面的Nginx版本比较旧,需要先添加一个Nginx的源,再通过apt-get安装Nginx。使用下列命令

$ sudo add-apt-repository ppa:nginx/stable
$ apt-get update
$ apt-get install nginx

进行Nginx的安装。
注意:如果之前删除了ubuntu中原先的Python软连接,那么此时运行第一条命令的时候会出错,这样的话就只能从头开始安装了
安装完成后使用命令/etc/init.d/nginx start启动nginx,在虚拟机下部署的话可能会出现错误
在这里插入图片描述
这是因为已经有一个绑定到HTTP端口80的进程。可以运行命令sudo lsof -i:80以使用该端口获取进程列表,然后停止/禁用Web服务器。
在这里插入图片描述
使用命令sudo fuser k 80 / tcp来停止上述进程,此时可能会出现xshell断开的现象,重新连接即可。
在这里插入图片描述
上述问题只在虚拟机中出现,在云服务器上还未发现。
再次使用nginx服务开启的命令,此时可以发现开启成功
在这里插入图片描述
使用service --status-all命令进行查看,安装好并启动服务之后,nginx旁边会出现一个+号
在这里插入图片描述
此时可以在主机上的浏览器访问虚拟机或云服务器的IP地址,如果出现下面的界面,说明Nginx服务正常
在这里插入图片描述

怎么是apache2……
在这里插入图片描述
nginx的主场居然跑出来一个apache……这就是安装虚拟机的时候把增值服务全部选择的结果吗……
执行下列命令

$ sudo apt-get --purge remove apache2
$ sudo apt-get --purge remove apache2-common
$ sudo apt-get --purge remove apache2-utils
$ sudo apt-get autoremove apache2
--purge 是不保留配置文件的意思

删掉/etc/apache2文件夹:
sudo rm -rf /etc/apache2

删掉/var/www文件夹:
sudo rm -rf /var/www

删掉/etc/init.d/apache2文件:
sudo rm -rf /etc/init.d/apache2

删除掉上述文件之后修改nginx的配置文件
vim /etc/nginx/sites-available/default
把图中标出的那一行注释掉
在这里插入图片描述
再一次访问服务器ip
在这里插入图片描述
出现上述画面说明配置成功

五、创建虚拟环境

这里要解释一下为什么要使用虚拟环境。
前文我们在安装Python3.7.5的时候也提到,ubuntu自带的Python3是3.5版本,同时ubuntu内还自带有一个Python2,。那么我们在使用Python进行开发时,就不可避免的会在Python环境这方面犯难:我究竟是处在Python3.5还是Python3.7还是Python2呢?同样的,当我们使用pip工具时也是如此。此时,虚拟环境就可以帮我们解决这个问题。使用虚拟环境可以为每一个项目建立一套独立的,与服务器环境相隔离的python运行环境,每一个项目在创建的出的一个虚拟环境中运行,使用虚拟环境就可以帮我们解决Python环境管理混乱的问题啦!。
在Python3.4之前,若要使用Python的虚拟环境需要独立手动安装一个virtualenv模块才能执行。在之后的版本中,Python自带了一个venv库,执行Python -m venv就可以达到与virtalenv相同的结果。
这里方便起见暂时不使用virtalenv这一方法
在命令行输入命令

$ python3 -m venv /data/myvenv

即可在/data目录新建一个名为/myvenv的虚拟环境目录。
之后进入/data/myvenv/bin目录,输入命令

$ source activate

当命令行前部出现(myvenv)时证明进入了虚拟环境
在这里插入图片描述
输入python3或python,可以看到,在虚拟环境中我们使用的python版本正是我们需要的版本
在这里插入图片描述

六、在虚拟环境下安装uWSGI

uWSGI是一个快速的、自我驱动的、对开发者和系统管理员友好的应用容器服务器,完全由C编写。

这里的安装参考了此博客的安装部分,简单描述如下
为了避免如上述博客中提到的配置方法不同从而导致踩坑,我选择了与博客中提到的相同的uwsgi版本进行安装。在虚拟环境中的/data目录下输入命令

注意!注意!如果你使用了虚拟环境,那么你必须使用虚拟环境的Python解释器安装uWSGI!!!在这里我们的Django代码使用的是虚拟环境中Python解释器,所以uWSGI也必须在该环境中进行安装!!!

$ wget  https://projects.unbit.it/downloads/uwsgi-2.0.14.tar.gz
$ tar -zxvf uwsgi-2.0.14.tar.gz
$ cd uwsgi-2.0.14
$ sudo python3 setup.py install

命令结束后进行检测
在这里插入图片描述
这里虽然运行出错了,但至少表明此时uWSGI在系统可执行目录中。

七、最后的配置

0、Django项目相关Python模块的安装

首先进入虚拟环境中,在虚拟环境下进入项目,这里是/data/mywebsite目录,在命令行中输入pip install -r requirements.txt进行项目相关Python模块的安装。
在这里插入图片描述
在这里插入图片描述

1、Django项目文件的配置
  • 修改settings.py文件

修改项目的settings.py文件,将DEBUG改为False,ALLOWED_HOSTS修改为**’或者’自己的ip地址或希望访问的IP地址’**,使用’'更加方便
在这里插入图片描述
如果使用的是MySQL数据库的话,就需要在settings.py文件中进行设置
在这里插入图片描述
进入项目的根目录,修改__init__.py文件如下:

import pymysql
pymysql.install_as_MySQLdb()

这样修改是为了保证在ubuntu上能够正常的使用MySQL,否则在最终运行时可能会出错。

2、MySQL数据库的设置

打开MySQL,在数据库中新建一个你要使用的数据库,这里由于我使用的数据库名为test于是新建了一个test数据库。
在这里插入图片描述

3、配置uWSGI

在项目文件中与manage.py文件同名的目录下,新建一个uwsgi.ini文件。文件名可根据自己喜好取,但后缀必须是imi

由于我与参考博客中选择的uwsgi版本相同,于是配置内容也大致相同,这里在引用参考博客内容的基础上增加了自己的一些想法。

[uwsgi]
chdir = /data/mywebsite    //项目根目录
module = web_project.wsgi:application     //  指定wsgi模块下的application对象
socket = 127.0.0.1:8000         //对本机8000端口提供服务
master = true                   //主进程

# 以上4个是核心配置项

#vhost = true          //多站模式
#no-site = true        //多站模式时不设置入口模块和文件
#workers = 2           //子进程数
#reload-mercy = 10
#vacuum = true         //退出、重启时清理文件
#max-requests = 1000
#limit-as = 512
#buffer-size = 30000
#pidfile = /var/run/uwsgi9090.pid    //pid文件,用于下脚本启动、停止该进程
daemonize = /data/mywebsite/run.log    // 日志文件
disable-logging = true   //不记录正常信息,只记录错误信息
static-map = /static=/data/mywebsite/static  //指定静态文件的目录

详细说明:

  • 配置项中以‘#’开头的都是被注释的项目,不起作用;
  • 以双斜杠开头,表示注释;
  • chdir是你的项目根目录。我这里的项目名叫for_test;
  • moudule是你的入口wsgi模块,将for_test替换成你的项目名称;
  • socket是通信端口设置,和我一样就行;
  • master=True表示以主进程模式运行;
  • demonize是你的日志文件,会自动建立
  • disable-logging = true 表示不记录正常信息,只记录错误信息。否则你的日志可能很快就爆满了。
  • env: 指定DJANGO_SETTINGS_MODULE的值
  • home:可选的项目虚拟环境路径

也可以通过命令行参数的方式,不过就显得复杂而不可修改了

uwsgi --chdir=/path/to/your/project \
    --module=mysite.wsgi:application \
    --env DJANGO_SETTINGS_MODULE=mysite.settings \
    --master --pidfile=/tmp/project-master.pid \
    --socket=127.0.0.1:49152 \      # can also be a file
    --processes=5 \                 # number of worker processes
    --uid=1000 --gid=2000 \         # if root, uwsgi can drop privileges
    --harakiri=20 \                 # respawn processes taking more than 20 seconds
    --max-requests=5000 \           # respawn processes after serving 5000 requests
    --vacuum \                      # clear environment on exit
    --home=/path/to/virtual/env \   # optional path to a virtual environment
    --daemonize=/var/log/uwsgi/yourproject.log      # background the process
4、配置Nginx

建议备份一下/etc/nginx/sites-available文件夹内的default文件,然后再编辑
在这里插入图片描述

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#
server {
	listen 80 default_server;
	listen [::]:80 default_server;

	# SSL configuration
	#
	# listen 443 ssl default_server;
	# listen [::]:443 ssl default_server;
	#
	# Note: You should disable gzip for SSL traffic.
	# See: https://bugs.debian.org/773332
	#
	# Read up on ssl_ciphers to ensure a secure configuration.
	# See: https://bugs.debian.org/765782
	#
	# Self signed certs generated by the ssl-cert package
	# Don't use them in a production server!
	#
	# include snippets/snakeoil.conf;

#	注释掉这里root /var/www/html;

	# Add index.php to the list if you are using PHP
#	注释掉这里index index.html index.htm index.nginx-debian.html;

	server_name 192.168.154.136;# 更改为你的服务器ip

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		# try_files $uri $uri/ =404;
		include uwsgi_params;
		uwsgi_pass 127.0.0.1:8000; # 和uwsgi中配置的socket要相同
	}
	location /static {
		alias /data/mywebsite/static; # 项目的静态文件目录
	}
	# pass PHP scripts to FastCGI server
	#
	#location ~ \.php$ {
	#	include snippets/fastcgi-php.conf;
	#
	#	# With php-fpm (or other unix sockets):
	#	fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
	#	# With php-cgi (or other tcp sockets):
	#	fastcgi_pass 127.0.0.1:9000;
	#}

	# deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	#
	#location ~ /\.ht {
	#	deny all;
	#}
}


# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
#	listen 80;
#	listen [::]:80;
#
#	server_name example.com;
#
#	root /var/www/example.com;
#	index index.html;
#
#	location / {
#		try_files $uri $uri/ =404;
#	}
#}

请将server_name改成你的实际IP。include uwsgi_params一定要一样。uwsgi_pass和你uWSGI配置中的socket要一样。location /staticalias改成你的实际情况,让静态文件得以部署。

修改完毕后,保存退出,然后重启nginx服务

sudo service nginx restart

八、在服务器上启动项目

经过了上述的配置,我们已经可以尝试在服务器上启动项目了,但是先别急,在启动之前先在项目根目录下使用命令python manage.py runserver尝试启动一下以免使用uwsgi启动时启动出错。
在这里插入图片描述
我在虚拟机的虚拟环境(禁止套娃!)下使用该条命令进行启动发现了两处错误

  • 没有进行数据迁移
  • 8000端口被占用(虚拟机怎么一直都有端口被占用…)
    首先解决端口占用问题,使用命令lsof -i:8000查看被占用的端口。我一看,原来是昨天,有两个uwsgi进程忘记关掉了……
    在这里插入图片描述
    使用命令killall -9 uwsgi关掉uwsgi进程之后使用命令python manage.py migration进行数据库迁移
    在这里插入图片描述
    进行完毕后再次使用命令python manage.py runserver启动服务器
    在这里插入图片描述
    这之后使用命令uwsgi uwsgi.ini启动uwsgi服务
    系统提示:
    [uWSGI] getting INI configuration from uwsgi.ini
    到浏览器中访问:
    在这里插入图片描述
    已经成功访问了!
    但是显而易见的,页面非常的杂乱无章。这是因为使用的静态文件并没有成功加载出来的原因。
    我们关闭掉uwsgi,在项目根目录输入并执行命令
$ python manage.py collectstatic

收集一下静态文件,再重新启动uwsgi服务。此时我们在浏览器中访问
在这里插入图片描述
此时我们可以看到静态文件也已经加载出来啦!
至此一个完整的项目已经成功部署到了服务器了。

九、参考文章与结语

由于在部署Django时寻找了大量参考博客,此博客也可以说是一个总结性的内容,故在此将在写作时的一部分参考内容粘贴于此,感谢他们与无形之中对我的帮助。

最后,也欢迎大家多多尝试,如果在部署过程中遇到问题可以随时私信本人哦~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值