たびとの旅路 ~電脳砂漠の冒険譚~

フロッピー頼りに歩き、クラウドの地平を見つめる今日まで。見つけたオアシス、迷い込んだ砂の迷宮、全てこの羊皮紙に。

魂に、定刻の鼓動を ~Dockerfileとcronで操る、.NETバッチ処理~

旅の途中、興味深いオアシスを見つけた。忘れないうちに、この羊皮紙に記しておくとしよう。

「一定間隔で、自動的に魔法を発動させたい…」 かつて私がAIシステムという巨大なゴーレムを創り上げた時、この切実な問題に直面した。情報の砂漠を彷徨い、試行錯誤の末に辿り着いた答え。それは、.NET 6(Microsoftの開発フレームワーク)で創り上げた魂を、Dockerfile(イメージビルド定義)でビルドし、cron(UNIX定期実行デーモン)という古の魔法で、定刻に呼び覚ますというものだった。

今回は、WSL2 Ubuntu(Windows上のLinux環境)という名の祭壇で、その儀式の全てを再現する。これは、単なるバッチ処理(定期実行処理)ではない。コンテナ(隔離実行環境)という異次元の箱庭で、魂の錬成から、その魂に周期的な鼓動を与えるまでを、一気通貫で執り行う、壮大な錬金術の記録である。

この羊皮紙のあらまし

この羊皮紙が導く者

  • Dockerという箱庭で、.NET 6アプリという魂を、ビルドから実行まで完結させたいと願う者
  • cronという古の魔法を使い、コンテナ内のゴーレムに、周期的な命を吹き込みたい探求者
  • コンテナ化されたバッチ処理の自動実行を学びたい実務家
  • マイクロサービスアーキテクチャでの定期処理を実装したい開発者

砂漠の道標

  • .NET 6 - Microsoftのオープンソースなクロスプラットフォーム開発フレームワーク。
  • Docker - コンテナ仮想化技術。アプリケーションを隔離された環境で実行できる。
  • Dockerfile - Dockerイメージをビルドするための設定ファイル。
  • docker-compose - 複数のDockerコンテナを一括管理するツール。YAML形式で定義。
  • cron - UNIXシステムで定期的にコマンドを実行するデーモン。タスクスケジューラー。
  • crontab - cronの実行スケジュールを定義するファイル。時刻指定でコマンド実行。
  • マルチステージビルド - Dockerfileで複数の段階を経てイメージを作成する手法。最終イメージを軽量化できる。
  • WSL2 - Windows Subsystem for Linux 2の略。Windows上でLinux環境を動作させる仮想化技術。

儀式の準備:祭壇を整える

まずは、WSL2 Ubuntu(Windows上のLinux環境)という祭壇に、Docker(コンテナ仮想化技術)と.NET 6(Microsoftの開発フレームワーク)という、二つの魔法体系を築いておく必要がある。その方法は、過去の羊皮紙に記されているので、ここでは割愛しよう。

第一の儀式:魂の設計図(ソースコードとDockerfile)

VS Code(Visual Studio Code:Microsoft製コードエディタ)という魔法の工房で、我々の世界の設計図を描いていく。

ファイル構成

これから創造する、世界の設計図

世界の契約書:docker-compose.yml(コンテナ管理設定)

まずは、この箱庭に「batch」という名の魂を宿らせることを、docker-compose.yml(Docker Compose設定ファイル)に宣言する。これが、我々の世界の全てを定義する、契約の書だ。

version: '3.8'
services:
  batch:  # バッチ処理サービス
    container_name: 'batch'
    build:
      context: ./source
      dockerfile: Dockerfile
    environment:
      TZ: Asia/Tokyo  # タイムゾーン設定
    tty: true
    restart: always  # 自動再起動
    stdin_open: true

魂の設計図その1:BackApp(.NETコンソールアプリ)

dotnet new console(.NET新規プロジェクト作成コマンド)で、簡単な魂の素体(コンソールアプリケーション)を創り出す。この魂は、目覚めるたびに、現在時刻を/tmp/testfile.txtという羊皮紙に記録する、という単純な使命を帯びている。

Console.WriteLine("Hello, World!");
using var sw = new StreamWriter("/tmp/testfile.txt");
sw.WriteLine(DateTime.Now);  // 現在時刻を記録

魂の設計図その2:crontab(cron実行スケジュール定義)

魂に、いつ目覚めるべきかを教える、運命のスケジュール帳だ。「1分ごとに」という、短い周期の運命をここに刻む。

*/1 * * * * /app/BackApp  # 毎分実行(分 時 日 月 曜日)

魂の錬成工程:Dockerfile(イメージビルド定義)

これが、今回の錬金術の核心だ。魂の素体をビルドし、運命のスケジュール帳を組み込み、そしてcron(定期実行デーモン)という名の心臓を動かす、その全工程を記した魔導書である。

# ビルド環境:.NET SDK(開発キット)という名の広大な工房
FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build
WORKDIR /source
COPY ["./BackApp/BackApp.csproj", "BackApp/"]
RUN dotnet restore "./BackApp/BackApp.csproj"  # 依存関係の復元
COPY . .
RUN dotnet build "./BackApp/BackApp.csproj" -c Release -o /app/build  # Releaseビルド

FROM build AS publish
WORKDIR /source
RUN dotnet publish "./BackApp/BackApp.csproj" -c Release -o /app/publish  # 発行

# 実行環境:.NET Runtime(実行環境のみ)という名の、戦闘に特化した器
FROM mcr.microsoft.com/dotnet/runtime:6.0.6-focal AS runtime
COPY ["crontab", "/var/spool/cron/crontabs/root"]  # cron設定ファイルをコピー
WORKDIR /app
COPY --from=publish /app/publish .  # publishステージから成果物をコピー
WORKDIR /

# cron(定期実行デーモン)という古の魔法を使うための、追加の道具
RUN apt-get update && apt-get -y install --no-install-recommends \
      busybox-static \  # 軽量なcron実装
    && apt-get -y clean \
    && rm -rf /var/lib/apt/lists/*

# 魂に、定刻の鼓動を与える心臓を起動する
ENTRYPOINT ["/usr/bin/busybox", "crond", "-f", "-l", "2", "-L", "/dev/stderr"]

最終儀式:魂の召喚と、鼓動の確認

全ての設計図が揃ったら、docker-compose build(イメージビルド)で魂を錬成し、docker-compose up -d(コンテナ起動)で箱庭に魂を召喚する。

$ cd ~/batsv
$ docker-compose build
$ docker-compose up -d

召喚した魂が宿る器に入り込み(docker-compose exec batch /bin/bashでコンテナ内部に接続)、/tmp/testfile.txtの中身を覗き見る。1分ごとに、その羊皮紙に新たな時刻が刻まれていれば、儀式は成功だ。魂は、確かに、定刻通りに鼓動している。

羊皮紙を巻く前に

Dockerという箱庭の中で、.NETアプリのビルドから実行、そしてcronによる定期実行まで。この一連の儀式は、情報が少なく、当時は試行錯誤の連続だった。だが、一度この魔法体系を理解してしまえば、その応用範囲は無限に広がる。

この構成の優れた点

  1. 完全な自己完結性 - ビルドから実行までコンテナ内で完結し、ホストOS環境に依存しない
  2. マルチステージビルドの軽量化 - SDK→Runtime移行で最終イメージを劇的に軽量化
  3. 確実な定期実行 - cronをフォアグラウンドで実行し、コンテナの安定稼働を保証
  4. タイムゾーン完全対応 - Asia/Tokyo設定により日本時刻での正確な実行を実現

まとめ

データ収集、レポート生成、バックアップ処理など、あらゆる定期処理を、この箱庭で完結できる。マイクロサービスアーキテクチャにおいて、この構成は「定時に目覚める自律的な魂」として、システム全体に静かな秩序をもたらす。

この羊皮紙が、同じように自動化という名のゴーレムを、よりスマートに、より力強く運用したいと願う、未来の冒険者の助けとなることを願う。

東の空が白んできた。相棒が「そろそろ日が昇る」と急かしている。今日はこのへんで筆を置くとしよう。

砂漠で見つけた魔法のランプ

ラクダの独り言

ご主人が、箱の中に創ったゴーレムに「1分ごとに起きろ」だの「時間を記録しろ」だの、細かい命令を下している。俺に言わせりゃ、そんなもん、自分で時計を見りゃ済む話だろうに。まったく、人間ってのは、自分の代わりに働かせるのが本当に好きだな。そのうち、俺の代わりに歩くゴーレムとか創り出すんじゃねえか。やれやれだぜ。