Dockerfileのベストプラクティスを行番号付きで確認
このDockerfileベストプラクティスチェッカーは、イメージをビルドシステムへ渡す前に、よくある3つの問題を確認します。WORKDIRの不足、変更され得るlatestタグを使ったベースイメージ、不要なレイヤーにつながる可能性がある連続したRUN命令を検出します。各指摘にはソースの行番号、安定した種類、明確な説明が含まれるため、ファイルの目視確認にも継続的インテグレーションの自動チェックにもご利用いただけます。
無料で実行
簡潔で対応しやすいレポートをご確認いただけます
Dockerfileの全文をテキスト欄へ貼り付けて、チェックを実行してください。結果には合格したかどうか、指摘数、各問題の1始まりの行番号、機械処理しやすい安定した種類、簡潔なメッセージが表示されます。本ツールはコンテナセキュリティ製品全体を置き換えるものではなく、保守で頻出する3つのリスクに意図的に絞っています。WORKDIRがない場合はファイル全体に関わるため、1行目の指摘として扱います。FROMのイメージがlatestを明示している場合、またはタグを省略してlatestとして解決される場合は、そのFROMの行を示します。RUNが連続すると、後の命令を指摘し、前の行もメッセージに含めます。コメントや空行が間にあっても、この関係は途切れません。問題がなければfindingsは空の配列となり、validを自動処理の合格条件としてそのまま利用できます。バックスラッシュで継続された行は1つの論理命令として扱い、エディターと一致する最初の物理行を報告します。
3つのルールが重要な理由をご理解いただけます
WORKDIRは、後続のRUN、COPY、CMD、ENTRYPOINTが使うファイルシステム上の位置を明確にします。指定がなければ、ビルドはベースイメージが選んだディレクトリを暗黙に引き継ぎ、ベースイメージの更新によって動作場所が変わるおそれがあります。FROMのイメージをバージョン付きタグまたは不変のダイジェストで固定すると、ビルドを再現しやすくなります。タグのない参照とlatestは、Dockerfile自体が同じでも別の内容を指す可能性があります。また、通常はRUNごとにファイルシステムのレイヤーが作られます。連続するインストール、後片付け、設定処理は1つのシェル操作にまとめることで、一時ファイルを同じレイヤー内で削除し、履歴を読みやすくできる場合があります。ただし、キャッシュ境界を意図的に分ける設計もあるため、結果は命令ではなく推奨として提示します。本ツールはコマンドを書き換えず、すべての統合が安全だとも判断しません。最終判断は、ビルド、キャッシュ戦略、エラー時のコマンド動作をご存じの方が行ってください。
時間のかかるイメージビルドより前に実行できます
エディターの操作、コミット前の処理、または継続的インテグレーションの早い段階で実行し、ベースイメージの取得やアプリケーションのコンパイルより先に問題をご確認ください。物理行と継続行を正しく保つため、解析済みデータではなく元のソーステキストを送信してください。アルゴリズムは決定的であり、同じ入力には常に同じ出力を返します。ネットワーク、時計、乱数、Dockerデーモン、環境固有の状態は使用しないため、生成されたDockerfileにも適しています。この結果は基本的な保守性の目安であり、イメージの安全性やビルド成功を保証するものではありません。シェルコマンドの実行、イメージ名の変数解決、パッケージ検査、COPY元の検証、非特権USERの強制、脆弱性スキャンは行いません。実際のビルド、イメージスキャン、ポリシー検査、完成したプロセスのテストと組み合わせてください。空白やコメントしかない入力は、評価できるDockerfile命令がないため無効として処理されます。
活用例
コミット前にDockerfileをご確認いただけます
対象行を編集中の段階で、変更され得る参照や不明確な作業ディレクトリを検出できます。
生成されたコンテナ定義を検査できます
パイプラインがイメージのビルドと公開に時間を使う前に、テンプレート出力を確認できます。
コンテナリポジトリを整理できます
複数サービスの簡単な改善に優先順位を付けられる、行番号付きの統一された指摘を作成します。
よくある質問
1回のチェック料金はいくらですか?
APIリクエスト1回につき$0.002です。このページのブラウザー版も直接ご利用いただけます。
タグのないイメージもlatestとして扱われますか?
はい。Dockerは省略されたタグをlatestとして扱うため、バージョン付きタグまたはダイジェストを推奨します。
RUN命令は自動的に統合されますか?
いいえ。連続するRUNを報告しますが、キャッシュ境界が意図的な場合もあるため書き換えません。
WORKDIR不足が1行目に表示されるのはなぜですか?
不足はファイル全体に関わり、対応するソース行が存在しないため、1行目をファイル単位の位置として使用します。
構文やイメージの安全性も検証しますか?
いいえ。3つの基本ルールのみを確認するため、実際のビルド、ポリシー検査、脆弱性スキャンと併用してください。
開発者向け — APIアクセス
このページの機能はすべてAPIからも利用できます。自社システムに組み込みたいチーム向けのセクションです。それ以外の方は上のツールをそのままお使いください。
エンドポイント
Bearerトークンで認証し、POST1回でタスクをキューに登録します。結果はWebhookまたは署名付きリンクで受け取れます。
お使いのスタックから呼び出す
curl -X POST https://api.kit.forhosting.com/dev2/dockerfile-lint-basic \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"}'const res = await fetch("https://api.kit.forhosting.com/dev2/dockerfile-lint-basic", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev2/dockerfile-lint-basic",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev2/dockerfile-lint-basic", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"FROM node:20-alpine\\nWORKDIR /app\\nCOPY package*.json ./\\nRUN npm ci && npm cache clean --force\\nCOPY . .\\nCMD [\\"node\\", \\"server.js\\"]"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev2/dockerfile-lint-basic", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)リクエスト例
{
"text": "FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"
}レスポンス例
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev2.dockerfile_lint_basic",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}非同期APIです。task_idは即時に返ります。ポーリングは1秒あたり1リクエストまでです。
料金
単価はすべて公開しています。トークン換算や独自クレジットはありません。失敗したタスクは課金されません。
エラー
| HTTP | コード | 意味 |
|---|---|---|
401 | unauthorized | APIキーが無効か、指定されていません。Authorizationヘッダーを確認してください。 |
402 | insufficient_balance | 残高が不足しています。チャージ後に再度お試しください。 |
404 | unknown_type | 指定されたタスクタイプは存在しません。タイプ名を確認してください。 |
429 | rate_limited | リクエストが多すぎます。しばらく待ってから再度お試しください。 |