はじめに
DockerでNginxを使用したり、DockerでAsp.netで使用するというものはよくWeb検索すれば見つかるのですが、DockerでNginxとAsp.netを連携させたものは少なかったので、試行錯誤しながら作成してみました。
とりあえず動作確認できるところまで行ったので備忘録もかねて記事にまとめてみました。
環境
Visual Studio 2022
Windows 11
Docker Desktop
ASP.NET 6.0
構成イメージ
ASP.NET Core Web API作成
APIプロジェクトを作成します
DemoAPIという名前で作ります。
Visual Sdudioで新しいプロジェクトの作成をします。
テンプレートとしてASP.NET.Core Web APIを選択します。
設定の留意点としては以下の通り
HTTPSは今回は使用しない(Dockerネットワーク内のみで使用するので)
Dockerを有効にする
DemoControllerの作成
初期設定ではWeatherForecastControllerが作成されてSwagger画面が表示されて、動作確認がしにくいので、別にコントローラーを作成します
APIを選択して、読み取り/書き込みアクションがあるAPIコントローラーを選択します。名前はDemoControllerとします。
作成したコントローラーは、確認しやすいようにちょっと内容を書き換えておきます。(記事用に分かりやすくするためです)
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "デモです", "DemoAPIです" };
}
DemoAPIのDockerfileの変更
初期作成時は以下のようになっています。
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["DemoAPI/DemoAPI.csproj", "DemoAPI/"]
RUN dotnet restore "DemoAPI/DemoAPI.csproj"
COPY . .
WORKDIR "/src/DemoAPI"
RUN dotnet build "DemoAPI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "DemoAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DemoAPI.dll"]
この中でEXPOSE 80 に対する変更と、ENV行追加を行います。
変更後は以下の通りです
#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
WORKDIR /app
EXPOSE 5001 # ここが変更箇所 80 -> 5000
ENV ASPNETCORE_URLS=http://+:5001 # これが追加箇所
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["DemoAPI/DemoAPI.csproj", "DemoAPI/"]
RUN dotnet restore "DemoAPI/DemoAPI.csproj"
COPY . .
WORKDIR "/src/DemoAPI"
RUN dotnet build "DemoAPI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "DemoAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DemoAPI.dll"]
Nginxの作成
ソリューションから新しいソリューションフォルダを作成します。フォルダ名はNginxとしておきます。
ここで注意なのですが、プロジェクトを作成した場合は、そのプロジェクト名でフォルダが作成されるのですが、ソリューションフォルダを作成しても、実際のディレクトリにはフォルダは作成されません。
そのため、フォルダ分けをきちんとしたい場合は、以下のようにフォルダを直接作成するのをお勧めします。
demo.conf作成
作成したフォルダの中にdemo.confを作ります。
これは現時点ではテンプレートがないので、フォルダ内に作成して、それをVisual Studioから既存の項目の追加をします。中身は空っぽのデータです。(このあたりの作業はVisual Sudio Codeのほうが分かりやすいですね。Visual Studioのソリューションフォルダはちょっと特殊でとっつきにくく感じます)
demo.conf
以下のように記述します。
後述しますが、default.confを書き換えるのでこの記述なります。
web検索すると、http{}とか、events{}など記載しているものもありますが、default.confの場合はエラーになるようです。
server {
listen 80;
server_name default_server;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/demo/ {
proxy_pass http://demoapi:5001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Nginxにindex.html作成
普通にNginxを起動するとデフォルト画面になるので、せっかくですから、自分で作成したページが表示するようにしましょう。
Nginxにindex.htmlを作成します。既存項目の追加という作業でいきます。
<!DOCTYPE html>
<html lang="ja" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>デモページ</title>
</head>
<body>
<h2>表示できた~</h2>
</body>
</html>
Nginx用のDockerfile作成
さきほどのdemo.confを作成したのと同じように、フォルダにDockerfileを作成して、既存の項目で追加します。
Dockerfileに以下のように記述します
FROM nginx:latest
COPY ./Nginx/demo.conf /etc/nginx/conf.d/default.conf
COPY ./Nginx/index.html /var/www/html/index.html
nginx:latestにしていますが、nginx:alpineでも構いません。
docker-composeの作成
ここまででDockerについては出来上がっているので、次はdocker-composeで連携させていきます。
DemoAPIからdocker-compose作成
Visual Sudioによる自動作成をなるべく使っていきたいので、DemoAPIプロジェクトを右クリックして、追加⇒コンテナーおーすけとレーターのサポート...を選択します。LinuxをターゲットOSとします。
作成するとdocker-composeプロジェクトが作成されて、docker-compose.ymlとdocker-compose.override.ymlが作られていると思います。
docker-compose.yml
初期値は以下のようになっています
version: '3.4'
services:
demoapi:
image: ${DOCKER_REGISTRY-}demoapi
build:
context: .
dockerfile: DemoAPI/Dockerfile
apiだけなので、ここにnginxの設定を追加します
version: '3.4'
services:
demoapi:
image: ${DOCKER_REGISTRY-}demoapi
build:
context: .
dockerfile: DemoAPI/Dockerfile
# 以下が追加した部分
nginx:
image: ${DOCKER_REGISTRY-}nginx
build:
context: .
dockerfile: Nginx/Dockerfile
docker-compose.override.yml
docker-compsoe.ymlだけでもいいのですが、Visual Studioで作成した場合、このoverrideで内容の上書きができるようになっています。
使い方はいろいろですが、Visual Studioとしてはdocker-compose.ymlでdockerイメージとビルドが記述され、環境等がoverrideに記述されているようです。
最初に作った時はこのようになっているかと思います。
version: '3.4'
services:
demoapi:
environment:
- ASPNETCORE_ENVIRONMENT=Development
ports:
- "80"
これを以下のように変更します。分かりやすくするために本当に必要なものだけにしました。それぞれの設定・環境に合わせて、追加していくとよいと思います。
version: '3.4'
services:
demoapi:
expose:
- "5001"
networks:
- front-back
nginx:
ports:
- 80:80
networks:
- front-back
networks:
front-back:
driver: bridge
大切なのは、demoapiのportsをexposeにしているところです。portsは外部との通信で使用されますが、exposeにすることで、Docker内部だけでの通信となり、セキュリティが上がります。これをすることで、httpsではなくhttpでの内部通信のみでよいことになるので、最初にAPIを作成したときにhttpsを選択しなかったわけです。
実際にセキュリティをきちんとするためには、外部と通信するnginxをssl化してhttps通信をするように変更する必要がありますが、これについてはまた後日記事にしようと思います。
あと、ポートでexposeは"5001"、portsは80:80としていて、" " で囲んでいたりいなかったりという風にしていますが、これはどちらでもOKです。
" " で囲むのは64以下の場合に確か必要だったような記憶があります。違ってたらご指摘ください。
起動
ここまでで設定など問題なければビルドしてdocker-composeで起動します。
自分が起動したときに一部エラーが起きました。
内容はDockerfileにこの記事用に 「# ここが変更箇所」と書いたままにしていて、それがエラーの原因になりました。
こういったコメントや、スペースが入っているとエラーになるので、注意が必要です。
あと、おそらくこのまま実行するとこんなエラーが出るかもしれません。
これはDemoAPIが初期状態ではSwaggerを表示させようとするのですが、内部ポート(5001)だけにしているのでエラーとなります。
これが表示されても、Swagger使えないと言っているだけなのでOKで次に進んでも問題ありませんが、気になるので出ないようにします。
ポートの警告を出さないようにする
docker-composeプロジェクトを右クリックしてプロパティを表示させます。
おそらく以下の項目があると思いますので、これを削除してください。
<DockerServiceUrl>{Scheme}://localhost:{ServicePort}/swagger</DockerServiceUrl>