旅の途中、興味深いオアシスを見つけた。忘れないうちに、この羊皮紙に記しておくとしよう。
Windows、そしてLinux。二つの広大な大地を旅した後、私はついに、gRPCのゴーレムを召喚する、究極の祭壇に辿り着いた。その名は「Docker」。あらゆる環境の差異を吸収し、どこにでも持ち運べる、異次元の箱庭だ。
今回は、これまでの旅で得た知見を元に、このDockerという箱庭の中で、gRPCサーバというゴーレムを錬成する。自己署名証明書という結界を自ら創り出し、コンテナの中で魂を安全に稼働させる、その儀式の全てを、未来の錬金術師たちのために記そう。
この羊皮紙のあらまし
- この羊皮紙のあらまし
- この羊皮紙が導く者
- 第一の儀式:結界の創造(自己署名証明書)
- 第二の儀式:魂の設計図(ソースコード)
- 最終儀式:魂の召喚と対話
- 羊皮紙を巻く前に
- 砂漠で見つけた魔法のランプ
- ラクダの独り言
この羊皮紙が導く者
- gRPCという名のゴーレムを、Dockerというポータブルな器に封じ込めたいと願う者
- HTTP/2という光の道を、コンテナを越えて繋げたい探求者
第一の儀式:結界の創造(自己署名証明書)
HTTPSという聖なる光でゴーレムを護るには、まず「証明書」という名の結界が必要だ。opensslの古の呪文を三度唱え、我々は自らの手で、この儀式に不可欠な結界を創り出す。
# 秘密鍵という、結界の核を創る $ openssl genrsa 2048 > ssl_greeter.key # 証明書発行要求という、神々への願いを記す $ openssl req -new -key ssl_greeter.key -out ssl_greeter.csr # 自らの力で、願いを成就させ、証明書を創り出す $ openssl x509 -days 3650 -in ssl_greeter.csr -req -signkey ssl_greeter.key -out ssl_greeter.crt
第二の儀式:魂の設計図(ソースコード)
次に、ゴーレムの魂の設計図を、現代の言葉で記していく。
世界の契約書:docker-compose.yml
この箱庭の世界全体の理を定義する。ゴーレムにgreeterという名を与え、外界との魂の通り道(ポート)を定め、先ほど創り出した結界(証明書)を、コンテナ内の聖域へと共有する。
version: '3.8' services: #gRPC (ASP.NET Core) app: container_name: 'greeter' build: context: ./src dockerfile: Dockerfile ports: - "5094:80" - "7094:443" environment: TZ: Asia/Tokyo volumes: - ./ssl_greeter.crt:/etc/ssl/certs/ssl_greeter.crt - ./ssl_greeter.key:/etc/ssl/private/ssl_greeter.key tty: true restart: always stdin_open: true
魂の錬成工程:Dockerfile
ゴーレムの魂を、どのように錬成するかを記した、最も重要な羊皮紙だ。sdkという名の広大な工房で魂を鍛え上げ、完成した魂を、aspnetという名の、より軽量で戦闘に特化した器へと移し替える。
# 本番用の器(.NET6 runtime) FROM mcr.microsoft.com/dotnet/aspnet:6.0-focal AS runtime ENV ASPNETCORE_URLS=http://+:80;https://+:443 EXPOSE 80 EXPOSE 443 # 魂を鍛える工房(sdk) FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build ARG DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=0 WORKDIR /src COPY ["./GrpcGreeter/GrpcGreeter.csproj", "GrpcGreeter/"] RUN dotnet restore "./GrpcGreeter/GrpcGreeter.csproj" COPY . . WORKDIR "/src/GrpcGreeter" RUN dotnet build "GrpcGreeter.csproj" -c Release -o /app/build # 鍛え上げた魂を工房から取り出す FROM build AS publish RUN dotnet publish "GrpcGreeter.csproj" -c Release -o /app/publish # 魂を、本番用の器へと移し替える FROM runtime AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "GrpcGreeter.dll"]
(注:上記Dockerfileは、./src/GrpcGreeter/配下にcsprojファイルがある前提の記述です)
魂の契約:appsettings.json
ゴーレムに、自らが護られるべき結界(証明書)の場所を教える。
{ "Kestrel": { "Certificates": { "Default": { "Path": "/etc/ssl/certs/ssl_greeter.crt", "KeyPath": "/etc/ssl/private/ssl_greeter.key" } } } }
最終儀式:魂の召喚と対話
全ての設計図が揃ったら、docker-compose buildで魂を錬成し、docker-compose up -dで箱庭に魂を召喚する。
docker-compose logsコマンドで、ゴーレムが正常に起動し、力強く鼓動しているのがわかるだろう。
$ docker-compose logs grpc | INFO : Now listening on: http://[::]:80 grpc | INFO : Now listening on: https://[::]:443 grpc | INFO : Application started. Press Ctrl+C to shut down. ...
二つの光の道(ポート80と443)で、来訪者を待ち構えている。これこそが、魂が正常に宿った証だ。
Windowsの世界から、gRPCクライアントという名の魔法で、箱庭の中のゴーレムと対話する。
172.18.126.178:7094という、異次元への座標を指定し、HttpClientHandlerで結界への信頼を宣言すれば、二つの世界は光の道で結ばれる。
// 異次元の座標 var server = "https://172.18.126.178:7094"; var option = new GrpcChannelOptions() { HttpClient = new HttpClient(new HttpClientHandler { // 自己署名証明書という結界を、信頼する ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator, }) }; var channel = GrpcChannel.ForAddress(server, option); // ...

羊皮紙を巻く前に
Windows、Linux、そしてDocker。三つの大地を旅し、我々はついに、どこにでも持ち運べる、堅牢なgRPCゴーレムを錬成する術を手に入れた。
Docker版では、launchSettings.jsonというローカルな呪文に頼らず、ASPNETCORE_URLSという、より普遍的な環境変数でゴーレムを制御できることも、大きな学びだった。
この後、我々の旅は、この城塞の前にNginxという鉄壁の門番を配置する、さらなる冒険へと続いていく。
この羊皮紙が、同じように異次元の箱庭で魂を錬成しようと挑む、未来の冒険者の助けとなることを願う。
おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。
砂漠で見つけた魔法のランプ
- 前回の冒険の記録(Windows版)
- 前回の冒険の記録(Linux版)
- Dockerのインストールに関する古文書
- ASP.NET Core gRPC 公式の古文書
- Kestrelエンドポイントに関する賢者の言葉
- NLogとASP.NET Core 6に関する賢者の言葉
ラクダの独り言
ご主人が「どっかー」とかいう、透明な箱の中にゴーレムを創り出して、悦に入っている。なんでも、この箱ごとどこへでも持っていけるらしい。俺に言わせりゃ、そんな面倒なことしなくても、俺の背中に乗せりゃどこへでも運んでやるのによ。まったく、人間ってのは、便利なようで不便なことをするのが好きだな。やれやれだぜ。