재우니의 블로그

ASP.NET CORE 8 : FLY.IO 설치 및 배포하기

 

Run a .NET App

 

https://fly.io/docs/languages-and-frameworks/dotnet/#generate-the-net-application

 

 

 

powershell 을 통해 dotnet new web 명령어를 통해서 asp.net core 8.0 을 만들고  dotnet run 명령어를 통해 웹화면에서 실행된 내용을 확인할 수 있습니다.

 

PowerShell 7.4.2
PS E:\sampleSource\Flyio> dotnet new web --name npmdotnet
"ASP.NET Core 비어 있음" 템플릿이 성공적으로 생성되었습니다.

생성 후 작업 처리 중...
E:\sampleSource\Flyio\npmdotnet\npmdotnet.csproj 복원 중:
  복원할 프로젝트를 확인하는 중...
  E:\sampleSource\Flyio\npmdotnet\npmdotnet.csproj을(를) 58 ms 동안 복원했습니다.
복원에 성공했습니다.

PS E:\sampleSource\Flyio> cd npmdotnet
PS E:\sampleSource\Flyio\npmdotnet> dotnet run
빌드하는 중...
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5229
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: E:\sampleSource\Flyio\npmdotnet
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...

 

 

fly cli 설치 가이드

 

https://fly.io/docs/hands-on/install-flyctl/

 

 

FLY.IO 배포하기

 

각 Fly 앱에는 배포 방법을 시스템에 알려주는 fly.toml 파일이 필요합니다. 해당 파일은 fly launch 명령을 사용하여 자동으로 생성될 수 있습니다. 이 명령은 배포용 Dockerfile 도 생성합니다.

 

PS E:\sampleSource\Flyio\npmdotnet> fly launch
Scanning source code
Detected a .NET app
Creating app in E:\sampleSource\Flyio\npmdotnet
We're about to launch your .NET app on Fly.io. Here's what you're getting:

Organization: luckshim               (fly launch defaults to the personal org)
Name:         npmdotnet              (derived from your directory name)
Region:       Singapore, Singapore   (this is the fastest region for you)
App Machines: shared-cpu-1x, 1GB RAM (most apps need about 1GB of RAM)
Postgres:     <none>                 (not requested)
Redis:        <none>                 (not requested)
Sentry:       false                  (not requested)
? Do you want to tweak these settings before proceeding? Yes
Opening https://fly.io/cli/launch/a69ac7a33e699d15dc56861e82ad080f ...

Waiting for launch data... Done
Created app 'npmdotnet' in organization 'personal'
Admin URL: https://fly.io/apps/npmdotnet
Hostname: npmdotnet.fly.dev
Wrote config file fly.toml
Validating E:\sampleSource\Flyio\npmdotnet\fly.toml
✓ Configuration is valid
==> Building image
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Remote builder fly-builder-purple-fire-5397 ready
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Remote builder fly-builder-purple-fire-5397 ready
==> Building image with Docker
--> docker host: 24.0.7 linux x86_64
[+] Building 14.7s (14/14) FINISHED
 => [internal] load .dockerignore                                                                                  0.3s
 => => transferring context: 116B                                                                                  0.3s
 => [internal] load build definition from Dockerfile                                                               0.3s
 => => transferring dockerfile: 623B                                                                               0.3s
 => [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:8.0                                               0.2s
 => [internal] load metadata for mcr.microsoft.com/dotnet/sdk:8.0-alpine                                           0.4s
 => [build 1/5] FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine@sha256:c4273e19738132e5cf1038a273644cadb0aa8ab1932e9  7.3s
 => => resolve mcr.microsoft.com/dotnet/sdk:8.0-alpine@sha256:c4273e19738132e5cf1038a273644cadb0aa8ab1932e9fb7ca5  0.0s
 => => sha256:34a7f10e38a45b7378af7a2cc7d2f85be75597cf53493c8f37d05715ae4ff243 20.48MB / 20.48MB                   0.4s
 => => sha256:5d298256e60cb506445d11627405e98490f075c3964ffd0a705f36fade8d5d71 2.01kB / 2.01kB                     0.0s
 => => sha256:4abcf20661432fb2d719aaf90656f55c287f8ca915dc1c92ec14ff61e67fbaf8 3.41MB / 3.41MB                     0.1s
 => => sha256:7bd7045ee784decbd1b7d7953deb19a7e0d94e9633b3b964fdc77eb881dbeb35 11.03MB / 11.03MB                   0.2s
 => => sha256:7573946fa12bc094350502288f4a3f10487cfa2e5251581dd2a4b714a40fec9f 1.24kB / 1.24kB                     0.1s
 => => sha256:e3db45edd5b64def72ad6de8ff05775a1ad9a2d0e203fdc5e58e2fd3bd8c27ad 32.25MB / 32.25MB                   0.5s
 => => sha256:4494aaa5a2f8ceb848e6a356fdb5802cddb2889fb8e4f4557f8d0658bf2c0678 187.60MB / 187.60MB                 2.5s
 => => sha256:7e684cc966247731c9267a443125e26030ff274caa5e06fd198434ed7fdd69d2 16.14MB / 16.14MB                   0.3s
 => => sha256:c4273e19738132e5cf1038a273644cadb0aa8ab1932e9fb7ca5491025e0e07fe 1.08kB / 1.08kB                     0.0s
 => => sha256:2597fff68151228710dc8edc9a02c1c13d7c7df3064ba21ca77cd73f97d19606 6.46kB / 6.46kB                     0.0s
 => => sha256:aa30b34b64bd28c6fc7ba13f4d92ff47f304714da5eecb027cd9ca62cb78df10 1.15MB / 1.15MB                     0.0s
 => => extracting sha256:4abcf20661432fb2d719aaf90656f55c287f8ca915dc1c92ec14ff61e67fbaf8                          0.2s
 => => extracting sha256:aa30b34b64bd28c6fc7ba13f4d92ff47f304714da5eecb027cd9ca62cb78df10                          0.0s
 => => extracting sha256:7573946fa12bc094350502288f4a3f10487cfa2e5251581dd2a4b714a40fec9f                          0.0s
 => => extracting sha256:e3db45edd5b64def72ad6de8ff05775a1ad9a2d0e203fdc5e58e2fd3bd8c27ad                          0.6s
 => => extracting sha256:7bd7045ee784decbd1b7d7953deb19a7e0d94e9633b3b964fdc77eb881dbeb35                          0.2s
 => => extracting sha256:34a7f10e38a45b7378af7a2cc7d2f85be75597cf53493c8f37d05715ae4ff243                          0.5s
 => => extracting sha256:4494aaa5a2f8ceb848e6a356fdb5802cddb2889fb8e4f4557f8d0658bf2c0678                          4.3s
 => => extracting sha256:7e684cc966247731c9267a443125e26030ff274caa5e06fd198434ed7fdd69d2                          0.4s
 => [internal] load build context                                                                                  0.3s
 => => transferring context: 2.06kB                                                                                0.3s
 => CACHED [stage-1 1/3] FROM mcr.microsoft.com/dotnet/aspnet:8.0@sha256:acb8f8e836ae3ba350d37edcfdfafb7bb6e58363  0.0s
 => [stage-1 2/3] WORKDIR /app                                                                                     0.0s
 => [build 2/5] WORKDIR /src                                                                                       0.0s
 => [build 3/5] COPY . ./                                                                                          0.0s
 => [build 4/5] RUN dotnet restore                                                                                 1.5s
 => [build 5/5] RUN dotnet publish -c Release -o /app                                                              4.8s
 => [stage-1 3/3] COPY --from=build /app .                                                                         0.0s
 => exporting to image                                                                                             0.0s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:7bbc7ea834fae1530a74df542ce2a21a5f0e58096b47d2323314ef61f445b995                       0.0s
 => => naming to registry.fly.io/npmdotnet:deployment-01HXF4V9FNQT35DCAFBNPDHRJQ                                   0.0s
--> Building image done
==> Pushing image to fly
The push refers to repository [registry.fly.io/npmdotnet]
4e2c2b919ed5: Pushed
d615b777acee: Pushed
2200575a6de5: Pushed
5dfd481b0bf1: Pushed
c75c7f2b5118: Pushed
047e0007fcf5: Pushed
ae3d04994a15: Pushed
52ec5a4316fa: Pushed
deployment-01HXF4V9FNQT35DCAFBNPDHRJQ: digest: sha256:5b290d245a6d37e3ad2e14b44c9a19db49a50964a84dfbf3ab8c3e5a9e2d62f5 size: 1995
--> Pushing image done
image: registry.fly.io/npmdotnet:deployment-01HXF4V9FNQT35DCAFBNPDHRJQ
image size: 217 MB

Watch your deployment at https://fly.io/apps/npmdotnet/monitoring

Provisioning ips for npmdotnet
  Dedicated ipv6: 2a09:8280:1::34:f834:0
  Shared ipv4: 66.241.124.23
  Add a dedicated ipv4 with: fly ips allocate-v4

This deployment will:
 * create 2 "app" machines

No machines in group app, launching a new machine
Creating a second machine to increase service availability
Finished launching new machines
-------
NOTE: The machines for [app] have services with 'auto_stop_machines = true' that will be stopped when idling

-------
Checking DNS configuration for npmdotnet.fly.dev

Visit your newly deployed app at https://npmdotnet.fly.dev/

 

 

먼저 fly.toml 파일이 생성되는 것을 볼 수 있습니다. 이는 배포 할 경우, region 이나  app 이름을 지정하거나 http 의 서비스의 각 기능들을 기술한 부분입니다. 여기서 primary_region 에 nrt 의미는 seoul 이 없어서 일본 도쿄를 지정한 부분입니다.

 

 

 

==> Building image with Docker
--> docker host: 24.0.7 linux x86_64

 

운영체제는 linux 에서 자동 설치되는것을 보실 수 있습니다.

 

 

This deployment will:
 * create 2 "app" machines

 

그리고 2대의 app 머신이 작동되는것을 보실 수 있습니다. 

 

 

 

아래는 생성된 Dockerfile 내용을 보여드립니다. 

 

# Adjust DOTNET_OS_VERSION as desired
ARG DOTNET_OS_VERSION="-alpine"
ARG DOTNET_SDK_VERSION=8.0

FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_SDK_VERSION}${DOTNET_OS_VERSION} AS build
WORKDIR /src

# copy everything
COPY . ./
# restore as distinct layers
RUN dotnet restore
# build and publish a release
RUN dotnet publish -c Release -o /app

# final stage/image
FROM mcr.microsoft.com/dotnet/aspnet:${DOTNET_SDK_VERSION}
ENV ASPNETCORE_URLS http://+:8080
ENV ASPNETCORE_ENVIRONMENT Production
EXPOSE 8080
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT [ "dotnet", "npmdotnet.dll" ]

 

 

재 배포해 보기

 

소스를 변경한 다음, 배포를 해보겠습니다. 이제는 fly deploy 명령어를 통해 바로 배포 진행하였습니다. 

PS E:\sampleSource\Flyio\npmdotnet> fly deploy
==> Verifying app config
Validating E:\sampleSource\Flyio\npmdotnet\fly.toml
✓ Configuration is valid
--> Verified app config
==> Building image
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Remote builder fly-builder-purple-fire-5397 ready
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Waiting for remote builder fly-builder-purple-fire-5397...
Remote builder fly-builder-purple-fire-5397 ready
==> Building image with Docker
--> docker host: 24.0.7 linux x86_64
[+] Building 7.7s (14/14) FINISHED
 => [internal] load build definition from Dockerfile                                                               0.4s
 => => transferring dockerfile: 623B                                                                               0.4s
 => [internal] load .dockerignore                                                                                  0.4s
 => => transferring context: 116B                                                                                  0.4s
 => [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:8.0                                               0.0s
 => [internal] load metadata for mcr.microsoft.com/dotnet/sdk:8.0-alpine                                           0.1s
 => [build 1/5] FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine@sha256:c4273e19738132e5cf1038a273644cadb0aa8ab1932e9  0.0s
 => [stage-1 1/3] FROM mcr.microsoft.com/dotnet/aspnet:8.0@sha256:acb8f8e836ae3ba350d37edcfdfafb7bb6e583630672faa  0.0s
 => [internal] load build context                                                                                  0.2s
 => => transferring context: 429B                                                                                  0.2s
 => CACHED [build 2/5] WORKDIR /src                                                                                0.0s
 => [build 3/5] COPY . ./                                                                                          0.0s
 => [build 4/5] RUN dotnet restore                                                                                 1.6s
 => [build 5/5] RUN dotnet publish -c Release -o /app                                                              5.1s
 => CACHED [stage-1 2/3] WORKDIR /app                                                                              0.0s
 => [stage-1 3/3] COPY --from=build /app .                                                                         0.0s
 => exporting to image                                                                                             0.0s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:648794fb1bf9fa0c0ca710f9238899a7efcf84d542f3835257987d9dc16ed0e7                       0.0s
 => => naming to registry.fly.io/npmdotnet:deployment-01HXF50K5V64S858JKN58YZWG5                                   0.0s
--> Building image done
==> Pushing image to fly
The push refers to repository [registry.fly.io/npmdotnet]
faf2fbd59250: Pushed
d615b777acee: Layer already exists
2200575a6de5: Layer already exists
5dfd481b0bf1: Layer already exists
c75c7f2b5118: Layer already exists
047e0007fcf5: Layer already exists
ae3d04994a15: Layer already exists
52ec5a4316fa: Layer already exists
deployment-01HXF50K5V64S858JKN58YZWG5: digest: sha256:c8decd35aa129595fe81fb908ba8bb8657fc9f8a6e44ac124769773b3afef346 size: 1995
--> Pushing image done
image: registry.fly.io/npmdotnet:deployment-01HXF50K5V64S858JKN58YZWG5
image size: 217 MB

Watch your deployment at https://fly.io/apps/npmdotnet/monitoring

-------
Updating existing machines in 'npmdotnet' with rolling strategy

-------
 ✔ [1/2] Machine 6833023b77d538 [app] update succeeded
 ✔ [2/2] Machine 7842303a277758 [app] update succeeded
-------
Checking DNS configuration for npmdotnet.fly.dev

Visit your newly deployed app at https://npmdotnet.fly.dev/
PS E:\sampleSource\Flyio\npmdotnet>

 

 

2대의 머신은 순차적으로 하나씩 재가동 하여 배포됩니다.

 

-------
 ✔ [1/2] Machine 6833023b77d538 [app] update succeeded
 ✔ [2/2] Machine 7842303a277758 [app] update succeeded
-------