好用的 Heroku 平台即將取消免費方案,今年 11/28 後會關閉免費 Heroku Dyno,逐水草而居的免費仔們得尋覓新家囉。我在 Heroku 有個 LINE 機器人,雖屬好玩性質可有可無,想想還是為它找個落腳處,順便見識其他平台。上週看到 Cash 大分享一個可取代 Heroku 的好選擇 - Fly.io,不囉嗦,馬上來試試。

先簡單介紹 Fly.io,它跟 Heroku 一樣是個可以讓你部署應用程式上去執行的平台,提供了一些免費額度,包含:

  • 最多三個 shared-cpu-1 x 256mb VM
  • 總共 3GB 資料儲存空間
  • 依資源所在區域有不同的對外流量上限:北美歐洲 100GB、南美亞太非洲地中海 30GB、印度 30GB

對小型應用程式來說,這樣免費額度應該已經很夠用,但有些較方便的指令,功能,即使免費也需綁定信用卡才能使用。

Fly.io 針對 Rails、Laravel、G、NextJS、Deno、Ruby、靜態站台、Node、Python 等平台 提供專屬的部署做法,不包含 ASP.NET Core,但不用擔心,Fly.io 支援以 Dockerfile 建置部署,一切就好辦了。前陣子剛做完的 ASP.NET Core + Dockerfile 練習立刻派上用場,我也打算用它當範例部署到 Fly.io 試玩看看。

官方有使用 Dockerfile 部署的說明,基本上按表操課即可,但我有將檔案寫入外部儲存空間的需求,故還需知道如何建立 Volume 及對映路徑;Fly.io 不支援 Docker Compose,故對映 Port 及資料夾路徑需修改 Fly.io 設定檔,這部分後面會提。

以下是本次部署測試的筆記:

  1. 首先要安裝 Fly CLI 工具,照著說明,Windows 用 PowerShell 指令跑 iwr https://fly.io/install.ps1 -useb | iex 完成下載安裝即可,之後動作靠在命令列視窗輸入 flyctl 及 fly 完成。
  2. 使用 Fly.io 前要先註冊,使用指令 flyctl auth signup 開啟註冊網頁,用 Github 帳號或 Email 建帳號完成註冊。
  3. 接著切到 ASP.NET Core 專案,Dockerfile 要先做好,執行 fly launch,fly CLI 將詢問 VM 名稱、VM 建立區域(若無距離速度考量,選美國流量額度較大)、要不要連 Postgresql DB、要不要現在部署(請選 No,因為設定檔需要修改)
  4. fly launch 會建立一個 fly.toml,包含所有 VM 相關設定。Docker 容器無法長期保存資料,因此我們需要新增一個 [Volume]((https://fly.io/docs/reference/volumes/) 來放網站寫入的 logs.txt。使用以下指令建立一個 1GB 的空間(最小單位為 1GB):
    fly volumes create myapp_data --region lax --size 1
  5. 接著修改 fly.toml,將 internal_port=8080 改成 internal_port=80 (ASP.NET Core 部署到 Docker 時預設跑 80 Port),並加入 [mounts] 設定,將剛才建立的 myapp_data 掛載為 /app/data 路徑。
    [mounts]
      source="myapp_data"
      destination="/app/data"
    
    [[services]]
      http_checks = []
      internal_port = 80
      processes = ["app"]
    
  6. 程式部分稍做修改,原本檔案寫入路徑為 /app/logs.txt,配合 Volume 改為 /app/data/logs.txt:
    var dataFolder = Path.Combine(
        app.Environment.ContentRootPath, "data");
    Directory.CreateDirectory(dataFolder);
    var dataFilePath = Path.Combine(dataFolder, "logs.txt");
    if (!File.Exists(dataFilePath))
        File.WriteAllText(dataFilePath, "");
    
  7. 修改完成後,再跑一次 fly launch 或 fly deploy,fly CLI 將開始建置 Docker Image 上傳,並部署建立容器:
    PS X:\Github\AspNetCoreInDocker> fly launch
    An existing fly.toml file was found for app aspnetcore-in-docker
    App is not running, deploy...
    Deploying aspnetcore-in-docker
    ==> Validating app configuration
    --> Validating app configuration done
    Services
    TCP 80/443 ⇢ 80
    Remote builder fly-builder-muddy-shape-286 ready
    ==> Creating build context
    --> Creating build context done
    ==> Building image with Docker
    --> docker host: 20.10.12 linux x86_64
    [+] Building 0.1s (0/1)
    [+] Building 12.4s (13/13) FINISHED
     => [internal] load remote build context                     
     => copy /context /                                          
     => [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:6.0   
     => [internal] load metadata for mcr.microsoft.com/dotnet/sdk:6.0 
     => [build-env 1/5] FROM mcr.microsoft.com/dotnet/sdk:6.0@sha256:40fbffef1e2bc78e56cb5039035204a86e32872f07496c68e7ca9c6878eab18a 
     => => resolve mcr.microsoft.com/dotnet/sdk:6.0@sha256:40fbffef1e2bc78e56cb5039035204a86e32872f07496c68e7ca9c6878eab18a     
     => => sha256:bbc33ac2bbd6b04d3e94435b0fa531623f934890521cf8a4f4d59a672a1e76e7 15.17MB / 15.17MB 
     => => sha256:d84eb8e4a38fbc505f3adead9c9beb2f4ff13a671f0684005165b7178f401075 156B / 156B 
     ... 省略 ...                                                                                                                                                                                                 
     => => extracting sha256:d6210c1394f70c8befb3116568b20ed4e289fcdfdaa567e7bd5309d1a00d9bae 
     => => extracting sha256:4b055625c05434d5a8e21c7eb72f3b45e886db239e0f29a7aba223b403de8378 
     => [stage-1 1/3] FROM mcr.microsoft.com/dotnet/aspnet:6.0@sha256:88801f2e57709b9aa33336551a4b367d9d8692db6dd42612ca16f4f7424e3816   
     => => resolve mcr.microsoft.com/dotnet/aspnet:6.0@sha256:88801f2e57709b9aa33336551a4b367d9d8692db6dd42612ca16f4f7424e3816   
     => => sha256:bbc33ac2bbd6b04d3e94435b0fa531623f934890521cf8a4f4d59a672a1e76e7 15.17MB / 15.17MB      
     => => sha256:25554d842538a621137d9ed16f8b48c606a978ea80d4c455bcb5757ed46e54ee 31.62MB / 31.62MB   
     ... 省略 ...
     => => extracting sha256:d84eb8e4a38fbc505f3adead9c9beb2f4ff13a671f0684005165b7178f401075   
     => => extracting sha256:d0ac34266377c020aee8092add89b91d9dbceb62d3d3c49ff54f2abf39b2eab4   
     => [stage-1 2/3] WORKDIR /app                                                        
     => [build-env 2/5] WORKDIR /app                                                    
     => [build-env 3/5] COPY . ./                                                   
     => [build-env 4/5] RUN dotnet restore                                        
     => [build-env 5/5] RUN dotnet publish -c Release -o out                     
     => [stage-1 3/3] COPY --from=build-env /app/out .                            
     => exporting to image                                              
     => => exporting layers                                            
     => => writing image sha256:e4703dae9edf76e6b93d382ca75a06cfb72980103b40e0559b2f75b44d9ee53c   
     => => naming to registry.fly.io/aspnetcore-in-docker:deployment-01GCVPPNEZMZ90YQ3P233B4AEB  
    --> Building image done
    ==> Pushing image to fly
    The push refers to repository [registry.fly.io/aspnetcore-in-docker]
    511d266350d8: Pushed
    a8898723a70a: Pushed
    1bed68ac56ad: Pushed
    ca8fa5aaeb59: Pushed
    52c79685d4bb: Pushed
    c1d5a2a44dd3: Pushed
    b45078e74ec9: Pushed
    deployment-01GCVPPNEZMZ90YQ3P233B4AEB: digest: sha256:1a4ba316a391de6211db3183d8a9c6c13ea6662852f0038fccb29243c60bf640 size: 1787
    --> Pushing image done
    Image: registry.fly.io/aspnetcore-in-docker:deployment-01GCVPPNEZMZ90YQ3P233B4AEB
    Image size: 209 MB
    ==> Creating release
    Release v1 created
    
    You can detach the terminal anytime without stopping the deployment
    Monitoring Deployment
    
     1 desired, 1 placed, 1 healthy, 0 unhealthy [health checks: 1 total, 1 passing]
    --> v1 deployed successfully    
    
    註:過程遇到亂流,一開始出現 Error server returned a non-200 status code: 504,但多試幾次就成功了。

使用 fly open 可開啟網站,部署成功!

fly dashboard 則會開啟應用程式的管理面版,有 GUI 可以查看流量、記憶體使用量、CPU 負載等資訊:

Monitor 甚至可以看 ASP.NET Core 的 Information Log,超方便:

前面有說到,有些好用指令雖然免費但需要提供信用卡資料後才能使用,例如:要暫時停用 App,原本有個 fly suspend 指令被 fly scale count 0 取代,而 fly scale 需提供付款資訊才能用,大家自行拿捏囉。

Tutorial of deploying ASP.NET Core to Fly.io.


Comments

# by Ho.Chun

如果不去使用那些"好用指令",這樣是不是就不用綁信用卡了 ? 可以這樣理解嗎 ?

# by Ziv

今天試做 flyctl launch 要綁信用卡才行

# by Jeffrey

to Ziv, 我剛才測試還可以 fly launch 沒出現信用卡提示,但有個 Update available 0.0.390 -> v0.0.406 訊息,不知是否更新版本後會加入限制?

# by 小雞

請問有沒有不用綁信用卡的 雖然不會扣錢 但要綁還是覺得不舒服

Post a comment