查看源代码 在 Fly.io 上部署
Fly.io 为 Elixir/Phoenix 提供了他们自己的指南:Fly.io/docs/elixir/getting-started/ 我们会继续维护本指南,但最新的信息请参考他们的网站!
我们需要什么
本指南只需要一个可运行的 Phoenix 应用程序。对于需要部署简单应用程序的用户,请遵循 运行指南。
你只需要
$ mix phx.new my_app
目标
本指南的主要目标是在 Fly.io 上运行一个 Phoenix 应用程序。
章节
我们将把这个过程分成几个步骤,这样我们就可以跟踪我们的进度。
- 安装 Fly.io CLI
- 注册 Fly.io
- 将应用程序部署到 Fly.io
- Fly.io 额外提示
- 有用的 Fly.io 资源
安装 Fly.io CLI
按照 这里的说明 安装 Flyctl,它是 Fly.io 平台的命令行界面。
注册 Fly.io
我们可以使用 CLI 注册一个帐户。
$ fly auth signup
或者登录。
$ flyctl auth login
Fly 为大多数应用程序提供 免费层级。在设置帐户时需要信用卡,以防止滥用。有关更多详细信息,请查看 定价 页面。
将应用程序部署到 Fly.io
要将应用程序告知 Fly,请在包含源代码的目录中运行 fly launch
。这将创建和配置一个 Fly.io 应用程序。
$ fly launch
这将扫描您的源代码,检测 Phoenix 项目,并为您运行 mix phx.gen.release --docker
!这将为您创建一个 Dockerfile。
fly launch
命令将引导您完成一些问题。
- 您可以命名应用程序,也可以让它为您生成随机名称。
- 选择一个组织(默认为
personal
)。组织是 Fly.io 用户之间共享应用程序和资源的一种方式。 - 选择一个要部署到的区域。默认为最接近的 Fly.io 区域。您可以查看 完整的区域列表。
- 为您设置一个 Postgres DB。
- 构建 Dockerfile。
- 部署您的应用程序!
fly launch
命令还为您创建了一个 fly.toml
文件。您可以在其中设置环境变量和其他配置。
在 Fly.io 上存储秘密
您可能还有一些秘密需要在您的应用程序上设置。
使用 fly secrets
来配置它们。
$ fly secrets set MY_SECRET_KEY=my_secret_value
再次部署
当您想部署对应用程序的更改时,请使用 fly deploy
。
$ fly deploy
注意:在 Apple Silicon (M1) 计算机上,docker 使用 qemu 运行跨平台构建,这可能并不总是有效。如果您遇到以下类似的段错误,
=> [build 7/17] RUN mix deps.get --only
=> => # qemu: uncaught target signal 11 (Segmentation fault) - core dumped
您可以通过添加 --remote-only
标志来使用 fly 的远程构建器
$ fly deploy --remote-only
您始终可以检查部署的状态
$ fly status
检查您的应用程序日志
$ fly logs
如果一切正常,请在 Fly 上打开您的应用程序
$ fly open
Fly.io 额外提示
进入正在运行的节点的 IEx shell
Elixir 支持进入正在运行的生产节点的 IEx shell。
有几个先决条件,我们首先需要建立一个到 Fly.io 上我们机器的 SSH Shell。
此步骤将为您的帐户设置根证书,然后颁发证书。
$ fly ssh issue --agent
配置好 SSH 后,让我们打开一个控制台。
$ fly ssh console
Connecting to my-app-1234.internal... complete
/ #
如果一切顺利,那么您就可以进入机器的 shell 了!现在我们只需要启动远程 IEx shell 即可。部署的 Dockerfile 被配置为将我们的应用程序拉取到 /app
。因此,名为 my_app
的应用程序的命令如下所示
$ app/bin/my_app remote
Erlang/OTP 23 [erts-11.2.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1]
Interactive Elixir (1.11.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(my_app@fdaa:0:1da8:a7b:ac4:b204:7e29:2)1>
现在我们已经进入节点的运行 IEx shell 了!您可以使用 CTRL+C、CTRL+C 安全地断开连接。
对应用程序进行集群
Elixir 和 BEAM 具有令人难以置信的能力,可以将它们一起集群,并在节点之间无缝传递消息。本指南的这一部分将引导您完成对 Elixir 应用程序进行集群的过程。
在 Fly.io 上快速设置集群有两个部分。
- 安装和使用
libcluster
- 将应用程序扩展到多个实例
添加 libcluster
广泛采用的库 libcluster 在这里有所帮助。
libcluster
可以使用多种策略来查找和连接其他节点。我们将在 Fly.io 上使用的策略是 DNSPoll
。
安装 libcluster
后,像这样将其添加到应用程序中
defmodule MyApp.Application do
use Application
def start(_type, _args) do
topologies = Application.get_env(:libcluster, :topologies) || []
children = [
# ...
# setup for clustering
{Cluster.Supervisor, [topologies, [name: MyApp.ClusterSupervisor]]}
]
# ...
end
# ...
end
我们的下一步是在 config/runtime.exs
中添加 topologies
配置。
app_name =
System.get_env("FLY_APP_NAME") ||
raise "FLY_APP_NAME not available"
config :libcluster,
topologies: [
fly6pn: [
strategy: Cluster.Strategy.DNSPoll,
config: [
polling_interval: 5_000,
query: "#{app_name}.internal",
node_basename: app_name
]
]
]
这将配置 libcluster
使用 DNSPoll
策略,并使用 $FLY_APP_NAME
在 .internal
私有网络上查找其他已部署的应用程序。
控制节点的名称
我们需要控制 Elixir 节点的命名。为了帮助它们连接起来,我们将使用以下模式为它们命名:[email protected]
。为此,我们将生成发布配置。
$ mix release.init
然后编辑生成的 rel/env.sh.eex
文件,并添加以下几行
ip=$(grep fly-local-6pn /etc/hosts | cut -f 1)
export RELEASE_DISTRIBUTION=name
export RELEASE_NODE=$FLY_APP_NAME@$ip
完成更改后,部署您的应用程序!
$ fly deploy
为了让我们的应用程序形成集群,我们必须拥有多个实例。接下来,我们将添加一个额外的节点实例。
运行多个实例
运行多个实例有两种方法。
- 将我们的应用程序扩展到在一个区域中拥有多个实例。
- 向另一个区域添加一个实例(多个区域)。
首先让我们从单个部署的基线开始。
$ fly status
...
Instances
ID VERSION REGION DESIRED STATUS HEALTH CHECKS RESTARTS CREATED
f9014bf7 26 sea run running 1 total, 1 passing 0 1h8m ago
在一个区域中进行扩展
让我们将当前区域中的实例扩展到 2 个。
$ fly scale count 2
Count changed to 2
检查状态,我们可以看到发生了什么。
$ fly status
...
Instances
ID VERSION REGION DESIRED STATUS HEALTH CHECKS RESTARTS CREATED
eb4119d3 27 sea run running 1 total, 1 passing 0 39s ago
f9014bf7 27 sea run running 1 total, 1 passing 0 1h13m ago
现在我们拥有两个位于同一个区域的实例。
让我们确保它们已形成集群。我们可以查看日志
$ fly logs
...
app[eb4119d3] sea [info] 21:50:21.924 [info] [libcluster:fly6pn] connected to :"my-app-1234@fdaa:0:1da8:a7b:ac2:f901:4bf7:2"
...
但这不如从节点内部查看它那么令人满意。从 IEx shell 中,我们可以询问我们连接到的节点,它可以看到哪些其他节点。
$ fly ssh console -C "/app/bin/my_app remote"
iex(my-app-1234@fdaa:0:1da8:a7b:ac2:f901:4bf7:2)1> Node.list
[:"my-app-1234@fdaa:0:1da8:a7b:ac4:eb41:19d3:2"]
IEx 提示符已包含在内,以帮助显示我们连接到的节点的 IP 地址。然后获取 Node.list
将返回另一个节点。我们的两个实例已连接并形成集群!
扩展到多个区域
Fly 使得在靠近您的用户的位置部署实例变得非常容易。通过 DNS 的魔力,用户会被定向到您应用程序所在的最近区域。您可以在此处阅读有关 Fly.io 区域 的更多信息。
从我们的基线开始,它是一个位于 sea
(即美国华盛顿州西雅图)中的单个实例,让我们添加区域 ewr
(即美国新泽西州帕西帕尼)。这将在美国的两个海岸上放置一个实例。
$ fly regions add ewr
Region Pool:
ewr
sea
Backup Region:
iad
lax
sjc
vin
查看状态显示我们只在 1 个区域中,因为我们的计数设置为 1。
$ fly status
...
Instances
ID VERSION REGION DESIRED STATUS HEALTH CHECKS RESTARTS CREATED
cdf6c422 29 sea run running 1 total, 1 passing 0 58s ago
让我们添加一个第二个实例,看看它是否部署到 ewr
。
$ fly scale count 2
Count changed to 2
现在状态显示我们拥有两个跨越 2 个区域的实例!
$ fly status
...
Instances
ID VERSION REGION DESIRED STATUS HEALTH CHECKS RESTARTS CREATED
0a8e6666 30 ewr run running 1 total, 1 passing 0 16s ago
cdf6c422 30 sea run running 1 total, 1 passing 0 6m47s ago
让我们确保它们已形成集群。
$ fly ssh console -C "/app/bin/my_app remote"
iex(my-app-1234@fdaa:0:1da8:a7b:ac2:cdf6:c422:2)1> Node.list
[:"my-app-1234@fdaa:0:1da8:a7b:ab2:a8e:6666:2"]
我们拥有两个应用程序实例,分别部署到北美大陆的西海岸和东海岸,它们已形成集群!我们的用户将自动被定向到离他们最近的服务器。
Fly.io 平台内置了分发支持,使在多个区域中对分布式 Elixir 节点进行集群变得非常容易。
有用的 Fly.io 资源
打开您帐户的仪表板
$ fly dashboard
部署您的应用程序
$ fly deploy
显示已部署应用程序的状态
$ fly status
访问并跟踪日志
$ fly logs
将您的应用程序扩展或缩减
$ fly scale count 2
有关更多信息,请参考 Fly.io Elixir 文档。
使用 Fly.io 应用程序 涵盖了以下内容
- 状态和日志
- 自定义域名
- 证书
故障排除
请查看 故障排除 和 Elixir 故障排除
访问 Fly.io 社区 以找到解决方案并提出问题。