Codexに記事コードの検証を任せる:Docker環境の構築から後片付けまで
作成日:2026.10.25
PHPのサンプルコードを題材に、Docker環境の構築から検証、ログ保存、後片付けまでCodexに任せた記録です。記事ごとの環境分離、AGENTS.mdによる操作ルール、実行前の設定検査と、実際に確認できた範囲を紹介します。
目次
技術ブログのサンプルコードを確認するとき、コードを書くところだけでなく、実行環境の準備もCodexに任せられないかと思いました。PHPの拡張をそろえたり、テスト用のAPIを用意したりと、実行する前にも結構やることがあります。
そこで、記事ごとにDocker環境を用意し、構築から検証、結果の記録、後片付けまでCodexに任せる仕組みを作ってみました。共通化したのは、全言語を詰め込んだ環境ではなく、操作ルール・実行前の検査・結果を残す手順です。
今回は、PHPで外部APIのフォールバックとキャッシュを実装する記事のコードを検証した1ケースを紹介します。本文のサンプルは、作成したルールや設定から要点を抜粋したものです。Dockerの基本操作は、Windows 11でDocker Composeを使ってLaravel環境を作る記事を参照してください。
環境は記事ごとに分け、手順をそろえる
最初は、いろいろな言語を入れた共通の検証用コンテナを用意することも考えました。ただ、記事が増えるたびに依存関係や設定、データが積み重なると、何が必要な環境なのか分かりにくくなりそうです。
共通イメージを使い、記事ごとにComposeの環境を分ける案もあります。今回は、環境の準備自体をCodexに任せたいので、記事に必要なDockerfileやCompose設定をその都度作り、共通のルールで検査・実行する形にしました。
ホストPC
Codex
├─ 記事ごとの設定・検証コードを作成
└─ 内容確認 → 設定検査 → Dockerで実行 → ログ保存・後片付け
│
専用のCompose環境
├─ verify:記事コードを検証
├─ primary:架空API 1
└─ secondary:架空API 2
Codexはホスト側で作業し、検証するPHPコードをコンテナ内で動かします。今回、AIエージェント自体をコンテナへ入れたり、Docker操作専用のMCPサーバーを作ったりはしていません。
記事ごとのファイルは、次のようにまとめています。記事IDに合わせたディレクトリを作り、実行ごとのログはその下へ保存します。
verification/
├─ AGENTS.md # 操作範囲と作業手順
├─ scripts/ # 共通の設定検査
└─ cases/2026/10/261023/
├─ Dockerfile
├─ .dockerignore
├─ compose.yaml
├─ mock.php # 架空API
├─ verify.php # 原稿コードの抽出と検証
├─ run.ps1 # 検査・実行・記録・後片付け
├─ README.md
└─ results/ # 実行ごとのログ。Git管理外
AGENTS.mdで任せる操作を決める
環境を分けても、Codexがホスト側で何を操作してよいのかは、別に決める必要があります。そこで、検証用のAGENTS.mdへ、依頼に含める操作と個別に確認する操作を書きました。
AGENTS.mdは、Codexへプロジェクトの作業ルールを伝えるファイルです。読み込む範囲や優先順位は、OpenAI公式のAGENTS.mdガイドに説明があります。今回のように作業ディレクトリの下にルールを置く場合は、ルートのAGENTS.mdにも「検証環境を作る前に、そのファイルを読む」と明記しておきます。
方針を短くすると、次のような内容です。実際には、この下に設定の上限やマウント先、実行手順も書いています。
# 記事コードのDocker検証ルール
- 対象記事のケース内で、設定・検証コード・ダミーデータを作成する。
- ビルド前に、Dockerfile・検証コード・ホスト実行スクリプトを読む。
- 共通の設定検査に合格した構成だけをビルド・実行する。
- 検査済み設定を保存し、以後のDocker操作にも同じ設定を使う。
- 実行ごとに専用のComposeプロジェクト名を付ける。
- 成否にかかわらずログを取得し、その実行分の資源を片付ける。
- 実API・認証情報・業務データの利用は、実行前に確認する。
- ポート公開・許可外のマウント・root実行は、実行前に確認する。
- Dockerのインストール・更新・設定変更は、実行前に確認する。
- 対象を限定しないprune、他の開発環境の操作は行わない。
- sandboxや権限制限で拒否された場合は、正規の承認手順を使う。
許可した範囲であれば、ケースの作成からビルド、検証、専用コンテナ・ネットワークなどの削除までを、一連の依頼として進められるようにしました。毎回「次は起動してよいですか」と止まっていては、環境準備まで任せる意味が薄くなってしまうので。
ただし、AGENTS.mdへの記載で、実行環境の権限が増えるわけではありません。今回もDocker Engineへの接続が制限内から拒否され、権限確認を経て実行しました。作業ルールと、sandbox・承認による制御は分けて考えます。後者については、OpenAI公式の承認とセキュリティの説明も参照してください。
PHPと2つの架空APIで検証する
検証対象の記事では、最初のAPIでデータが得られなかった場合に別のAPIへ切り替え、成功した結果をキャッシュします。外部の実サービスへ接続せず、成功・該当なし・HTTPエラー・タイムアウトなどを返す架空APIを2つ用意しました。
primaryとsecondaryはPHPの開発用HTTPサーバー、verifyは記事コードを実行するコンテナです。2つのAPIのヘルスチェックが通ってから検証を開始します。
必要なファイルだけを渡す
ホストからマウントするのは、検証対象のHTML原稿1ファイルだけで、読み取り専用にしています。検証コードとモックAPIはケース内からイメージへコピーします。リポジトリ全体、認証情報、Dockerソケットはコンテナへ渡しません。
各サービスに適用した共通設定とネットワークの抜粋は、次のとおりです。servicesや原稿のマウント指定は省略しているので、この抜粋だけで起動するものではありません。
x-runtime: &runtime
image: techblog-261023-verification:local
build:
context: .
user: "10001:10001"
read_only: true
cap_drop: [ALL]
security_opt: ["no-new-privileges:true"]
init: true
cpus: 1.0
mem_limit: 256m
pids_limit: 32
tmpfs:
- /tmp:size=16m,mode=1777
networks: [verification]
networks:
verification:
internal: true
非rootで動かし、ルートファイルシステムを読み取り専用にして、一時ファイルは小容量の/tmpへ書き込みます。CPU・メモリ・プロセス数にも上限を付けました。設定項目の意味は、Composeのサービス設定で確認できます。
3つのサービスは専用のinternalネットワークへ接続し、ホストへポートを公開しません。Composeのinternal: trueは、外部から分離したネットワークを作る設定です。一方、初回のイメージ取得など、ビルドの準備には外部通信を使います。検証時の通信と取得時の通信は分けて扱います。
検証用に書き直さず、原稿から取り出す
同じ処理を検証用ファイルへ書き写すと、原稿だけ直して検証コードを直し忘れる、といったずれが起きます。そこで、HTMLの<pre><code class="language-php">から、PHPコード6ブロックをDOMで抽出する形にしました。
抽出時にはコードブロック数と主要な関数の位置を確認し、想定と違えば停止します。その上で、サンプル全体の構文と出力、関数を直接呼び出した結果を調べます。原稿を変更したときに、検証側の前提も見直すためです。
実HTTP通信の検証では、原稿の架空HTTPS接続先2か所だけを、コンテナ内のHTTPモックへ差し替えました。フォールバックやキャッシュの処理はそのまま使います。この差し替えがあるので、TLS接続や証明書検証まで確認できたわけではありません。
生成された設定を、実行前に検査する
AGENTS.mdはCodexへの指示なので、それだけで設定ミスを防げるとは限りません。今回はPowerShellで共通の検査処理も作り、ビルド前に通すようにしました。
検査では、最初にケースの場所と参照先を確認します。Composeが別ファイルやホストの環境値を読む前に、今回許可しない外部ファイル参照や変数展開も拒否します。その後、展開済みのCompose設定をJSONで取得し、許可した項目と値になっているか調べます。
docker compose configは、複数ファイルの統合、変数の解決、省略記法の展開を行うコマンドです。公式のconfigコマンドの説明にあるとおり、設定を解釈して出力するもので、今回の独自ルールへの適合まで判定するものではありません。その判定をPowerShell側へ追加しています。
| 検査する対象 | 今回の主な基準 |
|---|---|
| 実行権限 | 非root、読み取り専用、追加権限なし。特権モードやDockerソケット共有を拒否 |
| 通信 | 専用internalネットワークのみ。ポート公開や外部・共有ネットワークを拒否 |
| マウント | 対象原稿またはケース内の明示した入力だけ。読み取り専用にし、リンク・ジャンクションも確認 |
| 資源 | CPU・メモリ・プロセス数・一時書き込み領域の上限を確認 |
| ビルド | ケース内の入力、許可した配布元、digest固定のベースイメージに限定 |
| 未知の設定 | 許可リストにない項目は拒否し、必要性を確認してから扱う |
合格した設定はcompose.checked.jsonとして保存し、その後のビルド、起動、ログ取得、後片付けにも使います。検査後に別のComposeファイルを足したり、権限やマウントを上書きしたりしない手順です。入力を変更したら、検査からやり直します。
設定検査だけでは足りない部分もある
この検査でDockerfileのRUNや、検証用PHP、ホスト側スクリプトの処理内容まで安全と判断することはできません。そのため、ビルド前にCodexがコード、取得元、インストール時の処理、実行コマンドなどを読む手順も残しました。
実装中に見直した点の一つが、.dockerignoreです。ケース内のファイルだけをビルドへ渡すため、最初に*で除外し、必要な入力だけを追加する形にしました。ただし、Dockerfile固有のignoreファイルがあると、そちらが優先されます。これはDocker公式のビルドコンテキストの説明にも記載されています。
そこで、今回の検査ではその上書きを拒否し、拒否できることを回帰テストにも追加しました。AIが作った設定を一度読んで終わりにするより、見つけた条件を検査へ残しておく方が、次の記事でも同じ確認をしやすくなります。
ベースイメージもdigestで固定しています。同じ内容を指定できる反面、固定したままでは更新を取り込めないため、更新時にはdigestを確認して検証し直す運用が必要です。Docker公式のベースイメージ固定の説明も参照してください。
Codexへ依頼するときは、期待する結果も渡す
ルールを用意したら、対象コードと、何を確認したいかを伝えます。例えば、今回の構成を依頼するなら、次のように書けます。これは依頼内容を整理した例で、構築時の会話そのものの引用ではありません。
ルートのAGENTS.mdとverification/AGENTS.mdを読んでください。
外部API記事のPHPコードを検証するDocker環境を、記事専用のケース内に作成してください。
原稿のコードを抽出して使い、実APIの代わりに2つのローカルAPIモックを用意してください。
成功、該当なし、HTTPエラー、タイムアウト時の切り替えを確認してください。
キャッシュのヒット・期限切れ、問い合わせ順と回数も確認してください。
ビルド前にコードをレビューし、共通の設定検査を通してください。
環境、原稿のハッシュ、期待結果と実結果、未検証事項を記録してください。
検証後はログを保存し、その実行で作成した専用資源を片付けてください。
「動くか確認して」だけだと、構文が通ったところで終わるかもしれません。タイムアウトしたら次のAPIを使う、キャッシュがあれば問い合わせない、といった期待結果まで渡すのがよいかと思います。
今回作成した実行スクリプトは、設定検査、ローカルEngineの確認、ビルド、モックAPIの起動待ち、検証を順に行います。Dockerコマンドの終了コードを確認し、失敗した場合もfinallyでログ取得と後片付けを試みるようにしました。
ただし、PowerShellの強制終了やDocker自体の停止まで含めて、必ず片付く保証はありません。残った場合に対象を特定できるよう、Composeプロジェクト名に記事ID・実行日時・識別子を含め、その名前もログへ保存しています。イメージとビルドキャッシュは再利用のため残し、対象を限定しない削除は行いません。
確認できた結果と、まだ確認していないこと
2026年10月24日の構築・再実行では、次の環境と結果を記録しました。現在の推奨バージョンを示すものではありません。
| 項目 | 確認した環境・結果 |
|---|---|
| ホスト側 | Windows、PowerShell 7.6.8、Docker Desktop 4.93.0 |
| Docker | Engine 29.8.1、Compose v5.5.1 |
| 検証コンテナ | Linux / amd64、PHP 8.3.36、libcurl 7.88.1、OpenSSL 3.0.22 |
| PHPコードの検証 | 45項目成功、失敗0。実HTTP通信11ケースを含む |
| 設定検査の回帰テスト | 40項目成功、失敗0 |
| 後片付け | 当該実行の専用コンテナとネットワークを削除 |
タイムアウトのケースでは、primaryが700ミリ秒待つようにし、約300ミリ秒で打ち切ってsecondaryを採用できました。保存したPHP検証ログから、該当部分を抜粋すると次のとおりです。
timeout elapsed_ms=300.4
PASS HTTP: TIMEOUT
...
RESULT tests=45 failures=0
PHPの検証件数と、設定検査の回帰テスト件数は別です。前者は原稿コードの動作、後者は特権モードや書き込み可能なホストマウントなどを検査処理が拒否できるかを確認しています。執筆時にも設定検査の回帰テストを再実行し、40項目の成功を確認しました。
ログには、検査済み設定、ビルド結果、PHPなどの実バージョン、原稿のSHA-256、サービスログ、後片付け結果、全体の成否を残しました。これで、どの原稿をどの環境で確認したのかを追えます。件数だけでなく、何を確認した結果なのかもセットで残しておきたいところです。
一方、今回のHTTPモックでは、実APIの仕様や認証、TLS証明書検証、実際のDNS失敗・接続失敗、負荷、永続キャッシュは確認していません。TLSなどのエラー分類は関数モックで確認した範囲です。また、元記事のWindows環境と、今回のLinuxコンテナは同一の環境ではありません。
Named Volumeを使うDB、別言語のケース、複数ケースの並列実行、強制終了からの復旧も、まだ実証していません。今回の実行スクリプトはWindowsのローカルdesktop-linuxを前提にしています。
コンテナの設定を絞っても、ホスト上のCodexが持つ権限は残ります。この仕組みは、自分の管理する記事コードの検証で設定ミスを減らすためのものです。悪意ある任意のコードを受け付けて安全に実行するサービスとしては作っていません。Docker Engineのセキュリティに関する公式資料でも、コンテナの隔離だけでなく、daemonの権限や設定が検討対象になっています。
環境の作成と、検証結果の確認をセットにする
今回、CodexにはDockerfileやテストを書くところから、実行時の問題の切り分け、ログ保存、後片付けまで任せられました。ただ、最初から一度で完成したわけではなく、Engineへの接続権限や、Composeの出力形式、検証コード側のPHP定数の違いなどを順に確認して修正しています。
記事ごとに環境を作る方針にしたことで、何を用意するかは柔軟にしつつ、許可する操作と確認手順はそろえられました。まずは小さな1ケースで、期待する結果、実際のログ、片付ける範囲まで決めて試すと、次に任せる作業も具体的にしやすいかと思います。
奈良市を拠点に、27年以上の経験を持つフリーランスWebエンジニア、阿部辰也です。
これまで、ECサイトのバックエンド開発や業務効率化システム、公共施設の予約システムなど、多彩なプロジェクトを手がけ、企業様や制作会社様のパートナーとして信頼を築いてまいりました。
【制作会社・企業様向けサポート】
Webシステムの開発やサイト改善でお困りの際は、どうぞお気軽にご相談ください。小さな疑問から大規模プロジェクトまで、最適なご提案を心を込めてさせていただきます。
ぜひ、プロフィールやWeb制作会社様向け業務案内、一般企業様向け業務案内もご覧くださいね。
SkillだけのプラグインをCodexとChatGPT Workで使う
2026.10.14
Skillだけを含むHello Worldプラグインを例に、plugin.json と SKILL.md の作成、ローカルマーケットプレイスへの登録、ChatGPTデスクトップアプリのWorkとCodexからの呼び出し方を紹介します。MCPサーバーを使わない最小構成と、登録・呼び出しでつまずいたときの確認点も解説します。
VS CodeでGitHub CopilotとCodexを比較:機能の違いと使い分け
2026.10.07
VS Codeで利用するGitHub CopilotとCodexの機能と使い分けを比較します。コード補完、コード調査・修正、モデル選択、AGENTS.mdやSkillsによる指示の再利用を整理し、具体的な依頼文と変更内容を確認するポイントを紹介します。
VS Code版CodexのStopフックで応答終了をWindowsに通知する
2026.10.04
VS Code版CodexのStopフックとPowerShellを使い、最後の応答をWindows通知に表示する方法を紹介します。hooks.jsonの設定と非同期実行、日本語が文字化けした際のUTF-8による対処、通知が出ない場合の確認点をまとめます。
CodexのGPT-6.1 SolとGPT-6 Lunaを比較:コストと使い分けの目安【2026年10月3日時点】
2026.10.03
GPT-6.1 SolとGPT-6 Lunaを、PlusでのCodex利用枠、API料金、公開ベンチマークから比較します。2026年10月3日時点の情報をもとに、日常作業はLuna、難しい調査や設計はSol Mediumを試すという使い分けと、自分の作業で費用対効果を確かめるポイントを整理します。