檢視原始碼 在 Fly.io 上部署
Fly.io 在此維護其 Elixir/Phoenix 的指南:Fly.io/docs/elixir/getting-started/ 我們會持續維護這個指南,但最新且最棒的資訊請在他們那裡查看!
我們需要
本指南唯一需要的是一個可用的 Phoenix 應用程式。對於需要一個簡單應用程式來部署的人,請遵循執行中指南。
你可以只需
$ mix phx.new my_app
目標
本指南的主要目標是讓 Phoenix 應用程式在Fly.io上執行。
部分
讓我們將此程序分為幾個步驟,以便我們可以追蹤進度。
- 安裝 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 你的應用程式,請在你的 source code 目錄中執行fly launch
。這將建立並設定一個 Fly.io 應用程式。
$ fly launch
這會掃描你的 source code,偵測 Phoenix 專案,並為你執行mix phx.gen.release --docker
!這會為你建立一個 Dockerfile。
fly launch
指令會帶你瀏覽幾個問題。
- 你可以替應用程式命名,或讓它為你產生一個隨機名稱。
- 選擇一個組織(預設為
personal
)。組織是可以讓多個 Fly.io 使用者分享應用程式和資源的方式。 - 選擇部署區域。預設為最靠近的 Fly.io 區域。您可以在此查看完整區域清單。
- 為您設定 Postgres 資料庫。
- 建構 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 上快速設定叢集,有 2 部分。
- 安裝和使用
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
接下來,我們將將 topologies
組態設為 config/runtime.exs
。
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
策略,並利用 .internal
私密網路尋找使用 $FLY_APP_NAME
的其他已部署應用程式。
控制節點的名稱
我們需要控制 Elixir 節點的命名。為了幫助它們連線,我們會利用此模式命名:your-fly-app-name@the.ipv6.address.on.fly
。为此,我們將產生釋出組態。
$ 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
我們來加入第 2 個執行個體,看看它會部署到 ewr
中。
$ fly scale count 2
Count changed to 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 社群 尋找解法和提出問題。