社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

Django搭建个人博客:将项目部署到服务器

杜赛_dusai • 5 年前 • 500 次点击  
阅读 12

Django搭建个人博客:将项目部署到服务器

我们的博客虽然还有很多不完善的地方,但是没关系,越早把它部署到互联网上,才能越早发现线上特有的问题。现在也提倡渐进式开发,让产品在迭代中快速成长。

部署考验的不是你的 Django 编程水平,而是你对 Linux 的操作能力,以及对网络通信的理解。多说无益,直接开干!

配置服务器

要架设网站,首先你要有一台连接到互联网的服务器。国内比较出名的云服务器属阿里云腾讯云百度云,三家各有优劣,大家自行了解比较,并选择自己适合的购买。

利益相关:博主自己用的是阿里云,所以教程会以阿里云ECS作为例子讲解。新用户通过推广链接注册有折扣和现金券(目前是20元);学生有优惠服务器每月9.5元,性能还不错,很划算。如果你想用其他云服务器,操作流程也差不多,不必担心。

首先进入阿里云ECS的购买页面

图片字很小,看不清楚的同学将就一下放大看吧。

挑重点说一下:

  • 实例从入门级里选一款便宜的,以后流量高了再升级也不迟(土豪请无视这条)。
  • 镜像选择 Ubuntu 16.04 64位。其他 Linux 版本也是可以的。
  • 系统盘先选个 20G,够你用一阵了。数据盘暂时用不上,不用勾选。

点击下一步,来到网络和安全组页面:

这页默认就行了,公网带宽选最低的 1M ,初期够用了。

点击下一步,到系统配置页面:

为了后面远程连接服务器更简单,这里勾选自定义密码,也就是输入用户/密码的认证方式了。实际上秘钥对的认证方式更安全些,以后摸熟了再改回来吧。

点击下一步,到分组设置页面。这个页面全部默认设置就好了。点击下一步,确认订单无误后,就可以付款啦。

付款成功后,通过控制台就可以看到已购买的云服务器了:

这里有时候会有黄字提醒你服务器的网络端口没开,点击黄字链接去开通一下:

把 22(远程连接端口)、443(HTTPS端口)、80(HTTP端口)都打开,3389端口顺便也开了。

至此服务器的购买、配置就完成啦。稍等几分钟后等待初始化完成,就可以得到服务器的公网 IP 地址,博主的是 118.31.35.48 ,后面会用到。

接下来就是正式的部署。

正式部署

开发时我们用的是 Django 自带的开发服务器,但那个性能太差了,不可能用到线上环境。所以线上部署时,我们不仅要安装 Django,还要安装 NginxGunicorn,这三兄弟的工作流程如下:

  • 客户端发来 http 请求,Nginx 作为直接对外的服务器接口,对 http 请求进行分析
  • 如果是静态资源请求,则由Nginx自己处理(效率极高)
  • 如果是动态资源请求,则把它转发给 Gunicorn
  • Gunicorn 对请求进行预处理后,转发给 Django,最终完成资源的返回

如果用餐馆来做比喻的话,Nginx 就是迎宾小姐,客人如果点了酒水,迎宾小姐自己就帮忙拿了;而 Gunicorn 是传菜员,Django 是厨师,他两一起满足客人对现炒美食的需求。

远程连接

部署的第一步就是想办法连接到云服务器上去,否则一切都免谈。鉴于项目是在 Windows 环境开发的,推荐用 XShell 来作为远程连接的工具,非常的好用。XShell 有学校及家庭版本,填一下姓名和邮箱就可以免费使用了。千万别嫌麻烦去下载来路不明的“绿色版”、“纯净版”,万一有木马你哭都哭不出来了。

XShell 怎么使用就不赘述了,以读者的聪明才智,稍微查阅一下就明白了。

使用相当简单,基本就是把主机 IP、端口号(22)以及登录验证填好就能连接了。

连接成功后,就能在 XShell 窗口中看到阿里云的欢迎字样了:

Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-151-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

Welcome to Alibaba Cloud Elastic Compute Service !

root@dusaiphoto:~$ 
复制代码

root@dusaiphoto:~$是命令提示符,输入命令时不需要你输入这个。本文后面把 root@dusaiphoto:字符省略掉,方便大家阅读。

代码部署

为了防止系统太旧引起的各种麻烦,先升级一下库的版本:

~$ sudo apt-get update
~$ sudo apt-get upgrade
复制代码

完成之后,接着安装需要的几个包:

~$ sudo apt-get install nginx
~$ sudo apt-get install python3
~$ sudo apt-get install python3-pip
~$ sudo apt-get install git
~$ sudo pip3 install virtualenv
复制代码

分别安装了 nginxpython3pipgitvirtualenv。其中 python3 和 pip3 的写法是因为阿里云自带了 Python2.7,把它们区分一下。之前开发时虚拟环境用的 python 自带的,为了避免读者的版本不同造成的各类错误,稳妥起见用 virtualenv 库来创建虚拟环境,操作步骤都是差不多的。

接下来就是要改一下 Django 的配置文件 settings.py

my_blog/settings.py

# 关闭调试模式
DEBUG = False

# 允许的服务器
ALLOWED_HOSTS = ['*']

# 静态文件收集目录
STATIC_ROOT = os.path.join(BASE_DIR, 'collected_static')
复制代码
  • 部署时要关闭调试模式,避免安全性问题(此时 Django 就不再处理静态资源了)。
  • ALLOWED_HOSTS指明了允许访问的服务器名称或 IP,星号表示允许所有的请求。实际部署时请改成你的域名或 IP,比如ALLOWED_HOSTS = ['.dusaiphoto.com', '127.0.0.1']
  • 项目中有很多静态文件,部署时需要找一个地方统一收集起来,也就是STATIC_ROOT指定的地址了。

因为项目代码需要通过 GitHub 仓库进行下载(就像本教程的示例代码一样),因此修改完毕后需要把代码上传到 GitHub。怎么上传这里也不赘述了,博主之前写过一篇《Win 10 连接 GitHub》的文章,有需要的读者稍微读一下。

需要注意的是,虚拟环境一般是需要在服务器上重新生成的,因此我们需要把开发中用到的库列一个清单,以便在服务器上统一安装。在本地虚拟环境中输入:

pip freeze > requirements.txt
复制代码

项目中就多了个 requirements.txt 文件,里面记录了项目需要的库的清单。

教程为了演示,上传了媒体资源和数据库,实际开发时可千万不要上传。

然后更新 Git 记录并上传到 GitHub。重新回到服务器的命令行,给项目代码创建目录并进入此目录:

~$ mkdir -p /home/sites/dusaiphoto.com
~$ cd /home/sites/dusaiphoto.com
复制代码

目录位置是随便你的,但建议找个地方统一管理所有的网站项目。

然后从 GitHub 中拉取项目代码:

../dusaiphoto.com$ git clone https://github.com/stacklens/django_blog_tutorial.git
复制代码

这里拉取的博客教程的代码。建议读者先拉取教程代码来测试,成功之后再重新部署自己的代码。完成之后可以输入 ls 指令,看看代码文件夹是否正常生成了。

接着在服务器生成虚拟环境:

../dusaiphoto.com$ virtualenv --python=python3.5 env
../dusaiphoto.com$ source env/bin/activate
(env) ../dusaiphoto.com$ 
复制代码

这里用 virtualenv 生成并激活了虚拟环境。python 版本选择 3.5 还是 3.7 都可以,区别并不大。

接下来就是安装库、收集静态资源、数据迁移了:

(env) ../dusaiphoto.com$ cd


    
 django_blog_tutorial
(env) ../django_blog_tutorial$ pip3 install -r requirements.txt
(env) ../django_blog_tutorial$ python3 manage.py collectstatic
(env) ../django_blog_tutorial$ python3 manage.py migrate
复制代码

代码部署基本就完成了,接下来配置 Nginx

Nginx

前面我们安装了 Nginx ,先来试试安装是否正常。启动 nginx 服务:

(env) ~$ sudo service nginx start
复制代码

打开浏览器,输入你的服务器公网 IP 地址

Nginx 欢迎界面出现了,神奇吧。但这个默认配置显然是不能用的,所以需要重新写 Nginx 的配置文件。进入 /etc/nginx/sites-available 目录,这里是定义 Nginx 可用配置的地方。输入指令 sudo vi dusaiphoto.com 创建配置文件并打开 vi 编辑器

(env) ~$ cd /etc/nginx/sites-available
(env) /etc/nginx/sites-available$ 
(env) /etc/nginx/sites-available$ sudo vi dusaiphoto.com
复制代码

关于 vi 编辑器如何使用也不赘述了,这里只说两个最基本的操作:

  • i 键切换到编辑模式,这时候才可以进行输入、删除、修改等操作
  • Ctrl + c 退回到命令模式,然后输入 :wq + Enter 保存文件修改并退回到服务器命令行

回到正题,用 vidusaiphoto.com 文件中写入:

server {
  charset utf-8;
  listen 80;
  server_name 118.31.35.48;  # 改成你的 IP

  location /static {
    alias /home/sites/dusaiphoto.com/django_blog_tutorial/collected_static;
  }
  
  location /media {
    alias /home/sites/dusaiphoto.com/django_blog_tutorial/media;
  }

  location / {
    proxy_set_header Host $host;
    proxy_pass http://unix:/tmp/118.31.35.48.socket;  # 改成你的 IP
  }
}
复制代码

此配置会监听 80 端口(通常 http 请求的端口),监听的 IP 地址写你自己的服务器公网 IP

配置中有3个规则:

  • 如果请求 static 路径则由 Nginx 转发到目录中寻找静态资源
  • 如果请求 media 路径则由 Nginx 转发到目录中寻找媒体资源
  • 其他请求则交给 Django 处理

如果你已经申请好域名了,就把配置中有 IP 的地方都修改为域名,比如:server_name www.dusaiphoto.com;

写好后就退出 vi 编辑器,回到命令行。因为我们写的只是 Nginx 的可用配置,所以还需要把这个配置文件链接到在用配置上去:

(env) ../sites-available$ sudo ln -s /etc/nginx/sites-available/dusaiphoto.com /etc/nginx/sites-enabled
复制代码

至此 Nginx 就配置好了,接下来搞定 Gunicorn

有的读者无论怎么配置都只能看到 Nginx 欢迎页面,有可能是 sites-enabled 目录中的 default 文件覆盖了你写的配置。将 default 文件删掉就可以正常代理自己的配置文件了。

Gunicorn及测试

先回到项目所在的目录,并且进入虚拟环境,然后输入:

(env) ../django_blog_tutorial$ pip3 install gunicorn
(env) ../django_blog_tutorial$ sudo service nginx reload
(env) ../django_blog_tutorial$ gunicorn --bind unix:/tmp/118.31.35.48.socket my_blog.wsgi:application
复制代码

这里的三个步骤分别是:

  • 安装 Gunicorn
  • 重启 Nginx 服务
  • 启动 Gunicorn

启动 Gunicorn 也是一样,如果你已经有域名了,就把套接字中的 IP 地址换成域名;wsgi 字眼前面是项目的名称。另外 sudo service nginx reload 可替换成 sudo service nginx restart,区别是 reload 只重载配置文件,restart 重启整个服务。

接下来用浏览器访问服务器试一下:

大功告成啦,撒花庆祝!

后续工作

遗留问题

成功部署到线上后,还有些小问题没解决。

第一个问题是进入文章详情页面, ckeditor 无法加载了,并且浏览器报出 prism_patched.js Not Found的错误。这个问题的根源在于之前我们在开发 ckeditor 的代码高亮功能时,prism 模块是直接插入到虚拟环境的库中的,但问题是部署时虚拟环境是需要重新建立的,所以就缺少了这个 prism 插件导致报错。

解决办法也很简单,在虚拟环境中找到 prism 插件的位置:

..\env\Lib\site-packages\ckeditor\static\ckeditor\ckeditor\plugins\prism
复制代码

然后把它原封不动的复制到项目的 static 中完全相同的目录中去:

my_blog\static\ckeditor\ckeditor\plugins\prism
复制代码

这样做行得通的原因是 django-ckeditor 也是一个 app,Django 访问 app 资源时会优先在项目中搜索,没有才去虚拟环境里搜索。

然后就是通过 GitHub 更新服务器代码,并且重新收集静态文件:

(env) ../django_blog_tutorial$ git pull origin master
(env) ../django_blog_tutorial$ python3 manage.py collectstatic
复制代码

这个问题给我们的启示就是:针对三方库、资源的改动最好不要直接修改源文件或环境,而是想办法在项目副本中更改,这样更便于维护。

有读者发现旧的富文本评论中的表情没显示,这个别担心,新发表的评论是没问题的。

第二个问题是 GitHub 登录不正常了,这个多半不是代码的问题,而是你的服务器以及 GitHub 的回调配置问题。这里也不展开讲了,请读者返回前面第三方登录的文章再研究下。

第三个问题是开发阶段用的 sqlite 数据库虽然很方便,但是性能较差。线上以性能为王,所以需要将数据库更换为 MYSQL 这类主流的高性能数据库。远程安装配置 MYSQL 的方法可以参考一下刘江的博客,讲得很清楚。

第四个问题是教程部署是以 root 用户进行的,这是服务器中具有最高权限的用户,除掉自身的瞎操作,一旦被攻击者登录了会相当惨烈(尤其是用户/密码的登录方式,安全系数极低)。比较好的方式是重新创建一个普通用户来进行部署,并且将登录方式改为秘钥对。

后期运维

你的网站是需要不断更新优化代码的。每次修改代码后,更新到服务器上也很简单。在虚拟环境中并进入项目目录,依次(collectstatic 和 migrate 是可选的)执行以下命令:

git pull origin master
python3 manage.py collectstatic
python3 manage.py migrate
# 重启 gunicorn
pkill gunicorn
gunicorn --bind unix:/tmp/118.31.35.48.socket my_blog.wsgi:application
复制代码

加上 cd 更改目录的指令,部署过程有十几条指令,手动输入也太麻烦了。简单粗暴的办法是利用 XShell 的宏,把部署指令写成顺序执行的脚本,点几个按钮就完成了,非常方便。

更高级的做法是在服务器上编写自动化部署的脚本,这个就读者以后慢慢研究吧

如果你更改了 Nginx 的配置文件,还需要重启 Nginx 服务:

sudo service nginx reload
复制代码

最后,还记得前面章节开发的日志记录功能不?看看项目中有 logs 目录吗?

域名及优化

相对部署来说,域名配置就很容易了。阿里云提供域名的购买、备案(顶级域名必须,约10个工作日)、解析服务,简直全家桶有没有。重点提醒有了域名之后要改的地方:

  • settings.py 中的 ALLOWED_HOSTS
  • Nginx 中与 IP/域名 有关的位置
  • Gunicorn 中与 IP/域名 有关的位置

域名搞定之后,接着就可以着手考虑把网站升级为 https 版本了,这是大趋势,一定要做。(这个也留给读者自己折腾)

另外,开发时为了效率把所有静态资源都下载到本地,但是部署时不推荐这样做,原因是静态文件通常体积都较大,你花血汗钱买的服务器载入会很慢。尽量远程 CDN 调用,像这样:

<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
复制代码

国内推荐BootCDN,速度快还免费。

媒体资源也是类似,小图还无所谓,大图就要放在七牛云这类的对象存储云上,否则你网页的载入速度会很悲剧的。

最后再次提醒,在开发时我们往 settings.py 中写入如 SECRET_KEY 、邮箱密码等各种敏感信息,部署时千万不要直接上传到互联网(GitHub 库是公开的!),而是把这些信息写到服务器本地,然后在 settings.py 中读取。

总结

部署可以说是入门者最大的难关了,也是检验成果、获取成就感的关键一步。多查资料,要相信你遇到的问题别人早就遇到过了。

部署是菜鸟的毕业礼,也是新人的第一课。

路漫漫其修远兮,吾将上下而求索。


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/43780
 
500 次点击