部署网站到服务器

写在前面

FirstWeb 中的 Web 框架,是基于 farbox_lite 这个库的,这个库对应的比较临时,不足以作为生产的环境来跑。虽然真要跑起来,问题应该也不是很大,基本的性能已做了调优处理。
farbox_lite 是 FarBox/Bitcron 的简化版,有不少局限性,未来没有什么特殊情况,我应该会另外提供一个 Web 端的平台,数据直接同步过来就可以完成网站的部署,就不用自己处理服务器了。

课程接下来的内容,我们会去控制服务器,它是命令行形式的,所以我们需要在 Mac 上先打开两个命令行窗口,也就是 Terminal.app,你可以在 启动台 里搜索 Terminal,中文翻译为 终端

两个命令行窗口,一个连接服务器,我们后续会说 在服务端操作,就是在这个窗口内操作;如果是 在客户端操作,就是另外一个窗口了。
如果说 执行下面的命令,且是多行的,就一行一行、逐行复制、粘贴、回车键,进行执行。
本篇的内容,我们将不过多解释为什么,就按照步骤一步步走下来即可。

服务器是什么

服务器主要两种类型: VPS 和 独立服务器,VPS 相当独立服务器上分割出来的。
一般情况下,特别对于入门者而言,VPS 就已经足够了。
准备一台 VPS,可以到 Vultr 或者 Linnode 上购买最低配置的,如果已经有了的,请确保是 KVM 结构的,而不是 OpenVZ。
VPS 从某种角度来说,就是一个云端, VultrLinnode 都可以按小时计费,如果尝试之后,并不需要长时间运行的,请自行删除服务器,避免产生不必要的账单。

非常重要的地方: 创建 VPS (服务器) 的时候,务必选择 Ubuntu 操作系统,操作系统的版本为 16.04 ,且是 64 位的。

注意: VPS 的 IP 可能会被阻断,不言而喻的现象,删除 VPS 再重建,试到可用为之。

登录服务器

在其中一个命令行窗口中输入:

ssh root@123.123.123.123

root 是服务器上的用户名,123.123.123.123 是服务器的 IP,这些自行替换。
这个过程中可能需要输入登录服务器 root 账户的密码。

一般建议服务器上使用 SSH Key 实现登录,免得密码被别人爆破了,可以搜索 Mac ssh 免密 远程登录 进一步了解、尝试,反正服务器弄坏了,重新安装一下就好了。

使用 root 权限

为了方便期间,后面运行的脚本,应该是在 root 权限下的,最简单的方法,就是使用 root 这个账户运行命令。
如果 VPS 是刚刚创建,并且没有 root 密码的,可以运行 sudo passwd root 对 root 设定密码;在 root 密码已知的前提下,可以运行 su,然后键入密码,切换到 root 的运行环境。

注意: 直接使用 root,理论上是不符合 Linux 的安全策略,但胜在方便,所以,请务必确保不要在重要的服务器环境中这样处理。

准备部署环境

在服务端的窗口中,执行下面的命令:

apt-get update
apt-get install -y wget python-dev python-pip nano ethstatus gcc
pip install setuptools==43.0.0  wheel==0.33.0

安装 Docker:

apt-get install  apt-transport-https  ca-certificates -y
apt-get install  curl   software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

下面是单独一行的命令,为避免在一些设备、媒介中换行带来的困扰,故单独提出来:

add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu  $(lsb_release -cs) stable"
apt-get update
apt-get install docker-ce -y

Docker 可以简单理解为服务器上的虚拟机软件,如果在这个过程中遇到困难而无法正常运行下去,可以在搜索引擎上查找 Ubuntu 16.04 安装 Docker 类似的关键词。

部署 firstweb:

pip install xserver
xserver_package deploy firstweb
xserver start firstweb

这里的 xserver 是 Python 的 一个 package,也是我写的,直接拿去用吧,内置了 firstweb 需要的初始配置文件。

如果打算常驻当前 firstweb 这个容器,执行下面的命令:

xserver install_live

容器 简单来说,在此处就是特指 Docker 上运行起来的一个虚拟机系统,而所谓的 常驻,就是指这个容器挂了,xserver会通过 contab (计划任务) 自动重启一个新的容器替代。

注: 这里其实会自动下载 hepochen/pyweb:firstweb 这个 Docker 镜像回来,由 Docker Hub 提供的存储、下载、分发服务,相当于内置于 Docker 内的一个机制,一般情况应该不至于出问题。但如果是国内的线路,比如阿里云,可能要进行 Docker 相关的线路加速。

同步网站数据

之前的操作,都是在服务器端的命令行窗口,现在,我们换到另外一个窗口,在本地进行执行 rsync。
rsync 是一个 Mac 系统自带的命令,可以通过 ssh 将本地的文件夹数据,同步到服务器上。

要准备两件事情:

  1. 你要上传的网站文件夹的路径,在 FristWeb 这个 App,右键点击,可以看到 复制路径
  2. 一个域名(或二级域名) 用来绑定当前的网站

然后执行下面的命令,这个过程中可能需要输入登录服务器 root 账户的密码:

rsync -avh 本地网站目录路径/ root@服务器IP:/app/firstweb/网站域名

比如我本地执行的一个完整命令,看起来是这样的:

rsync -avh /Users/hepochen/Dropbox/WorkSoho/FirstWeb/FirstWebSites/blog3/ root@104.207.153.68:/app/firstweb/demo.firstweb.com

必须要注意的:

  1. 本地网站目录路径 必须是以 / 结尾的!
  2. 网站域名 必须要有!

等数据同步到服务器端之后,然后在服务器端的命令行窗口中执行下面命令,以重启 Web 服务:

docker exec firstweb bash -c 'kill -HUP `cat /tmp/web_server.pid`'

注意:

  1. 以后本地内容修改后,也进行如上同步+重启 Web 服务器的两步操作;
  2. firstweb (也就是 farbox_lite) 支持多个网站同时部署,当然不同网站的域名应该是不一样的;
  3. 命令行中要分清引号、反引号(一般键盘上也就是 ~ 这个键,但不是这个字符)。

绑定网站域名

在没有绑定域名的时候,只能通过 IP 访问,如果有多个网站,则只能默认命中其中一个网站。
域名如何绑定,可以从搜索引擎中寻找答案,主要是在 DNS 中,设定一个 A 记录指向刚才的服务器 IP。假设 domain.com 这个域名,一般是设定一个泛解析 *.domain.com 的 A 记录 (一般输入 *),以及根域 (一般留空) domain.com 的 A 记录指向服务器 IP。所谓 A 记录,就是 IP 的地址。
DNS 的记录修改了,一般都有缓存,快着几分钟,慢则几小时,甚至一天多。

另外,我们也可以在本地修改 hosts,强制将域名和 IP 匹配起来。即使这个域名尚未注册过,甚至不是你的域名都可以,当然,这也仅在本地生效。
在本地的命令行窗口中输入:

sudo nano /etc/hosts

光标移动到最后,输入 服务器IP 域名 这样的格式为单独一行,然后键盘按下 Control+X,会提示是否保存,保存后退出即可。
如果要删除一行,将光标通过方向键移动到当前行,然后快捷键 Control+K 进行删除。

如果不放心是否修改生效了,可以执行 cat /etc/hosts 查看具体的内容:

一般情况下, /etc/hosts 产生的缓存期很短,主要是浏览器本身也有一个缓存,不过,这个缓存期也是很短的。简单来说,/etc/hosts的修改是很快生效的;当然,你也可以自行确定是否生效了,在本课程最开始讲解如何 Debug 的时候,有提及如何查看当前页面的请求,确定其 Remote Address 是否匹配自己的 hosts 记录即可。

后记

技术是复杂的,也是简单的,借助工具,总能让我们在一开始的时候,去接触到复杂的技术,并且这个过程还是简单的。
比如这次的部署,我们实际上使用了下面这些相关的技术,也是一般正式的 Web 产品会用到的技术栈,它们可并非玩具性质的工具:

  • 基于 Ningix 之上的 OpenResty
  • Docker
  • Gunicorn
  • Gevent
  • Flask