fly.io的使用

# fly.io (主线)

目前团队采用的部署方式是 Fly.io,用了一段时间了,记录一下。

Fly.io 是一个基于容器的部署平台,能够保证开发和生产的环境运行在同一环境。

普通部署的话,需要在服务器上安装对应的环境,比较麻烦。而且 Fly.io 部署起来会更方便,价格也会很便宜。

另外主要是它可以提供不同国家的节点,根据需求选择不同的国家节点进行部署。

# 安装命令

1
curl -L https://fly.io/install.sh | sh

# 登陆

1
flyctl auth login

会提示 (点击里面的链接来确认登陆):

1
2
3
4
5
failed opening browser. Copy the url (https://fly.io/app/auth/cli/f71341b207055cb68e89fdcd3b049f0c) into a browser and continue
Opening https://fly.io/app/auth/cli/f71341b207055cb68e89fdcd3b049f0c ...(点击这个地址来登陆)

Waiting for session... Done
successfully logged in as rubyer1993@gmail.com

不要忘了绑定信用卡。

拿一个月前用 fly.io 在 Sinatra 例子部署的演示:

# app.rb 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env ruby

require 'rubygems'
require 'bundler/setup'
require 'sinatra'

get '/' do
"<h1>我是sai</h1>"
end

get '/:name' do
"<h1>i am sai</h1>"
end

# Gemfile 文件

1
2
3
4
5
source 'https://rubygems.org'

ruby '3.0.3'
gem 'sinatra'
gem 'puma'

# config.ru

1
2
3
require './app.rb'

run Sinatra::Application

运行 flyctl launch。

这里有可能会提示:

  • Error: Validation failed: Name has already been taken 这里需要你更改 app 的名字 (sai,ruby, rails 都占用了。。。)
  • Error: Your account has been marked as high risk. Please go to https://fly.io/high-risk-unlock to verify your account 这里需要绑定你的信用卡

这里会让选择 app 的名字、服务器所在的节点、数据库等信息,按需要选择就好了

这时候在 fly.io 官网已经可以看到

这个 app 已经创建好了

接下来执行 fly deploy --remote-only

执行完成的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
==> Verifying app config
Validating /opt/app/sai/fly.toml
Platform: machines
✓ Configuration is valid
--> Verified app config
==> Building image
WARN Failed to start remote builder heartbeat: failed building options: failed probing "personal": context deadline exceeded
Remote builder fly-builder-weathered-cherry-206 ready
==> Creating build context
--> Creating build context done
==> Building image with Docker
--> docker host: 20.10.12 linux x86_64
Sending build context to Docker daemon 866B
[+] Building 31.4s (14/14) FINISHED
=> [internal] load remote build context 0.0s
=> copy /context / 0.0s
=> [internal] load metadata for docker.io/library/ruby:3.0.3-slim 1.2s
=> [base 1/3] FROM docker.io/library/ruby:3.0.3-slim@sha256:086f56a91f8952c50e3a088e174557c7d578e381c9531270a97f6248e8a5d398 2.3s
=> => resolve docker.io/library/ruby:3.0.3-slim@sha256:086f56a91f8952c50e3a088e174557c7d578e381c9531270a97f6248e8a5d398 0.0s
=> => sha256:80209e0f3e367b8b27a3d8cbf88b1d3f8a39623b7555de84f8b473940fc1cb68 29.11MB / 29.11MB 0.3s
=> => sha256:603493fe65bd0f3843878643ba6ce54df4d35bce9e3e5fbd560cd13007c6903c 175B / 175B 0.0s
=> => sha256:086f56a91f8952c50e3a088e174557c7d578e381c9531270a97f6248e8a5d398 1.86kB / 1.86kB 0.0s
=> => sha256:1272dbaa1796076e45114e52af11667e7ea15a1d2ace44cfeb911fcc7acd0b5c 1.37kB / 1.37kB 0.0s
=> => sha256:874a9777434b8b790543604d69aa5f8cd6ecdf45f7b9077d58c87c959efdfe84 5.80kB / 5.80kB 0.0s
=> => sha256:c229119241af7b23b121052a1cae4c03e0a477a72ea6a7f463ad7623ff8f274b 31.38MB / 31.38MB 0.5s
=> => sha256:c14a196c62ee705bf37cfab91ea1d171f7b636ffd65269877b758f726189872e 9.99MB / 9.99MB 0.3s
=> => sha256:365bbf24384cc62b2e96112071ead0fb9d34bb8f42158306d2b628b641fc0068 199B / 199B 0.0s
=> => extracting sha256:c229119241af7b23b121052a1cae4c03e0a477a72ea6a7f463ad7623ff8f274b 0.7s
=> => extracting sha256:c14a196c62ee705bf37cfab91ea1d171f7b636ffd65269877b758f726189872e 0.4s
=> => extracting sha256:365bbf24384cc62b2e96112071ead0fb9d34bb8f42158306d2b628b641fc0068 0.0s
=> => extracting sha256:80209e0f3e367b8b27a3d8cbf88b1d3f8a39623b7555de84f8b473940fc1cb68 0.5s
=> => extracting sha256:603493fe65bd0f3843878643ba6ce54df4d35bce9e3e5fbd560cd13007c6903c 0.0s
=> [base 2/3] WORKDIR /app 0.1s
=> [base 3/3] RUN gem update --system --no-document && gem install -N bundler 7.2s
=> [stage-2 1/4] RUN useradd ruby --home /app --shell /bin/bash 0.5s
=> [build 1/3] RUN apt-get update -qq && apt-get install --no-install-recommends -y build-essential 9.9s
=> [build 2/3] COPY Gemfile* . 0.0s
=> [build 3/3] RUN bundle install 8.2s
=> [stage-2 2/4] COPY --from=build /usr/local/bundle /usr/local/bundle 0.2s
=> [stage-2 3/4] COPY --from=build --chown=ruby:ruby /app /app 0.0s
=> [stage-2 4/4] COPY --chown=ruby:ruby . . 0.0s
=> exporting to image 0.3s
=> => exporting layers 0.3s
=> => writing image sha256:f506ae858e2c10ea5b51c85d4bbe861fc675f590d9f453897179db968bb72fde 0.0s
=> => naming to registry.fly.io/rubyonrails:deployment-01HABDF81PVD00K9EGCHXB82KQ 0.0s
--> Building image done
==> Pushing image to fly
The push refers to repository [registry.fly.io/rubyonrails]
3f68502190ea: Pushed
57a2ed221edf: Pushed
bc879954f0ad: Pushed
bc0f426be5a5: Pushed
e93e1dc6c52d: Pushed
13cfe581df09: Pushed
4a9a6a9f7117: Pushed
55f04a2d15b5: Pushed
0e71b336039b: Pushed
479c23445642: Pushed
608f3a074261: Pushed
deployment-01HABDF81PVD00K9EGCHXB82KQ: digest: sha256:f5c104c56cd0ec61554165fc1c7d54f2c0e9e3824781862f0f62c4792e54c322 size: 2616
--> Pushing image done
image: registry.fly.io/rubyonrails:deployment-01HABDF81PVD00K9EGCHXB82KQ
image size: 207 MB

Watch your app at https://fly.io/apps/rubyonrails/monitoring

Provisioning ips for rubyonrails
Dedicated ipv6: 2a09:8280:1::2d:7125
Shared ipv4: 66.241.124.143
Add a dedicated ipv4 with: fly ips allocate-v4
Process groups have changed. This will:
* create 1 "app" machine

No machines in group app, launching one new machine
Error: error creating a new machine: failed to launch VM: flyctl version too old, must be at least 0.1.20

这里看到提示了 VM: flyctl version too old, must be at least 0.1.20

执行, fly version update

1
2
3
4
5
6
7
8
Running automatic update [curl -L "https://fly.io/install.sh" | sh]
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1735 0 1735 0 0 1307 0 --:--:-- 0:00:01 --:--:-- 1307
######################################################################## 100.0%
set channel to shell
flyctl was installed successfully to /root/.fly/bin/flyctl
Run 'flyctl --help' to get started

然后重新执行 fly deploy --remote-only

这时候可以看到没有报错,服务已经跑起来了。

这里可以看到服务的详细信息。访问地址:https://rubyonrails.fly.dev/app name .fly.dev)

会在本地生成 fly.toml 文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# fly.toml app configuration file generated for rubyonrails on 2023-09-15T11:07:57+08:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = "rubyonrails"
kill_signal = "SIGINT"
kill_timeout = 5
mounts = []
primary_region = "hkg"
processes = []

[build]

[[services]]
internal_port = 8080
processes = ["app"]
protocol = "tcp"
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"

[[services.ports]]
force_https = true
handlers = ["http"]
port = 80

[[services.ports]]
handlers = ["tls", "http"]
port = 443

另外想问 admin 管理访问 https://fly.io/apps/app_name

比如我的就是:https://fly.io/apps/rubyonrails

如果对代码进行修改之后,重新执行部署就会生效:

1
fly deploy --remote-only

# 其他(非主线)

进入 console 控制台:

1
flyctl ssh console

进入 Rails console,在 app 目录下执行:

1
./bin/rails console

连接 PostgreSQL 数据库:

1
flyctl postgres connect -a <contract-api-db>

如果想在外部连接:

1
flyctl proxy 5432 -a <contract-api-db>

然后可以通过以下方式连接:

1
psql postgres://database_name:LJNA12LSAI@localhost:5432

或者

1
psql -U database_name -h 127.0.0.1 -p 5432

导入文件到 Fly.io 服务器上的 PostgreSQL:

1
psql -h 127.0.0.1 -U database_name -d database_name -f file.sql

# Fly.io 的各种报错:

1.Error failed building options: failed probing “personal”: context deadline exceeded

解决方法:需要重新登录 (flyctl auth login)

2.You don’t have net-smtp installed in your application. Please add it to your Gemfile and run bundle install

解决方法:在 Gemfile 中添加以下内容:

1
2
3
gem 'net-smtp', require: false
gem 'net-imap', require: false
gem 'net-pop', require: false

3. 在部署过程中 rails assets::precompile 执行命令错误

解决方法:注释掉 dockerfile 中的两个 without,同时注释掉下面标记为 # 的部分。

4.remote builder app unavalilable

解决方法:删除 Fly.io 的 fly-builder-nameless-XXX(可以在 Fly.io 的 Apps 查看),然后重新执行 fly deploy 即可。

5. 部署成功后,访问 Fly 生成的 URL 提示 403 或打不开(Rails)

在 config/application.rb 文件中添加生成的 URL,例如:

1
config.hosts << 'rubyonrails.fly.dev'

备注:可以通过这个来排查问题

  • fly status --all
  • fly logs -i