旅の途中、興味深いオアシスを見つけた。忘れないうちに、この羊皮紙に記しておくとしよう。
「一定間隔で、自動的に魔法を発動させたい…」 かつて私がAIシステムという巨大なゴーレムを創り上げた時、この切実な問題に直面した。情報の砂漠を彷徨い、試行錯誤の末に辿り着いた答え。それは、.NET 6(Microsoftの開発フレームワーク)で創り上げた魂を、Dockerfile(イメージビルド定義)でビルドし、cron(UNIX定期実行デーモン)という古の魔法で、定刻に呼び覚ますというものだった。
今回は、WSL2 Ubuntu(Windows上のLinux環境)という名の祭壇で、その儀式の全てを再現する。これは、単なるバッチ処理(定期実行処理)ではない。コンテナ(隔離実行環境)という異次元の箱庭で、魂の錬成から、その魂に周期的な鼓動を与えるまでを、一気通貫で執り行う、壮大な錬金術の記録である。
この羊皮紙のあらまし
- この羊皮紙のあらまし
- この羊皮紙が導く者
- 砂漠の道標
- 儀式の準備:祭壇を整える
- 第一の儀式:魂の設計図(ソースコードとDockerfile)
- 最終儀式:魂の召喚と、鼓動の確認
- 羊皮紙を巻く前に
- 砂漠で見つけた魔法のランプ
- ラクダの独り言
この羊皮紙が導く者
- 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による定期実行まで。この一連の儀式は、情報が少なく、当時は試行錯誤の連続だった。だが、一度この魔法体系を理解してしまえば、その応用範囲は無限に広がる。
この構成の優れた点
- 完全な自己完結性 - ビルドから実行までコンテナ内で完結し、ホストOS環境に依存しない
- マルチステージビルドの軽量化 - SDK→Runtime移行で最終イメージを劇的に軽量化
- 確実な定期実行 - cronをフォアグラウンドで実行し、コンテナの安定稼働を保証
- タイムゾーン完全対応 - Asia/Tokyo設定により日本時刻での正確な実行を実現
まとめ
データ収集、レポート生成、バックアップ処理など、あらゆる定期処理を、この箱庭で完結できる。マイクロサービスアーキテクチャにおいて、この構成は「定時に目覚める自律的な魂」として、システム全体に静かな秩序をもたらす。
この羊皮紙が、同じように自動化という名のゴーレムを、よりスマートに、より力強く運用したいと願う、未来の冒険者の助けとなることを願う。
東の空が白んできた。相棒が「そろそろ日が昇る」と急かしている。今日はこのへんで筆を置くとしよう。
砂漠で見つけた魔法のランプ
- 蜃気楼との決別 ~Docker Desktopを捨て、WSL2に拠点を築く~ | Dockerのインストールに関する古文書
- Microsoft .NET - Docker Hub | 公式イメージの宝物庫
- 現場で役立つ Docker 実践ガイド - Amazon | Docker魔導書(アプリ開発者向け)
- プログラマのためのDocker教科書 第2版 - Amazon | Docker魔導書(インフラ構築者向け)
- cron入門 - Wikipedia | cronの基礎知識
ラクダの独り言
ご主人が、箱の中に創ったゴーレムに「1分ごとに起きろ」だの「時間を記録しろ」だの、細かい命令を下している。俺に言わせりゃ、そんなもん、自分で時計を見りゃ済む話だろうに。まったく、人間ってのは、自分の代わりに働かせるのが本当に好きだな。そのうち、俺の代わりに歩くゴーレムとか創り出すんじゃねえか。やれやれだぜ。