14
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Visual Studio2022】.NETのプロジェクトをDockerで開発出来るようにする

Last updated at Posted at 2022-08-22

概要

Visual Studio2022で、Dockerサポート機能を使って、開発出来るようにする手順です。
実行する環境は以下の通りです。


OS:Windows11
プロジェクト:.NET Core Razor Pages
DB:MSSQL2019
Dockerバージョン:4.9.0

設定ファイルなどに含まれる、プロジェクト名などは、適宜書き換えてください。

プロジェクトをDockerコンテナ上で実行する

手順1. Dockerをインストールする

まずは、Dockerを公式サイトからインストールします。

手順2. プロジェクトの作成

新規プロジェクトを作成します。
今回はRazor Pageを選択して、プロジェクト名は「RazorPageSample」で作成します。
画像1.png

画面を進めていくと、追加情報という画面が表示されます。
「Dockerを有効にする」という項目に、チェックを入れて、OSはLinuxを選択しておきます。
画像2.png

作成が完了すると、デバッグ開始ボタンがDockerになっています。
Dockerfileは自動で生成されるので、このまま実行すれば、Dockerコンテナ上で実行され、いつも通りデバッグ可能な状態になります。
画像3.png

Dockerに関する操作をすることなく、簡単に設定出来てしまうため、本当にDockerコンテナ上で動いているか、OSバージョンを表示させて確認してみます。

Index.cshtml
@page
@model IndexModel
@{
    // OSの情報を取得する
    System.OperatingSystem os = System.Environment.OSVersion;
    ViewData["OS"] = os.ToString();

    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p class="display-6">OS:@ViewData["OS"]</p>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

画像4.png

.net6.0のイメージに使われているOSが、Debainになるので、Unixと表示されます。
以上の設定で、DBを使わないWebアプリなどであれば、簡単にDocker上で動かすことが出来ます。

補足

Dockerfileに下記の設定を追加すると、DateTimeで取得できる日時を、JSTのYYYY/MM/DD形式に変更できます。
.net6.0のイメージに使われているOSのタイムゾーンをJSTにして、言語を日本語にしています。
ENV TZ Asia/Tokyo
ENV DEBIAN_FRONTEND noninteractive
ENV LC_ALL ja_JP.UTF-8

RUN apt-get update
RUN apt-get install -y locales
RUN echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
    locale-gen ja_JP.UTF-8 && \
    dpkg-reconfigure locales && \
    /usr/sbin/update-locale LANG=ja_JP.UTF-8
Dockerfile
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base

# .net6.0のイメージに使われているOSがDebainで、以下の設定でタイムゾーンをJSTに変更して、日本語化している
ENV TZ Asia/Tokyo
ENV DEBIAN_FRONTEND noninteractive
ENV LC_ALL ja_JP.UTF-8

RUN apt-get update
RUN apt-get install -y locales
RUN echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
    locale-gen ja_JP.UTF-8 && \
    dpkg-reconfigure locales && \
    /usr/sbin/update-locale LANG=ja_JP.UTF-8

WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["RazorPageSample/RazorPageSample.csproj", "RazorPageSample/"]
RUN dotnet restore "RazorPageSample/RazorPageSample.csproj"
COPY . .
WORKDIR "/src/RazorPageSample"
RUN dotnet build "RazorPageSample.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "RazorPageSample.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "RazorPageSample.dll"]

画像15.png

プロジェクトのコンテナとDBコンテナを同時に立ち上げる

次に、プロジェクトのコンテナとDBコンテナを、同時に立ち上げる設定方法です。
大抵の場合は、DBが必要になってくると思うので、こちらの設定が必要になるかと思います。

手順1. コンテナーオーケストレーターサポートの追加

プロジェクトを右クリックして、追加からコンテナオーケストレーターサポートを追加をします。
コンテナーオーケストレーターは「Docker Compose」、ターゲットOSは、「Linux」を選択します。

画像5.png

手順2. docker-compose.ymlにDBコンテナの設定を追加

ソリューションエクスプローラーにdocker-compose.ymlというファイルが追加されます。
このファイルは、複数のコンテナを同時に立ち上げるのに使うファイルです。
デフォルトでは、プロジェクトのコンテナのみになっているので、DBコンテナも立ち上げるように設定を追加します。
docker-compose.yml
version: '3.4'

services:
  razorpagesample:
    image: ${DOCKER_REGISTRY-}razorpagesample
    build:
      context: .
      dockerfile: RazorPageSample/Dockerfile
    depends_on:
      - sqlexpress

  sqlexpress:
    image: mcr.microsoft.com/mssql/server:2019-latest
    environment:
        MSSQL_PID: "Express"
        ACCEPT_EULA: "Y"
        SA_PASSWORD: "P@ssw0rd"
        MSSQL_LCID: "1041"
        MSSQL_COLLATION: "Japanese_CI_AS"
    volumes:
        - "./db/mssqlserver/data:/var/opt/mssql/data"
        - "./db/mssqlserver/log:/var/opt/mssql/log"
        - "./db/mssqlserver/secrets:/var/opt/mssql/secrets"
        - "./db/mssqlserver/backup:/var/opt/mssql/backup"
    ports:
        - "1401:1433"

depends_on: - sqlexpressで、先にDBコンテナを立ち上げてから、プロジェクトのコンテナを立ち上げるようにしています。
あとは、パスワードを設定したり、日本語化設定を行っています。
volumes:の設定はDBの永続化設定になります。
こうすることで、DBコンテナが終了しても、DBのデータが消えないようにしています。dbフォルダはプロジェクトの直下に生成されます。

手順3. SSMSからDBコンテナにアクセスする

開始ボタンが、「Docker」から「Docker Compose」に変わっていると思います。
Dockerは、Dockerfileを元に実行されますが、Docker Composeの場合は、docker-compose.ymlを元にコンテナが実行されます。

画像7.png


一度、Docker Composeで実行します。
すると、プロジェクトのコンテナと、DBコンテナが立ち上がります。
コンテナの状況は、Docker DesktopのContainersから確認出来ます。
画像6.png

DBコンテナが起動していることを確認して、SSMSからDBコンテナにアクセスしてみます。
接続先情報は、先ほどdocker-compose.ymlで設定した通りです。
画像8.png
画像9.png

アクセス出来ました。
これで、Docker上で開発出来る環境が整ったので、試しに公式のチュートリアルを進めてみます。

手順4. ムービーモデルの作成

まずは、Razor Pagesの公式チュートリアルのムービー モデルのスキャフォールディングまで進めます。

手順5. DBコンテナに対して、EF の移行機能を使用して初期データベース スキーマを作成する

appsettings.jsonのDB接続先を、ローカルDBからDBコンテナに変更します。
appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RazorPageSampleContext": "Server=localhost,1401;Database=razor_sample_db;User ID=sa;Password=P@ssw0rd;initial catalog=razor_sample_db;MultipleActiveResultSets=True;App=EntityFramework;"
  }
}

スタートアッププロジェクトを「docker-compose」から「RazorPageSample」に切り替えてから、パッケージマネージャーコンソールで下記コマンドを実行します。
スタートアッププロジェクトを切り替えておかないと、コマンドが実行出来ません。

画像10.png

Add-Migration InitialCreate
Update-Database

コマンドが実行され、DBコンテナに初期データベースが作成されました。

画像11.png

手順6. appsettings.jsonを書き換える設定を追加

appsettings.jsonの接続先情報で、Docker Composeで実行すると、コンテナ自身のlocalhostを参照してしまい、DB接続エラーになってしまいます。
なので、ソリューションエクスプローラーから、docker-compose.ymlの下にある「docker-compose.override.yml」というファイルに、下記の通り設定して接続出来るようにします。
docker-compose.override.yml
version: '3.4'

services:
  razorpagesample:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - ConnectionStrings__RazorPageSampleContext=Server=sqlexpress;Database=razor_sample_db;User ID=sa;Password=P@ssw0rd;initial catalog=razor_sample_db;MultipleActiveResultSets=True;App=EntityFramework;
    ports:
      - "80"
      - "443"
    volumes:
      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro

実行するときに、appsettings.jsonのConnectionStrings > RazorPageSampleContextの値が、docker-compose.override.ymlで設定した内容に書き換わるようになります。

これで、Dockerコンテナ上で、データの登録、編集、削除が出来るようになります。
画像12.png

DockerコンテナからホストのDBに接続する方法

最後に、Dockerコンテナから、ホストのローカルSQL Serverに接続する方法です。
DBコンテナも一緒に立ち上げる方が簡単で、開発環境を統一しやすいメリットがあるので、あまり使わないかもしれません。

手順1. TCP/IPを有効にする

SQL Server構成マネージャーを開いて、TCP/IPを有効にします。
そして、TCP/IPのプロパティのIPAllの「TCP 動的ポート」を後で使うので、メモしておきます。

画像13.png

手順2. SQL Serverの再起動

SQL Serverのサービスから、SQL Serverの再起動をします。
画像14.png

手順3. 接続先を変更

appsettings.jsonのDB接続先を変更します。
appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RazorPageSampleContext": "Server=host.docker.internal,50489; Database=razor_sample_db; User ID=sa; MultipleActiveResultSets=true;App=EntityFramework;"
  }
}

localhost,1401;だった部分を、host.docker.internal,50489;に変更しています。
「host.docker.internal」はコンテナから、ホストのネットワークにアクセスするためのDNS名になります。ポート番号は、手順1. TCP/IPを有効にするで、メモしたポート番号を指定します。
あとは、ユーザーはsaのままで、パスワードは設定していないので、IDだけの指定になっています。

以上の設定で、ホストのローカルDBに繋がるようになるはずです。

14
24
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?