我们的相册虽然还有不完善的地方,但是没关系,越早把它部署到互联网上,才能越早发现线上特有的问题,让产品在迭代中成长。
注意:以下流程经过笔者验证,能够保证顺利部署项目。如果你不知道每一步都是干嘛的,那么请严格按照文章的流程顺序操作。
配置服务器
要架设网站,首先你要有一台连接到互联网的服务器。国内比较出名的云服务器有阿里云、腾讯云、百度云,三家各有优劣,大家自行了解比较,并选择自己适合的购买。
和前章一样,笔者用的是阿里云全家桶,所以教程会以阿里云ECS作为例子讲解。新用户通过此阿里云ECS推广链接注册有折扣和现金券;学生有优惠服务器每月9.5元,很划算。
阿里云服务器购买页面变动频繁,如果图中展示的步骤和你购买时的不一样也没关系,核心步骤都是差不多,稍微找一下就OK了。
首先进入阿里云ECS的购买页面:
图片字很小,看不清楚的同学将就一下放大看吧。
挑重点说一下:
- 实例从入门级里选一款便宜的(比如2核2G的),以后流量高了再升级也不迟(土豪请无视这条)。
- 镜像选择 Ubuntu 。其他 Linux 版本也是可以的,根据你的使用习惯确定。
- 系统盘先选个 20G,够你用一阵了。数据盘暂时用不上,不用勾选。
点击下一步,来到网络和安全组页面:
这页默认就行了,公网带宽选最低的 1M ,初期够用了。
如果有询问是否购买公网 IP 的选项,记得勾上。没公网 IP 就没办法连接到互联网了。
点击下一步,到系统配置页面:
为了后面远程连接服务器更简单,这里勾选自定义密码,也就是输入用户/密码的认证方式了。实际上秘钥对的认证方式更安全些,以后摸熟了再改回来吧。
点击下一步,到分组设置页面。这个页面全部默认设置就好了。点击下一步,确认订单无误后,就可以付款啦。
付款成功后,通过控制台就可以看到已购买的云服务器了:
这里有时候会有黄字提醒你服务器的网络端口没开,点击黄字链接进入安全组规则选项卡开通一下:
把 22(远程连接端口)、443(HTTPS端口)、80(HTTP端口)都打开,3389端口顺便也开了。
这一步很重要,如果不打开后续会始终连接不上站点。如果没有黄字提醒,那就一定要到安全组中确认端口已打开。
至此服务器的购买、配置就完成啦。稍等几分钟后等待初始化完成,就可以得到服务器的公网 IP 地址,笔者的是 47.104.227.185 ,后面会用到。
准备工作
在正式部署前,还有些准备工作需要做。
修改后端配置
首先 Django 的配置要更改为线上状态:
# /album/settings.py
...
# 修改项。关闭调试模式
# 关闭后 django 不再处理静态资源
# 也不再提供错误提示页面
DEBUG = False
# 修改项。允许所有的IP访问网络服务
ALLOWED_HOSTS = ['*']
# 新增项。静态文件收集目录
STATIC_ROOT = os.path.join(BASE_DIR, 'collected_static')
然后在虚拟环境中执行:
(env)> pip freeze > requirements.txt
将后端所有的依赖库记录到 requirements.txt 中。
代码上传Github
将项目代码拷贝到云服务器的方式有几种。比较方便的是上传到 Github ,再由 Github 将项目代码下载到服务器。因此你需要把项目上传到 Github。
Github 经常会速度很慢或无法登录。这时候你也可以尝试用国内的 Gitee,或者直接点对点本地上传服务器。
如何上传这里就不细讲了,请自行学习 Git 相关知识,注册 Github 账号等。
需要提醒的是,所有依赖的库都不需要上传,比如 env 目录,它们可以在服务器中很方便地安装。
这就是前面生成的 requirements.txt 的作用。
接下来就是正式部署了。
远程连接
部署的第一步就是想办法连接到云服务器上去,否则一切都免谈。鉴于项目是在 Windows 环境开发的,推荐用 XShell 来作为远程连接的工具。XShell 有学校及家庭版本,填一下姓名和邮箱就可以免费使用了。
XShell 怎么使用就不赘述了,以读者的聪明才智,稍微查阅一下就明白了。
使用相当简单,基本就是把主机 IP、端口号(22)以及登录验证填好就能连接了。
连接成功后,就能在 XShell 窗口中看到阿里云的欢迎字样了:
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-77-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@dusai:~$
root@dusai:~$是命令提示符(root 是用户名,dusai 是主机名),输入命令时不需要你输入这个。
本文后面把 root@dusai:字符省略掉,方便大家阅读。
安装项目及依赖
接下来的部署指令均在服务器中执行,也就是在 XShell 中操作,别搞混了。
首先更新系统库:
~$ apt-get update
~$ apt-get upgrade
部署到正式环境时,后端服务器就不能用 Django 自带的开发服务器了(性能低下),而是改用 Nginx + Gunicorn + Django 配合提供网络服务:
- 客户端发来 http 请求,Nginx 作为直接对外的接口,对 http 请求进行分析;
- 如果是静态资源请求,则由Nginx自己处理(效率极高);
- 如果是动态资源请求,则把它转发给 Gunicorn 进行预处理后,再转发给 Django,最终完成资源的返回。
除此之外,还要确保 Python3 、Git 和 virtualenv 也都正确安装。
顺序执行以下指令:
~$ apt-get install nginx
~$ apt-get install python3.8
~$ apt-get install python3-pip
~$ apt-get install git
~$ pip3 install virtualenv
均成功后,创建并跳转到项目目录:
~$ mkdir -p /home/sites/album
~$ cd /home/sites/album
# 进入的路径如下所示
/home/sites/album$
接下来就可以从 Github 下载项目了:
# 以教程仓库为例 django-vue-tutorial
../album$ git clone https://github.com/stacklens/django-album-tutorial.git
这里就以教程的仓库为例,读者用自己项目时一定要注意路径名称正确。
如果你是从非公开项目下载,用户名密码的认证方式 Github 已经准备废弃了。如遇报错请以密钥认证的形式下载。
下载好项目后,在同级路径创建并进入虚拟环境:
../album$ virtualenv --python=3.8 venv
../album$ source venv/bin/activate
# 看到 (venv) 开头就对了
(venv) ../album$
进入项目目录,安装依赖、收集静态资源并迁移数据库:
# 这里的 django-album-tutorial 路径是从 Github 拉取下来的项目路径
# 记得改成你自己的
(venv) ../album$ cd django-album-tutorial
(venv) ../django-album-tutorial$ pip3 install -r requirements.txt
(venv) ../django-album-tutorial$ python3 manage.py collectstatic
(venv) ../django-album-tutorial$ python3 manage.py migrate
最后启动 nginx:
# 为了阅读方便,后续命令行均省略 $ 前面的路径部分
(venv) ~$ service nginx start
在浏览器中访问你的云服务器的公网 IP ,看看效果:
看到 Nginx 的欢迎页面则成功一半了。继续。
配置nginx
Nginx 欢迎界面这个默认配置显然是不能用的,所以需要重新写 Nginx 的配置文件。
/etc/nginx/sites-available 目录是定义 Nginx 可用配置的地方。输入指令创建配置文件 myblog 并打开 vim 编辑器:
(venv) ~$ vim /etc/nginx/sites-available/album
关于 vim 编辑器如何使用也不多说了,这里只说两个最基本的操作:
- 按 i 键切换到编辑模式,这时候才可以进行输入、删除、修改等操作
- 按 Ctrl + c 退回到命令模式,然后输入 :wq + Enter 保存文件修改并退回到服务器命令行
回到正题,用 vim 在 album 文件中写入:
server {
charset utf-8;
listen 80;
server_name 47.104.227.185; # 改成你的 IP
location /static {
# 这里的 django-album-tutorial 路径是从 Github 拉取下来的项目路径
# 记得改成你自己的
alias /home/sites/album/django-album-tutorial/collected_static;
}
location /media {
# 这里的 django-album-tutorial 路径是从 Github 拉取下来的项目路径
# 记得改成你自己的
alias /home/sites/album/django-album-tutorial/media;
}
location / {
proxy_set_header Host $host;
proxy_pass http://unix:/tmp/47.104.227.185.socket; # 改成你的 IP
}
}
此配置会监听 80 端口(通常 http 请求的端口),监听的 IP 地址写你自己的服务器公网 IP。
配置中有两个核心规则:
- 如果请求静态资源,则直接转发到对应目录中寻找
- 其他请求则转发给 Gunicorn(再转交给 Django)
如果你已经申请好域名了,就把配置中有 IP 的地方都修改为域名,比如:server_name www.dusaiphoto.com。
写好后就退出 vim 编辑器,回到命令行。因为我们写的只是 Nginx 的可用配置,所以还需要把这个配置文件链接到在用配置上去:
(venv) ~$ ln -s /etc/nginx/sites-available/album /etc/nginx/sites-enabled
测试下 nginx 配置是否正常:
(venv) ~$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
至此 Nginx 就配置好了,接下来搞定 Gunicorn。
有的读者无论怎么配置都只能看到 Nginx 欢迎页面,有可能是 sites-enabled 目录中的 default 文件覆盖了你写的配置。将 default 文件删掉就可以正常代理自己的配置文件了。
Gunicorn及测试
Nginx 搞定后就只剩 Gunicorn 了。
下面的三条命令分别是安装 Gunicorn 、 重启 Nginx 和 启动 Gunicorn:
(venv) ~$ pip3 install gunicorn
(venv) ~$ service nginx restart
# 将 IP 改为你的公网 IP
# .wsgi 前面为 Django 配置文件所在的目录名
(venv) ~$ gunicorn --bind unix:/tmp/47.104.227.185.socket album.wsgi:application
# Gunicorn 成功启动后命令行提示如下
[2021-07-29 15:09:22 +0800] [11945] [INFO] Starting gunicorn 20.1.0
[2021-07-29 15:09:22 +0800] [11945] [INFO] Listening at: unix:/tmp/47.104.227.185.socket (11945)
[2021-07-29 15:09:22 +0800] [11945] [INFO] Using worker: sync
[2021-07-29 15:09:22 +0800] [11947] [INFO] Booting worker with pid: 11947
Gunicorn 就启动成功了。(注意启动时命令行所在的路径)
接下来用浏览器访问试试:
大功告成,撒花庆祝!
此时你就可以对比本地存储和 OSS 存储的巨大鸿沟了。
收尾工作
后期运维
你的网站是需要不断更新优化代码的。每次修改代码后,更新到服务器上也很简单。在虚拟环境中并进入项目目录,依次(collectstatic 和 migrate 是可选的)执行以下命令:
git pull
python3 manage.py collectstatic
python3 manage.py migrate
# 重启 gunicorn
pkill gunicorn
gunicorn --bind unix:/tmp/47.104.227.185.socket my_blog.wsgi:application
加上 cd 更改目录的指令,部署过程有十几条指令,手动输入也太麻烦了。简单粗暴的办法是利用 XShell 的宏,把部署指令写成顺序执行的脚本,点几个按钮就完成了,非常方便。
更高级的做法是在服务器上编写自动化部署的脚本,这个就读者以后慢慢研究吧。
如果你更改了 Nginx 的配置文件,还需要重启 Nginx 服务:
service nginx restart
域名及优化
相对部署来说,域名配置就很容易了,各家云服务商都有此业务。
有了域名之后要改的地方:
- Nginx 中与 IP/域名 有关的位置
- Gunicorn 中与 IP/域名 有关的位置
域名搞定之后,接着就可以着手考虑把网站升级为 https 版本了。
最后,在开发时我们往 settings.py 中写入如 SECRET_KEY 、邮箱密码等各种敏感信息,部署时千万不要直接上传到公开仓库,而是把这些信息写到服务器本地,然后在 settings.py 中读取。
进程托管
部署过程中还有个新手经常碰到的问题,就是当 SSH 终端一关闭,Web 服务也一起被关闭了,导致网站无法连接。这个问题在 @frostming 的文章 《Web 服务的进程托管》 中用了三种常见方法解决了,并且还实现了异常重启和开机自启动。有类似疑惑的同学可以前往围观。
总结
部署可以说是入门者最大的难关了,也是检验成果、获取成就感的关键一步。
多查资料,要相信你遇到的问题别人早就遇到过了。
路漫漫其修远兮,吾将上下而求索。