「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>Github上の成果物]] -戻る([[Docker]] / [[.NET Core on Linux]] / [[Github上の成果物]]) --[[ASP.NET Coreをコンテナ化する際の設定ポリシー]] --ASP.NET Coreをスクラッチでコンテナ化する際の手順 *目次 [#c0c09feb] #contents *概要 [#fcae2f60] 生成AIを活用しスクラッチでコンテナ化する際の手順をメモ *詳細 [#t0574a42] -ASP.NET Core アプリケーションのコンテナ化を[[ツール>https://techinfoofmicrosofttech.osscons.jp/index.php?Visual%20Studio%20Tools%20for%20Docker]]に頼らず手動で行う。 -[[コチラ>https://techinfoofmicrosofttech.osscons.jp/index.php?.NET%20Core%E3%81%AEDocker%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E5%8C%96]]を確認すると、むしろ手動でないと問題になりそう(開発用は仕込みが多過ぎる)。 **[[Dockerファイル]]の作成 [#x64bcbd0] プロジェクト・ルートに Dockerfile を作成 ***ソース [#ib9f9929] dockerfile# ビルドステージ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src # プロジェクト・ファイルをコピーして依存関係を復元 COPY ["MyApp.csproj", "."] RUN dotnet restore "./MyApp.csproj" # ソースコードをコピーしてビルド COPY . . RUN dotnet build "MyApp.csproj" -c Release -o /app/build # 発行ステージ FROM build AS publish RUN dotnet publish "MyApp.csproj" -c Release -o /app/publish /p:UseAppHost=false # 実行ステージ(軽量イメージ) FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final WORKDIR /app EXPOSE 8080 COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "MyApp.dll"] ***解説 [#s1de94fb] ※ マルチステージ・ビルドという手法を使っている。 -ステージ1: build --buildステージを初期化~ 各種のSDKを含む開発用の重量級イメージ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build --buildステージの「カレント・ディレクトリ」を設定 WORKDIR /src --初めに、プロジェクト・ファイルをコピーして依存関係を復元 COPY ["MyApp.csproj", "."] RUN dotnet restore "./MyApp.csproj" --次に、ソース全体をコピーしてReleaseビルド COPY . . RUN dotnet build "MyApp.csproj" -c Release -o /app/build -ステージ2: publish --publishはbuildステージを引き継ぐ FROM build AS publish --/app/publish へ本番用の成果物を生成~ (/p:UseAppHost=false は、OS依存の実行ファイルを生成しない設定) RUN dotnet publish "MyApp.csproj" -c Release -o /app/publish /p:UseAppHost=false -ステージ3: final(実行用・軽量ステージ) --finalステージを初期化~ SDKを含まないランタイム専用の軽量イメージ FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final --コンテナ内の「カレント・ディレクトリ」を設定 WORKDIR /app --ポート公開 EXPOSE 8080 --publishステージで作られた成果物だけを取り込む COPY --from=publish /app/publish . --アプリ起動 ENTRYPOINT ["dotnet", "MyApp.dll"] ※ COPYコマンドのポイント -角括弧を使うと、JSON配列形式で、スペースを含むパスを正確に扱える。 --COPY My App/MyApp.csproj . --COPY ["My App/MyApp.csproj", "."] -左右のオペランド --COPY <ホスト側(コピー元)> <コンテナ側(コピー先)> --COPY --from=前ステージ名 <前ステージ側(コピー元)> <現ステージ側(コピー先)> **.dockerignoreの作成 [#q752a553] ***ソース [#w683e16a] **/bin/ **/obj/ **/out/ .git/ .vs/ *.user ***解説 [#e390d627] 不要なファイルをビルドコンテキストから除外。 **[[Dockerコマンド]]で実行 [#g3e94584] ***準備 [#k5b5fc4e] -Dockerfileをビルドし名称付与されたイメージを生成 docker build -t myapp:latest . -使用する場合は、[[Dockerコンポーズを定義>#bd5d88af]]する。 ***実行 [#r6de27c8] -[[Dockerコマンド]]によるコンテナ起動 docker run -d -p 8080:8080 --name myapp myapp:latest -[[Dockerコマンド]]によるコンテナ起動 docker compose up -d -ログ確認 docker logs myapp -コンテナに入る docker exec -it myapp /bin/bash **[[Dockerコンポーズ]] [#bd5d88af] プロジェクト・ルートに docker-compose.yml を作成 ***例1 [#h0721ef4] 最も簡潔な例 version: '3.8' services: ap: build: context: . dockerfile: Dockerfile ports: - "8080:8080" environment: - ASPNETCORE_ENVIRONMENT=Production - ConnectionStrings__Default=Server=db;Database=MyDb;... depends_on: - db db: image: mcr.microsoft.com/mssql/server:2022-latest environment: - SA_PASSWORD=YourPassword123! - ACCEPT_EULA=Y ports: - "1433:1433" ***例2 [#r5664ea1] 2つのファイルを使用する場合 -定義 --DB側 version: '3.8' services: db: image: mcr.microsoft.com/mssql/server:2022-latest environment: - SA_PASSWORD=YourPassword123! - ACCEPT_EULA=Y ports: - "1433:1433" networks: - shared-net networks: shared-net: name: myapp-network # 固定名を指定(server側から参照するため) driver: bridge ※ 各サービスは「参加する」ネットワークを指定し、末尾で、そのネットワークの「定義」する。~ ※ driver: bridge は networks のデフォルト値なので、今回のケースでは書かなくても動作は同じ。 --AP側 version: '3.8' services: ap: build: context: . dockerfile: Dockerfile ports: - "8080:8080" environment: - ASPNETCORE_ENVIRONMENT=Production - ConnectionStrings__Default=Server=db;Database=MyDb;... networks: - shared-net networks: shared-net: name: myapp-network # db側と同じ名前を指定する。 external: true # 新規作成せず、既存を使う。 ※ ファイルを跨いだ depends_on は使えないため削除する。 -起動・停止 --起動 # 1. まずDBを起動 docker compose -f docker-compose.db.yml up -d # 2. DBが準備できたらサーバーを起動 docker compose -f docker-compose.server.yml up -d --停止 # 停止する場合(逆順) docker compose -f docker-compose.server.yml down docker compose -f docker-compose.db.yml down ※ ネットワークはコマンドで作成してファイル中は全て「external: true」にすると起動順は任意になる。 docker network create --driver bridge shared-net **ホストビルド方式 [#w5b2ba11] -ホストビルド方式では、コンテナ内部ではなく、ホストOS(WindowsやLinux上)側でビルドした生成物をコンテナに詰める方式。 -ホストでpublishした内容をコンテナに詰める方式なので、プロジェクト出力以外は別途コピーする必要がある。 -Dockerfile中にビルド・スクリプトを長々書く必要がないので良い。非常にメジャーな構成。 -CI/CDパイプラインでも一度ビルド・サーバ(Linux)で全ビルドを行い、ソレをコンテナに詰める方が楽。 -発展系の方式として、ビルド・サーバ自体をコンテナ化して「環境のドリフト」を防ぐと言う方法もある。 ***Dockerファイル [#a00f35e6] # 実行ステージ(軽量イメージのみ) FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final WORKDIR /app EXPOSE 8080 COPY ./publish . ENTRYPOINT ["dotnet", "MyApp.dll"] ***ビルド&イメージ作成の手順 [#z4d347d5] -1. ホストでビルド・発行 dotnet publish "MyApp.csproj" -c Release -o ./publish /p:UseAppHost=false -2. Dockerイメージをビルド docker build -t myapp .