2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに ― 「Dockerがうまく起動しない」壁にぶつかったとき

2
Posted at

Dockerでよく遭遇するエラーと現場での対処法 5つの実践例

はじめに ― 「Dockerがうまく起動しない」壁にぶつかったとき

新人エンジニアの頃、ローカルで Docker Desktop をインストールした瞬間に「Cannot connect to the Docker daemon」みたいなエラーメッセージが出て、結局何時間も検索しても解決できずに諦めかけた経験はありませんか? 実は、あのエラーは「Docker がバックグラウンドで動いていない」だけでなく、権限や設定ミスが潜んでいるケースが多いんです。私が最初に直面したときは、Docker のサービスが自動起動に失敗していたことが原因でした。Windows のアップデートで Docker のサービスが停止したままになり、コマンドは通ってもデーモンに接続できませんでした。

なぜそうなるのか
Docker はクライアント‑サーバー構造で、docker コマンドはローカルのデーモン(dockerd)にリクエストを送ります。デーモンが起動していない、もしくは Unix ソケットや Windows の named pipe にアクセスできないと、クライアントはすぐに「接続できません」と返します。

具体的にどう対処するか

  1. サービスの状態確認
    • macOS / Linux: systemctl status docker または service docker status
    • Windows: タスクマネージャーの「サービス」タブで「Docker Desktop Service」を探す
  2. 手動で起動
    • sudo systemctl start docker
    • Windows なら「Docker Desktop」を再起動、もしくは PowerShell で Start-Service com.docker.service
  3. 権限の確認
    • Linux では自分のユーザーが docker グループに所属しているか groups $USER でチェック。所属していなければ sudo usermod -aG docker $USER を実行し、再ログイン。

自分の場合はこうだった
サービスが止まっていたことに気づいたのは、Docker Desktop の UI に「Docker is starting…」と表示されたまま進まない状態が続いたからです。タスクマネージャーでプロセスが存在しないことを確認し、Restart-Service com.docker.service で復活させた瞬間、すべての docker コマンドが正常に戻りました。この経験から、まずは「デーモンが起動しているか」を最優先でチェックする習慣が身につきました。


✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

スイカゲームとにゃんこ大戦争のようなタワーディフェンス系ゲームを組み合わせたゲームを作成しました!
遊んでみていただけると嬉しいです🙇‍♂️


ハジメル.dev: https://hajimeru-dev.vercel.app/

「ひとりで続けるのは難しい」「何から学べばいいか分からない」という方向けに、
プログラミングのマンツーマンレッスンサービス「ハジメル.dev」も運営しています。
未経験OK・オンライン完結・月額制/違約金なしなので、気軽に無料相談してみてください🙇‍♂️


海外テックニュースを追いたいけど、英語や情報量の多さで大変…という方向けに、
Hacker News の話題を日本語でサクッと追える「HackerNews 日本語まとめ & AI要約」
を個人開発しました!
技術トレンド収集に使ってもらえると嬉しいです🔥🙇‍♂️
→ HackerNews 日本語まとめ & AI要約: https://hn-matome-2ht.pages.dev/


「ニャンパイアサバイバー」というヴァンパイアサバイバーリスペクトのゲームを作成しました!
もしよろしければ遊んで頂けると嬉しいです😭


習い事教室の先生向けに、SNS 投稿・生徒募集・保護者通知の文章を AI で生成する Web サービス「おしらせAI」を個人開発しました。Next.js + Supabase + LLM で構成しており、無料で月 10 回まで試用できます。よければ触ってみてください。

→ おしらせAI: https://oshirase-ai.vercel.app/

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

エラー 1: ERROR: Cannot start service ...: driver failed programming external connectivity on endpoint ― ネットワーク設定の罠

Docker Compose で複数コンテナを立ち上げようとしたときに、driver failed programming external connectivity というエラーに遭遇したことはありませんか? 特にポートフォワーディング (ports:) を指定したときに突然失敗し、「ポートがすでに使われているのか?」と焦ることがあります。実は、単にポートが競合しているだけでなく、Docker のネットワークブリッジが破損しているケースもあります。

なぜそうなるのか
Docker は内部で Linux のブリッジネットワーク (docker0) を作り、各コンテナに仮想インターフェースを割り当てます。docker0 が何らかの理由で不整合になっていると、IP アドレスやポートの割り当てが失敗し、上記エラーが出ます。さらに、ホスト側で同じポートが別プロセスに占有されている場合も同様のメッセージが出るため、原因の切り分けが必要です。

具体的な対処手順

  1. ポート競合の確認
    sudo lsof -iTCP -sTCP:LISTEN | grep <対象ポート>
    
    例: lsof -iTCP:8080 で 8080 がどのプロセスにバインドされているか確認。
  2. Docker ネットワークのリセット
    docker network prune -f   # 未使用ネットワークを削除
    docker network rm bridge  # デフォルトブリッジを削除(再生成される)
    systemctl restart docker # Docker デーモンを再起動
    
  3. Compose ファイルの見直し
    • ports: の書き方は - "8080:80" のように文字列で囲むと誤解が減ります。
    • 同一サービス内で複数 ports: を指定するときは、重複がないか再確認。

自分のエピソード
あるプロジェクトで、フロントエンドの dev サーバー(ポート 3000)とバックエンド API(ポート 3000)を同時に起動しようとしたら、Compose 起動直後に上記エラーが大量に出ました。lsof で確認したところ、ローカルで動作していた Node.js の開発サーバーが既に 3000 番を占有していました。すぐにポートを変更し、さらに docker network prune を実行したところ、再度 docker compose up したときにエラーは消え、スムーズにコンテナが立ち上がりました。この経験から、**「ネットワーク系のエラーはまずポートとブリッジの状態を確認」**というチェックリストを作り、毎回実行するようにしています。


エラー 2: permission denied while trying to connect to the Docker daemon socket ― 権限周りの落とし穴

Docker の docker rundocker ps を実行したときに、permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock と表示されたことはありませんか? 特にチーム共有マシンや CI 環境で頻繁に目にするエラーです。権限が足りないだけでなく、システムのポリシーや SELinux の設定が影響しているケースもあります。

なぜそうなるのか
Unix 系 OS では Docker デーモンは /var/run/docker.sock というソケットファイルを通じて通信します。このファイルはデフォルトで root:docker の所有権で、モードは 660(所有者とグループが読み書き可能)です。したがって、実行ユーザーが docker グループに所属していないと接続が拒否されます。さらに、Docker Desktop for Windows でも同様に「Docker Engine にアクセスできません」というエラーが出るのは、PowerShell の実行権限が不足していることが原因です。

具体的な対処法

  1. ユーザーを docker グループに追加
    sudo usermod -aG docker $USER
    newgrp docker   # 直ちにグループ変更を反映
    
  2. ソケットの権限を一時的に緩める(テスト用)
    sudo chmod 666 /var/run/docker.sock
    
    ※本番環境ではセキュリティ上推奨しません。
  3. SELinux のポリシー確認(CentOS/RHEL 系)
    sudo setenforce 0   # 一時的に permissive に
    # 再度 docker コマンドが通るか確認
    sudo setenforce 1   # 元に戻す
    
    SELinux が原因の場合は、audit2allow で許可ルールを生成し、永続的にポリシーを緩和します。

自分の経験
新しい開発マシンをセットアップした直後、docker ps がすべて権限エラーで失敗しました。groups コマンドで自分が docker グループに入っていないことが判明し、usermod -aG docker $USER を実行したものの、まだエラーが出続けました。原因は、シェルを再起動していなかったことでした。newgrp docker で現在のシェルにグループ変更を即時反映させたら、すぐに docker ps が成功しました。この時に学んだのは 「ユーザー追加後はシェルを再起動、もしくは newgrp で即時反映」 が必要ということです。


エラー 3: failed to solve with frontend dockerfile.v0: failed to create LLB definition ― ビルド失敗の根本原因

Dockerfile を書いていると、failed to solve with frontend dockerfile.v0 系列のエラーが頻出します。特に COPY 命令でパスが正しくないときや、ビルドコンテキストが期待通りに送られないときにこのメッセージが出ます。エラーメッセージは長く、どこが問題か分かりにくいので、つい焦って docker build . を何度も走らせてしまいがちです。

なぜそうなるのか
Docker ビルドは内部で BuildKit(LLB: Low Level Build)というグラフ構造を生成します。COPYADD で指定したパスがコンテキスト外にあると、BuildKit はそのファイルを取得できずに「LLB definition の生成に失敗した」と報告します。また、.dockerignore に不要なファイルが入っていると、意図しないファイルが除外され、結果的にビルドが失敗することがあります。

対処のステップ

  1. ビルドコンテキストの確認
    docker build -f Dockerfile .   # カレントディレクトリがコンテキスト
    
    . の位置が正しいか、意図したディレクトリで実行しているか確認。
  2. COPY のパスを絶対化または相対化
    # 悪い例
    COPY ../shared /app/shared
    # 良い例(Dockerfile と同じ階層にある shared ディレクトリをコピー)
    COPY ./shared /app/shared
    
  3. .dockerignore の見直し
    • node_modulesbuild ディレクトリは除外すべきですが、src/** を誤って除外していないかチェック。
    • !(否定)パターンで必要なファイルだけ例外指定する。

実際にやってみたこと
あるフロントエンドプロジェクトで、ルートにある config/ ディレクトリを Docker イメージに入れたかったのですが、Dockerfile が src/ ディレクトリ内にあり、COPY ../config /app/config と書いた結果、ビルドが失敗しました。エラーログは「failed to solve with frontend dockerfile.v0」だけで原因が分からず、数時間検索しました。最終的に docker build -f Dockerfile ../ とコンテキストのルートを変更したら解決しました。この経験から、「Dockerfile の位置とビルドコンテキストは必ず合わせる」 というルールをチームで共有し、CI のビルドスクリプトにも明示的に -f とコンテキストを指定するようにしました。


エラー 4: no space left on device ― ディスク容量不足の見落としが招く悲劇

「Docker が途中で止まって no space left on device」というエラーに遭遇したことはありませんか? 特に開発マシンでイメージやボリュームを何度も作り直すと、/var/lib/docker が肥大化し、ディスクが一杯になるケースが多いです。エラーメッセージは単純ですが、原因がイメージだけなのか、ボリュームなのか、ビルドキャッシュなのかを切り分けるのがポイントです。

なぜ起こるのか
Docker はイメージ層、コンテナの書き込み層、ボリューム、ビルドキャッシュを全て同じパーティションに保存します。docker system prune -a で不要なリソースを削除しない限り、古いイメージや使われていないボリュームがどんどん蓄積します。特に CI 環境やローカルで頻繁に docker compose up --build を走らせると、ビルドキャッシュが大量に残ります。

対策とメンテナンス手順

  1. ディスク使用量の可視化
    docker system df
    
    イメージ、コンテナ、ローカルボリューム、ビルドキャッシュのサイズが一覧で表示されます。
  2. 不要リソースの一括削除
    docker system prune -a --volumes -f
    
    • -a は未使用イメージも削除
    • --volumes は未使用ボリュームも対象
    • -f は確認プロンプトを省略
  3. 定期的なクリーンアップを自動化
    • cron で週1回 docker system prune -a --volumes -f を実行
    • CI のジョブ終了後に docker builder prune -f を走らせる

自分の失敗談
プロジェクトで毎日ビルドを走らせていたとき、ある朝「docker compose up」 がすぐに no space left on device で失敗しました。df -h/var/lib/docker が 95% 超えていることが判明し、docker system df でビルドキャッシュが 30GB 超えていると分かりました。即座に docker builder prune -a -f を実行したら 20GB 程度回復し、再度ビルドが成功しました。その後、GitHub Actions のワークフローに docker system prune -f を組み込み、毎回クリーンな状態でビルドが走るようにしています。「容量不足は見た目ではすぐ分からない」 ので、定期的に docker system df を走らせる習慣が大事です。


エラー 5: exec format error ― アーキテクチャ不一致の盲点

マルチプラットフォームで Docker イメージを扱うとき、standard_init_linux.go:228: exec format error というエラーに出くわすことがあります。特に Apple Silicon(M1/M2)や Windows の WSL2 環境で、x86_64 用にビルドされたイメージをそのまま実行しようとすると起きやすいです。エラーメッセージは「実行形式が不正です」だけで、どのレイヤが問題か分かりにくいです。

原因のメカニズム
Docker イメージはバイナリの実行形式(ELF ヘッダー)に依存します。ホストの CPU アーキテクチャとイメージがビルドされたアーキテクチャが合わないと、カーネルはバイナリをロードできず exec format error を返します。docker run 時に自動的にエミュレーション(QEMU)が走りますが、ベースイメージが scratch だったり、エミュレーションが有効になっていないと失敗します。

対処策

  1. マルチアーキテクチャ対応のベースイメージを使用
    FROM --platform=$BUILDPLATFORM node:18-alpine
    
    --platform フラグでビルド時にターゲットプラットフォームを指定。
  2. docker buildx でマルチプラットフォームイメージを作成
    docker buildx create --use
    docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest --push .
    
    これにより、同一イメージが amd64 と arm64 の両方に対応したマニフェストが生成されます。
  3. ローカルでエミュレーションを有効化
    • macOS(Apple Silicon): brew install qemudocker run --platform linux/amd64 ...
    • WSL2: docker context use default でデフォルトが Linux/amd64 になるか確認

実体験
M1 Mac で Node.js アプリの Dockerfile を作成し、docker compose up したらすぐに exec format error が出ました。docker images でベースイメージが node:18-alpine(amd64)だったことに気づき、FROM --platform=linux/arm64/v8 node:18-alpine に書き換えて再ビルドしたら解決しました。また、CI で docker buildx を使ってマルチアーキテクチャイメージをプッシュするようにしたことで、チーム全員が同じイメージを問題なく使えるようになり、環境依存のエラーが激減しました。「アーキテクチャの不一致は見落としがちだが、--platformbuildx が鍵」 という教訓を得ました。


まとめ

Docker は便利な反面、環境依存のエラーが多く、原因を見極めるのに時間がかかりがちです。今回取り上げた 5 つのエラーは、**「デーモンの起動確認」→「ネットワークとポートの競合」→「権限とグループ」→「ビルドコンテキストの整合性」→「ディスク容量とキャッシュ管理」→「アーキテクチャの一致」**という順序でチェックリスト化すると、トラブルシューティングが格段に楽になります。

  • まずは状態を把握systemctl status dockerdocker system dfdocker network ls などのコマンドで現状を可視化。
  • 権限とグループは基本:ユーザーが docker グループに所属しているか、ソケットの権限は正しいかを確認。
  • ビルドはコンテキストと .dockerignore に注意:不要なファイルが入っていないか、パスが正しいかを常に意識。
  • リソースは定期的にクリーン:容量不足は予防が最善。docker system prune を自動化しておくと安心です。
  • マルチプラットフォームは buildx--platform を活用:アーキテクチャ不一致は見た目では分かりにくいので、ビルド時に明示的に指定しましょう。

これらのポイントを日々の開発フローに組み込めば、Docker のエラーで足踏みする時間が大幅に減ります。ぜひ自分の環境で一度試してみて、エラーが出たら今回のチェックリストを思い出してください。少しずつ慣れてくると、Docker が手放せない強力な開発ツールになるはずです。頑張ってください!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?