OcelotでDockerでマウントしたapiのルーティングで詰まったので備忘録

投稿者: | 2022年9月11日

仕事でDockerを使った環境でOcelot導入を頼まれたが詰まったのでメモ。

準備

プロジェクトの新規作成からスタート。

Dockerが必要なので「Dockerを有効にする」にチェックを入れます。

すると、こんな感じの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
WORKDIR /app
EXPOSE 80
EXPOSE 443

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

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

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

これでビルドの中にdocker-composeが出現して、Dockerにマウントする準備は整いました。

あとはマクロサービス(MicroA)とそれをルーティングするBFF(Bff)プロジェクトの2つを生成します。

Program.cs

BFFプロジェクトにnugetからOcelotを導入して、Program.csを下記のように書き換えます。(具体的には// !!これを追加!!のコメント部分を追加しています。)
あとは、ocelot.jsonファイルを作成して準備完了。

using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo()
    {
        Title = "GW",
        Version = "v1"
    });
});

//builder.Configuration.AddJsonFile(Path.Combine("configuration", "configuration.json"));
builder.Configuration.AddJsonFile("ocelot.json"); // !!これを追加!!
builder.Services.AddOcelot(); // !!これを追加!!

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger().UseSwaggerUI(c =>
    {
       // c.SwaggerEndpoint("/a/swagger/v1/swagger.json", "APIServiceA");
    });
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.UseOcelot().Wait(); // !!これを追加!!

app.Run();

マルチターゲットで稼働する

Dockerを使わずにBFFとmicroAサービスを同時に起動する場合は下記の設定で問題ありませんでした。

docker-compose.yml

version: '3.4'

services:
  microa:
    image: ${DOCKER_REGISTRY-}microa
    build:
      context: .
      dockerfile: MicroA/Dockerfile

  bff:
    image: ${DOCKER_REGISTRY-}bff
    build:
      context: .
      dockerfile: Bff/Dockerfile
     

docker-compose.override.yml

version: '3.4'

services:
  microa:
    hostname: microa
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "8081:80"
      - "8082:443"

  bff:
    hostname: bff
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "8083:80"
      - "8084:443"
  

ocelot.json

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/weatherForecast",
      "UpstreamPathTemplate": "/api/v1/weatherForecast",
      "DownstreamScheme": "http",
      "UpstreamHttpMethod": [ "Get" ],
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 8081
        }
      ]
    }
  ]
}

Dockerで稼働する

上記の設定のままでDocker-composeで起動するとルーティングが上手くいかなかった。

docker-compose.override.ymlにdepends_onの設定を追加し、ocelot.jsonのDownstreamHostAndPortsの値を変更すると上手くいった。

docker-compose.override.yml

version: '3.4'

services:
  microa:
    hostname: microa
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "8081:80"
      - "8082:443"

  bff:
    hostname: bff
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "8083:80"
      - "8084:443"
    depends_on:
      -  microa
 

ocelot.json

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/weatherForecast",
      "UpstreamPathTemplate": "/api/v1/weatherForecast",
      "DownstreamScheme": "http",
      "UpstreamHttpMethod": [ "Get" ],
      "DownstreamHostAndPorts": [
        {
          "Host": "microa",
          "Port": 80
        }
      ]
    }
  ]
}

Daprで稼働

余談ですがDapr使う場合はこんな感じ?自分用のメモ程度なので参考にはならないと思います。

docker-compose.yml

version: '3.4'

services:
  microa:
    image: ${DOCKER_REGISTRY-}microa
    build:
      context: .
      dockerfile: MicroA/Dockerfile
      
  microa-dapr:
    image: "daprio/daprd:latest"
    network_mode: "service:microa"
    depends_on:
      -  microa

  bff:
    image: ${DOCKER_REGISTRY-}bff
    build:
      context: .
      dockerfile: Bff/Dockerfile
      
  bff-dapr:
    image: "daprio/daprd:latest"
    network_mode: "service:bff"
    depends_on:
      -  bff

docker-compose.override.yml

version: '3.4'

services:
  microa:
    hostname: microa
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "8081:80"
      - "8082:443"

  microa-dapr:
    command: ["./daprd",
    "-app-id", "microa",
    "-app-port", "80"]

  bff:
    hostname: bff
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "8083:80"
      - "8084:443"
    depends_on:
      -  microa
 
  bff-dapr:
    command: ["./daprd",
    "-app-id", "bff",
    "-app-port", "80"]

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)