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...
https://fly.io/docs/hands-on/install-flyctl/
각 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
-------
ASP.NET CORE : Entity Framework Scaffold-DbContext Login failed for user (db 비밀번호 $ 문자 문제) (0) | 2024.07.09 |
---|---|
Docker : ASP.NET Core 앱이 작동하지 않는 이유? (2) | 2024.07.09 |
VISUAL STUDIO CODE 로 클래스라이브러리 및 ASP.NET CORE 8 MVC 구축하기 (2) | 2024.04.11 |
ASP.NET Core 8.0: Swagger UI Endpoints Securing 권한 부여로 보안강화 (MapSwagger().RequireAuthorization) (0) | 2024.01.23 |
QuickGrid for Blazor 알아보기 ( .NET 8) (0) | 2024.01.15 |