出来上がったコンテナイメージが思ったより重いことに気づき、Dockerfileを開いて中身を確かめようとしている開発者

AIに書かせたDockerfile|イメージ肥大と脆弱性の確認

「コンテナ化しておいて」と言われて、AIにDockerfileを書いてもらう。 貼り付けて docker build。通った。動いた。よし、これで一件落着——。

その流れ、すごく分かります。Dockerfileは書く機会がまばらで、毎回ちょっとずつ思い出しながら書く種類のファイルですよね。AIはそこをきれいに埋めてくれるので、正直ありがたい。

ただ、あとから「イメージがなぜか重い」「セキュリティ担当から指摘が来た」「ビルド時に渡した鍵がイメージに残っていた」と気づくことがあります。ビルドが通ることと、本番に置いていいことは、別の話なんですよね。

この記事は、AIに書いてもらったDockerfileを、そのまま本番に出す前に見ておきたい場所の話です。Dockerに詳しくなろう、という話ではありません。「重さ」と「安全」の2つの軸で、決まった場所を順に見る——それだけで、あとから効いてくる指摘のかなりの部分は先に潰せます。

結論:AIが書いたDockerfileは、「重さ」と「安全」の2軸で見ます。重さは、①ベースイメージが用途に対して大きすぎないか、②ビルド用の道具(コンパイラ・開発パッケージ)が最終イメージに残っていないか、③.dockerignore が無くて .gitnode_modules ごとコピーしていないか。安全は、④rootのまま動いていないか(USER の指定)、⑤ENVARG に鍵やパスワードを書いていないか、⑥ベースイメージのタグが latest などの動くタグのままになっていないか。仕上げに、イメージスキャン(docker scout cve や Trivy など)を1回かける。ここまでで、Dockerfileレビューで指摘されやすい所はだいたい拾えます。全部を今日やらなくて大丈夫です。まずは USER.dockerignore の2つから見てみましょう。

何が起きているのか——AIは「通るDockerfile」を書くのが得意

AIが手を抜いている、という話ではありません。頼まれたこと(ビルドが通って動くこと)にきちんと応えている結果として、こうなりやすい、という話です。

つまり、受け取ったあとに見る場所さえ決めておけばいい話です。次から、その場所を順にいきます。

①〜③ 重さを見る——「本番に運ぶ荷物」として見直す

ビルド用の道具ごと詰め込んだ重いイメージと、出来上がった成果物だけを詰めた軽いイメージを左右に並べて比べた図

イメージが重いと、配布も起動も遅くなり、余計なものが入っているぶん気にすべき脆弱性の数も増えます。見る場所は3つです。

① ベースイメージが用途に対して大きすぎないか FROM の行を見ます。フルセットのOSイメージが指定されていて、実際にはアプリを動かすだけ、ということがよくあります。多くの公式イメージには、必要最小限に絞った軽い版(-slim が付いたものなど)が用意されています。

② ビルド用の道具が最終イメージに残っていないか ここがいちばん効きます。コンパイラ、開発用ヘッダ、パッケージマネージャのキャッシュ——これらはビルドの間だけ必要で、動かすときには要りません。それでも、1段構成のDockerfileだと全部そのまま荷物に入ります。

対処はマルチステージビルドです。難しい仕組みではなく、「作業する部屋」と「出荷する箱」を分けるだけの話です。前半のステージでビルドし、後半のステージには成果物だけをコピーする。図の右側がこれにあたります。全部入りのまま運ばない、というだけで、荷物はかなり軽くなります。

.dockerignore があるか COPY . . の1行は、書いてあるとおりカレントディレクトリを丸ごと持っていきます。.gitnode_modules、ローカルのログ、そして .env。重くなるだけでなく、入れるつもりのなかった秘密情報が同梱される入り口にもなります。

.dockerignore は、Dockerfileと同じ場所に置く除外リストです。AIにDockerfileを頼むと、Dockerfile単体は書いてくれても .dockerignore は付いてこないことがよくあります。無ければ、「このプロジェクト用の .dockerignore も書いて」と一言足せば出してくれます。設定ファイルまわりで秘密が混ざる話は、AIに設定ファイルを生成させる|秘密情報の混入を防ぐ手順にも整理しています。

④〜⑥ 安全を見る——実行ユーザー・秘密・タグ

④ rootのまま動いていないか 何も指定しなければ、コンテナの中の処理はroot として動きます。動かすぶんには一番楽なので、AIの出力にも USER の行が無いことが多いです。

ENVARG に鍵・パスワードを書いていないか 「ビルド時にトークンが要る」場面で、AIは素直に ARG TOKEN=... と書いてくれることがあります。動きます。ただ、ENV に書いた値はイメージの中に残り、ARG で渡した値もビルド履歴に記録されます。あとから消したつもりでも、履歴をたどれば見えてしまう形です。

⑥ ベースイメージのタグが動くタグのままになっていないか FROM node:latest のような指定は、ビルドする日によって中身が変わります。「昨日は通ったのに今日は落ちる」の原因になりますし、セキュリティ担当から見ても「何が入っているか説明できない」状態になります。

そのほか、レビューでよく引っかかる小さな所

大きな2軸から外れますが、指摘されやすいわりに直すのが一瞬の所をまとめておきます。

スキャンを1回かける——目視の取りこぼしを拾う

ここまで目で見たら、最後に機械にも1回見てもらいます。ベースイメージやライブラリに既知の脆弱性が報告されていないかは、手で追うより道具のほうが確実です。

道具が拾ってくれるのは「既知の脆弱性」までで、設計や設定の穴は拾えません。両方が要るという意味で、AI生成コードのセキュリティ確認|見落としやすい穴の型も、必要なときにのぞいてみてください。

明日やること(3つだけ)

一気に全部は要りません。まずこの3つから。

  1. USER の行があるか見る:無ければ、AIに「非rootユーザーで動くようにこのDockerfileを直して。書き込み先の権限も一緒に見て」と頼む。動かなくなった所が、そのアプリの書き込み先です。
  2. .dockerignore があるか見る:無ければ作る。最低限 .gitnode_modules(や同等のもの)、.env、ログを外す。これだけで荷物が軽くなり、秘密の同梱も減ります。
  3. docker scout cve(または Trivy)を1回かける:結果は眺めるだけでOK。ベースイメージのタグを具体的な版に上げると、たいてい素直に減ります。

この3つは、慣れれば合わせて30分ほどの作業です。あとから指摘されて直すことを思えば、ずっと軽い。 そして、直したDockerfileの意図をコメント1行で残しておくと、次に触る人(数か月後の自分を含む)が助かります。

AI生成Dockerfileのチェックリスト

本番用のイメージを作る前に、上から順に。全部に○が要るわけではなく、そのプロジェクトで気になる所だけで十分です。

重さ

安全

その他

この記事のまとめ

AIが書くDockerfileは、出発点としてはとても優秀です。ゼロから思い出しながら書くより、ずっと速い。 そのうえで、受け取ったあとに見る場所を決めておく。重さは「ベースイメージ・ビルド道具・.dockerignore」、安全は「USER・秘密・タグ」。最後にスキャンを1回。それだけで、あとから来る指摘のかなりの部分は先回りできます。

全部を今日やらなくて大丈夫です。USER.dockerignore の2つだけでも、荷物はずいぶんまともになります。

軽く整ったコンテナイメージを送り出して、落ち着いた表情で次の作業に向かおうとしている開発者

Dockerfileは、書く機会が少ないぶん「これで合っているのか」が分かりにくいファイルです。 それでも今日、USER の1行を足せたなら、あるいは .dockerignore を1つ置けたなら、それは半年後の自分と、次に触る誰かを確実に助けます。急いで全部を整える必要はありません。触るときに、ひとつずつで十分です。

よければ、こちらも

関連用語