Dockerでアプリを動かしているフリーランスエンジニアなら、一度はセキュリティスキャンを走らせたことがあるだろう。そして、その結果に絶望したことも。
この記事では、僕が実際にDockerイメージの脆弱性スキャンをやってみて「なんだこの数は……」と固まった経験から、フリーランスとして現実的にどう対処しているかを書く。「全部直せ」は無理ゲーだけど、「全部無視」もさすがにマズい。その間のちょうどいい落としどころの話だ。
Dockerの脆弱性スキャンをやってみたら地獄だった
ある日、自分が運用しているサービスのDockerイメージに対して、Trivy(トリビー)というオープンソースの脆弱性スキャナを走らせてみた。Trivyは、Dockerイメージに含まれるOSパッケージやライブラリの既知の脆弱性を自動で検出してくれるツールだ。
結果、数百件の脆弱性が検出された。
内訳を見ると、深刻度が「LOW(低)」のものが半分以上。「MEDIUM(中)」がその次に多くて、「HIGH(高)」や「CRITICAL(致命的)」もちらほら混ざっている。
正直、最初の感想は「いや、多すぎて何もわからん」だった。
これは僕だけの感想じゃない。海外の開発者コミュニティでも「847件の脆弱性が出たけど、結局全部無視してデプロイした」なんてネタが共感を集めるくらい、みんな同じ壁にぶつかっている。いわゆる「CVE疲れ(CVE Fatigue)」というやつだ。CVEというのは、世界共通の脆弱性識別番号のこと。毎日のように新しい番号が採番されていて、スキャナはそれを律儀に全部拾ってくる。
なぜ脆弱性の数が膨れ上がるのか
そもそも、なぜDockerイメージにはこんなに大量の脆弱性が見つかるのか。理由はシンプルで、Dockerイメージの中にはOS丸ごとに近いものが入っているからだ。
たとえば、Node.jsアプリを動かすためにDebian系のベースイメージを使ったとする。そのイメージには、アプリとは直接関係のないシステムライブラリ——OpenSSL、apt、systemdなどが大量に含まれている。自分のアプリがそれらを一切使っていなくても、「イメージの中に存在する」というだけでスキャナは脆弱性としてカウントする。
つまり、スキャナは「あなたのアプリにとって危険かどうか」は判断してくれない。「このライブラリにはこの脆弱性がありますよ」という事実を機械的に報告しているだけだ。文脈を読んでくれないのだ。
フリーランスとして複数の案件を掛け持ちしていると、これがまたキツい。案件Aのイメージで300件、案件Bで500件、自分のサービスで200件。全部真面目に対応していたら、それだけで1日が終わる。というか1週間あっても足りない。
フリーランスが現実的にやるべき3つのこと
じゃあどうすればいいのか。僕が実際にやっている対処法を3つ紹介する。
1. ベースイメージを軽量なものに変える
これが一番効果がデカい。たとえば node:20 の代わりに node:20-slim や node:20-alpine を使う。Alpine Linux(アルパイン・リナックス)は、必要最小限のパッケージだけで構成された軽量Linuxで、イメージサイズが劇的に小さくなる。
通常のDebianベースだと数百MBあるイメージが、Alpine版だと数十MBまで縮む。パッケージが少ない分、そもそも脆弱性が見つかるライブラリ自体が減る。僕の環境では、ベースイメージをAlpineに変えただけで検出数が3分の1以下になった。
ただし、Alpine特有のハマりポイントもある。glibcではなくmusl libcを使っているので、一部のネイティブモジュールがビルドできないことがある。Pythonアプリでも同様の問題が起きがちだ。そこは事前にテストして確認するしかない。
2. CRITICALとHIGHだけに集中する
全部を直そうとしない。これが精神衛生上も、ビジネス的にも正しい。
LOWやMEDIUMの脆弱性の多くは、「理論上は攻撃可能だが、実際に悪用される可能性はかなり低い」ものだ。もちろんゼロリスクではないが、フリーランスのリソースは有限だ。
まずはCRITICAL(致命的)の脆弱性を確認して、それが自分のアプリで実際に使っているライブラリかどうかを調べる。使っていなければ、ベースイメージのアップデートで解消できることが多い。使っているなら、パッチが出ているか確認して、出ていればバージョンを上げる。
HIGH(高)も同じ手順で、使っているかどうか → パッチがあるか → 上げられるか、の3ステップで判断する。
3. CI/CDに組み込んで「気づける仕組み」を作る
スキャンを手動で走らせていると、忙しいときにサボってしまう。これはもう人間の性質としてしょうがない。
だから、GitHub ActionsなどのCI/CD(コードの変更を自動でテスト・デプロイする仕組み)にTrivyを組み込んでおく。イメージをビルドするたびに自動でスキャンが走り、CRITICALが見つかったらビルドを止める、くらいの設定にしておくと安心だ。
ポイントは「全件で止める」のではなく「CRITICALだけで止める」こと。LOWやMEDIUMで毎回止まっていたら、誰もCIの結果を見なくなる。オオカミ少年と同じだ。本当にヤバいときだけアラートが鳴るようにしておかないと、アラートの意味がなくなる。
フリーランスだからこそセキュリティは「信用」になる
ぶっちゃけた話、個人開発や小規模なサービスで脆弱性スキャンまでやっているフリーランスは少数派だと思う。だからこそ、これをちゃんとやっていると差別化になる。
クライアントに「Dockerイメージの脆弱性スキャンをCIに組み込んでいます」と言えるだけで、「この人はセキュリティ意識が高い」という評価になる。フリーランスにとって信用は最大の資産だ。月に1回、30分だけスキャン結果を確認する習慣をつけるだけでも、十分に価値がある。
それに、万が一セキュリティインシデントが起きたとき、「何もやっていませんでした」と「スキャンは定期的に実施していました」では、責任の重さがまるで違う。これは自分を守るためでもある。
まとめ
Dockerの脆弱性スキャンは、走らせると大量の警告が出て心が折れる。でも、全部無視するのも全部直すのも現実的じゃない。
フリーランスとして現実的にやるべきことは3つ。
- ベースイメージを軽量にする(Alpine等を使って、そもそもの検出数を減らす)
- CRITICALとHIGHに集中する(LOWは後回しでいい)
- CI/CDに組み込んで自動化する(手動だと絶対にサボる)
完璧を目指す必要はない。でも「何もしない」からは卒業しよう。800件の警告に圧倒されても、やるべきことは意外とシンプルだ。
【PR】フリーランスエンジニアにおすすめのツール
Dockerでサービスを運用するなら、安定したサーバー環境は必須だ。最後に、僕が実際に使っているサービスを紹介しておく。
カゴヤ・ジャパン レンタルサーバー
Dockerが使えるVPSプランがあって、検証環境を気軽に立てられるのが気に入っている。個人開発のステージング環境として重宝している。
freee会計
サーバー代やツールのサブスク代は全部経費になる。freeeに連携しておけば、クレカ明細から自動で仕訳してくれるので確定申告が本当にラクになった。
→ freee会計
お名前.com ドメイン
独自ドメインでサービスを公開するときに使っている。Whois代行が無料なのが地味にありがたい。フリーランスとしてポートフォリオサイトを持つなら、まずはドメインからだ。


コメント