第34章:使用AWS
进行部署¶
亚马逊网络服务(AWS
)是目前最大的云服务提供商。它提供了许多服务产品,简化了应用程序的部署和维护。在本章中,你将学习如何使用其中的一些服务来部署Vapor
应用。
开始之前¶
要执行本章的步骤,你必须有一个AWS
账户。如果你还没有,请按照https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/上的说明创建一个。
设置你的AWS
实例¶
你的第一步是启动一个EC2
实例。EC2
是AWS
的一个虚拟机产品。这给你一个普通的Linux
机器,你可以用它来运行你的Vapor
应用程序。
在这个例子中,你将创建一个Ubuntu 20.04
实例。20.04
是Ubuntu
的最新LTS
(长期服务)版本。
首先,你必须决定你要使用哪个地区。点击你名字旁边的下拉菜单,选择离你最近的地区。
选择区域后,点击Services
和EC2
。
在你启动你的实例之前,你必须创建一个Security Group
。这基本上是你的实例的防火墙,允许你指定服务器上哪些端口是开放的。
点击Security Groups
,然后点击Create Security Group
。
在出现的对话框中,输入一个Security group name
和Description
,这将使你很容易把它与你的应用程序联系起来。在这个例子中,将你的组命名为vapor-til
。
在Inbound
部分,点击Add Rule
来添加一个新规则。使用Type
下的下拉菜单,选择SSH
。在Source
下,选择My IP
。重复HTTP
和HTTPS
的过程,但把Source
设置为Anywhere
。你的屏幕应该与下面类似:
点击页面底部的Create security group
来创建你的安全组。
你现在准备好创建你的实例了。点击Instances
和Launch Instances
。这就开始了配置和启动EC2
实例的七步程序。
首先,你必须选择一个亚马逊机器图像(AMI
)作为你的EC2实例的基础。为了简化寻找正确的AMI
,在搜索框中输入20.04
,并勾选Free tier only
。选择一个名为Ubuntu Server 20.04 LTS
的,点击其行中的Select
。
接下来,你将选择你的Instance Type
。AWS
突出了默认的t2.micro
。这是Free tier eligible
,意味着在你拥有账户的前12
个月,你可以免费获得1GB
内存和1vCPU
。你将坚持这个选择。
点击Next: Configure Instance Details
。
在这一页,你可以为你的实例设置各种细节。在这个例子中,只需让一切保持原样。
点击Next: Add Storage
。
在这一页,你将为你的应用程序配置卷。将Size
改为20
;这将为你的应用程序提供足够的空间。
点击Next: Add Tags
。
这个页面允许你为你的实例添加标签。这一步是可选的,但随着使用量的增加,这样做将简化对AWS资源的管理。单击Add Tag
,并输入以下值:
- Key: Name
- Value: vapor-til
这使得该实例被命名为vapor-til
。
单击Next: Configure Security Group
。
在这一页,你将把你之前创建的安全组附加到你的实例上。点击Select an existing security group
单选按钮。然后,选择你的vapor-til
组:
最后,点击Review and Launch
。
在这个页面上,你可以验证你之前选择的选项。当你满意时,点击Launch
。AWS
将提示你选择一个现有的密钥对或创建一个新的。你需要一个密钥对来允许你对你的实例进行SSH
访问,所以不要跳过这个步骤。如果你创建一个新的密钥对,记得点击Download Key Pair
。
一旦你配置并保存了你的密钥对,点击Launch Instances
。
AWS将确认它正在启动你的实例。点击View Instances
,返回到你的实例摘要页面。如果你足够快,你的实例将显示Instance State
为Pending
,有一个黄色指示灯。过了一会儿,它将显示为Running
,并有一个绿色指示灯。
复制IPv4 Public IP
。你将用它来登录到你的实例。
SSH
要求你把你的私钥设置为对其所有者只读,也就是你,其他人不能访问。如果该文件有任何其他保护设置,SSH
将拒绝使用它。在终端,输入以下命令设置保护你的私钥:
chmod 600 /path/to/your/ssh/key
Note
一般来说,SSH
密钥和其他相关文件应该放在隐藏目录~/.ssh
中。如果你没有把你的钥匙放在那里,请在设置其保护之前考虑这样做。
现在,在终端,输入以下命令:
ssh -i /location/to/your/ssh/key ubuntu@your-aws-ip
这将使你登录并进入你的实例中的shell
提示。
为了简化对实例的访问,你可以在~/.ssh/config
中为它创建一个条目。使用你喜欢的文本编辑器--nano
、vi
、Sublime Text
都是不错的选择--在该文件中添加以下内容:
Host vapor-til
HostName <your public IP or public DNS name>
User ubuntu
IdentityFile </path/to/your/key/file>
现在,你可以通过在终端输入以下命令连接到你的实例:
ssh vapor-til
下面的命令都是假设你已经登录到你的EC2
实例并有root
权限。
在一个新的系统中,确保所有软件包都是最新的,总是一个好主意。要更新你的系统,请输入以下命令:
sudo apt-get update
sudo apt-get upgrade -y
安装Swift
¶
为了构建你的Vapor
应用,你必须在你的EC2
实例上安装Swift
。Swift
支持许多Linux
平台,包括Ubuntu
和CentOS
。请访问https://swift.org/getting-started/,了解为你的平台安装的细节。
首先,为你的平台下载工具链。你可以在https://swift.org/download/#releases找到最新的工具链。例如,在终端,运行:
wget https://swift.org/builds/swift-5.3.2-release/ubuntu2004/swift-5.3.2-RELEASE/swift-5.3.2-RELEASE-ubuntu20.04.tar.gz
这就把Swift 5.3.2
的工具链下载到你的本地目录。接下来,解压下载的文件:
tar -xzf swift-5.3.2-RELEASE-ubuntu20.04.tar.gz
这样就把下载的文件解压到当前工作目录中。
接下来,安装你的系统所需的依赖项。对于Ubuntu 20.04
,在终端输入:
sudo apt-get install binutils git gnupg2 libc6-dev \
libcurl4 libedit2 libgcc-9-dev libpython2.7 \
libsqlite3-0 libstdc++-9-dev libxml2 libz3-dev \
pkg-config tzdata zlib1g-dev -y
最后,将Swift
工具链添加到你的路径中,这样你就可以从命令行中使用它。在终端,运行:
echo "export PATH=/home/ubuntu/swift-5.3.2-RELEASE-ubuntu20.04/usr/bin:${PATH}" >> .profile
source .profile
Note: If you download a newer version of the toolchain, be sure to update the path to reflect the new version.
This adds the directory to the Swift binary to your profile and reloads it. Important: remember to set the directory to the path where your Swift installation exists.
You can verify your installation by entering:
Note
如果你下载了较新版本的工具链,请确保更新路径以反映新版本。
这将把Swift
二进制文件的目录添加到你的配置文件中,并重新加载它。
Tips
记得将目录设置为你的Swift
安装所在的路径。
你可以通过输入验证你的安装:
swift --version
你应该看到返回的是正确的版本:
系统内存¶
Swift编译器可以使用大量的内存。小的云实例,如t2.micro
,不包含足够的内存让Swift
编译器工作。你可以通过启用交换空间来解决这个问题。在终端,输入以下内容:
sudo su -
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
exit
这些命令切换到一个超级用户,并创建一个2GB
的交换文件。这应该足够让编译器工作了。
设置你的应用程序¶
为了设置你的应用程序,你将首先从GitHub
克隆它。要从本书的其余部分建立TILapp
的例子,请输入以下命令:
# 1
git clone https://github.com/raywenderlich/vapor-til.git
# 2
cd vapor-til
# 3
swift build -c release --enable-test-discovery
下面是这个的作用:
- 克隆
GitHub
上的vapor-til
项目。 - 切换到
vapor-til
文件夹。 - 以发布模式构建项目。
构建项目后,你可以尝试通过输入来启动应用程序:
./.build/release/Run
这将不会起作用,因为你还没有设置数据库或必要的环境变量。
设置一个PostgreSQL
服务器¶
对于你的数据库,你将使用亚马逊关系型数据库服务(RDS
)。这个AWS数据库服务支持几个流行的关系型数据库系统,包括PostgreSQL
。
在创建你的数据库之前,你需要配置另一个安全组。点击你的AWS
页面顶部的Services
,在搜索栏中输入VPC
。这将带你到VPC
仪表板。点击Your VPCs
,显示你的VPC
(虚拟私有云)信息。选择你之前为EC2
实例选择的VPC
。在描述部分,记下你的IPv4 CIDR
。它将是类似于172.31.0.0/16
的东西。
现在,在控制台中点击左侧列表中的Security Groups
。现在出现的屏幕应该看起来很熟悉。点击Create Security Group
。将该组命名为vapor-til database
。
在Inbound
标签上,点击Add Rule
。从Type
下拉选择PostgreSQL
,在Source
框中输入你的IPv4 CIDR
。
你的屏幕应该看起来像这样:
点击Create security group
。
在AWS
控制台,点击Services
,找到RDS
。点击Create Database
。这将显示Select engine
页面。选择PostgreSQL
作为你的引擎。
接下来,你必须选择你的用例。在本教程中,选择Dev/Test
。在这下面,你被要求指定关于你的数据库的一些细节。在Settings
下,输入以下信息:
- DB instance identifier:vapor-til
- Master username:vaportil
- Master password和Confirm password:你的选择
接下来,在DB instance size
下,选择Burstable classes
单选按钮并从下拉列表中选择db.t3.micro
。
然后,在Connectivity
下,确保你选择与你的EC2
实例相同的VPC
。接下来,将Public accessibility
设置为Yes
。这将允许你从你的本地机器访问数据库,如果你愿意的话。
Note
如果你确实希望从你的本地机器访问你的数据库,你将需要在你的安全组中添加一条规则,以允许访问。
将VPC security groups
设置为Choose existing VPC security groups
。点击Default
旁边的X
,删除该组,并从下拉菜单中添加vapor-til database
。将其他设置保持在默认状态。
最后,展开Additional configuration
。在Database options
下,输入vaportil
作为Initial database name
。将所有其他选项保留为默认值。
滚动到页面底部,点击Create database
。这将需要一些时间来完成。点击数据库列表中的数据库,查看其详细信息。在Connectivity & security
部分找到Endpoint
,并记下它。你很快就会需要它。
安装和配置nginx
¶
nginx
是一个流行的网络服务器,通常用作其他网络应用程序前面的代理服务器。对于Vapor
应用程序来说,这很有用,因为它提供了额外的功能,如压缩、缓存、HTTP/2
支持、TLS(HTTPS)
等等。
这里的例子非常简单,只是让你开始。然而,它很容易定制,可以实现更多的功能。
首先,在你的EC2
实例上安装nginx
。SSH
进入你的EC2
实例,输入以下命令:
sudo su -
apt-get install nginx -y
这将切换到超级用户,并从APT
资源库中安装nginx
。为了设置nginx
配置,在/etc/nginx/sites-available
创建一个文件,名为vapor-til
,用你喜欢的编辑器添加以下内容:
server {
listen 80;
root /home/ubuntu/vapor-til/Public;
try_files $uri @proxy;
location @proxy {
proxy_pass http://localhost:8080;
proxy_pass_header Server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 3s;
proxy_read_timeout 10s;
}
}
然后运行以下命令:
# 1
rm /etc/nginx/sites-enabled/default
# 2
ln -s /etc/nginx/sites-available/vapor-til \
/etc/nginx/sites-enabled/vapor-til
# 3
systemctl reload nginx
以下是这样做的原因:
- 禁用默认网站。
- 启用你的
vapor-til
网站。 - 重新加载
nginx
以激活你的改变。
在测试所有这些之前,你需要一种方法来启动你的应用程序。
以系统服务的形式运行你的应用程序¶
你希望你的应用程序在实例启动时运行,并在由于关键错误而崩溃时重新启动。实现这一目标的最简单方法是将其整合为一个系统服务。大多数Swift
--因此也包括Vapor
--支持的Linux
版本都使用一个叫做systemd
的服务来完成这个任务。
你需要在你的运行系统中添加两个文件。一个是包含你的应用程序所需的所有环境变量,另一个是定义你的应用程序的服务。
Note
你可以在一个文件中完成所有的工作,但这样的划分使你在必要时更容易调整环境变量。
首先,SSH
到你的EC2
实例,如果你还没有成为root
的话。在终端,输入:
sudo su -
接下来,用你喜欢的编辑器创建/etc/vapor-til.conf
,并在其中添加以下内容:
DATABASE_HOST='<your AWS RDS endpoint>'
DATABASE_USERNAME='vaportil'
DATABASE_NAME='vaportil'
DATABASE_PASSWORD='<your chosen password>'
SENDGRID_API_KEY='test'
GOOGLE_CALLBACK_URL='test'
GOOGLE_CLIENT_ID='test'
GOOGLE_CLIENT_SECRET='test'
GITHUB_CALLBACK_URL='test'
GITHUB_CLIENT_ID='test'
GITHUB_CLIENT_SECRET='test'
SIWA_REDIRECT_URL='test'
IOS_APPLICATION_IDENTIFIER='test'
WEBSITE_APPLICATION_IDENTIFIER='test'
这设置了TILapp
用来寻找其数据库并与其他服务集成的环境变量。它们与你在其他章节中在Xcode
中创建的环境是相同的。
Note
为了让TILapp
的所有部分正常工作,你需要为所有的SENDGRID
、GOOGLE
、GITHUB
和SIWA
值替换有效值。关于如何配置这些值,见第22-26
章。现在,任何非空的字符串都将允许应用程序运行。
接下来,用你喜欢的编辑器创建/etc/systemd/system/vapor-til.service
,并在其中添加以下内容:
# 1
[Unit]
Description="Vapor TILapp"
After=network.target
# 2
[Service]
User=ubuntu
EnvironmentFile=/etc/vapor-til.conf
WorkingDirectory=/home/ubuntu/vapor-til
# 3
Restart=always
# 4
ExecStart=/home/ubuntu/vapor-til/.build/release/Run \
--env production
[Install]
WantedBy=multi-user.target
下面是这个的作用:
systemd
将其管理的项目称为unit
。本节为你的应用程序定义了这个单元,并规定它在网络启动后才能启动。- 为你的应用程序的服务指定参数。你可以让应用程序以任何有效用户的身份运行。注意,在这一节中,你使用你先前创建的配置文件来描述环境。
- 告诉
systemd
,如果你的应用程序失败了,它应该总是尝试重新启动。 - 指定
systemd
将执行的命令来启动你的应用程序。如果有必要,你可以在这里添加其他参数。
在保存了服务定义文件的修改后,你必须告诉systemd
读取该文件,以便让它识别服务。输入以下命令:
systemctl daemon-reload
这将使vapor-til.service
作为一个选项可用。通过下面的命令,你会发现标准的键盘快捷键,如tab
完成,与你的新服务一起工作,就像它们与现有的系统服务一样。
要启动你的应用程序并使其在重启后自动启动,请输入以下命令:
systemctl start vapor-til.service
systemctl enable vapor-til.service
你的应用程序应该启动。你可以通过输入来检查其状态:
systemctl status -l vapor-til.service
你应该看到服务器正在启动:
一旦你的应用程序运行,你应该能够通过在浏览器中输入你的EC2
实例的公共DNS
名称(与你用于SSH的名称相同)来访问它。
如果你需要手动重启你的应用程序,请使用以下命令:
systemctl restart vapor-til.service
而且,如果你想停止你的应用程序,下面的命令会起到作用:
systemctl stop vapor-til.service
接下来去哪?¶
你现在已经掌握了如何在AWS
上设置Vapor
应用程序的基本知识。AWS
允许的事情还有很多,如扩展、IP
池、自动备份、复制等等。你可以添加负载均衡器和带有TLS
证书的自定义DNS
名称。还有其他部署选项,如在Docker
中运行,甚至使用AWS Lambda
。涵盖AWS
的所有内容本身就是一整本书! 花一些时间阅读AWS
的文档和教程,以了解更多。
当你完成了本章的EC2
实例和RDS
数据库后,一定要Delete
数据库实例和Terminate EC2
实例,这样AWS
就会删除它们,你就不会为它们支付任何(额外)费用。