エラーの内容ボリュームのマウントがうまくいかないと、Dockerのデプロイが停止してしまうことがよくあります。Docker Composeを使用している場合や、単純な nginx.conf ファイルをマッピングしているときに、次のようなエラーメッセージが表示されることがあります。
Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/path/on/host/config.conf" to rootfs at "/etc/app/config.conf": mount through procfd: not a directory: unknown
このクラッシュは、コンテナの初期化中に発生します。通常は runc であるOCI(Open Container Initiative)ランタイムが、ホストファイルをバインドマウントしようとしますが、解決できない構造的な不一致に遭遇したことを示しています。
根本原因:構造的な不一致これはタイプの不一致です。Dockerはファイルを期待していましたが、フォルダが見つかった(あるいはその逆)状態です。通常、次の3つの一般的なミスのいずれかが原因です。
- ホストファイルの欠落:
/opt/app/settings.confをマウントしようとした際、そのファイルがまだ存在しない場合、Docker(特に古いバージョン)はディレクトリを作成しようとしていると判断します。その結果、ホスト上にsettings.conf/という名前のフォルダが作成されます。コンテナが起動し、ファイルを期待するとエラーになります。- ディレクトリからファイルへの不一致: ホストのディレクトリを、イメージ内ですでに通常のファイルとして定義されているコンテナ内のパスにマウントしようとしています。- ファイルからディレクトリへの不一致: 単一のホストファイルを、実際にはディレクトリであるコンテナ内のパスにマウントしようとしています。procfdというリファレンスは技術的な専門用語です。これは、パスの構成要素が宣言された通りのディレクトリではなかったため、カーネルのファイル記述子(file descriptor)のトラバーサルが失敗したことを意味します。
解決策1:誤って作成されたディレクトリを削除する設定ファイルを実際に作成する前に docker compose up を実行した場合、Dockerがその場所にフォルダを作成してしまった可能性があります。これがこのエラーの最大の原因です。
まず、ホスト上のファイルタイプを確認します。
ls -ld /path/to/your/host/config.conf
パーミッション文字列が d(drwxr-xr-x など)で始まっている場合、ファイルが必要な場所にディレクトリが存在しています。以下の手順でリセットしてください。
- 失敗しているコンテナを停止する:
docker compose down- 誤ったディレクトリを削除する:sudo rm -rf /path/to/your/host/config.conf- ファイルを手動で作成する:touch /path/to/your/host/config.conf- 再度起動する:docker compose up -d## 解決策2:コンテナイメージを調査する不一致がイメージ自体の内部に存在することもあります。DockerfileでRUN touch /etc/app/configを使用している場合、そのパスはファイルになっています。その正確なパスにホストのフォルダをマウントしようとすると、not a directoryエラーが発生します。 イメージの内部を確認して、実際に何があるか見てみましょう。
docker run --rm -it your-image-name ls -ld /etc/app/config
ターゲットがディレクトリである場合は、ファイルをその中にマウントしてください: -v /host/path/config.conf:/etc/app/config/config.conf。
解決策3:絶対パスを使用する相対パスは便利ですがリスクがあります。Dockerのパス解決は、デーモンが実行されている場所によって予測不能になることがあります。ComposeではなくCLIを使用している場合は、常にフルパスを指定してください。
避けるべき例:
docker run -v ./nginx.conf:/etc/nginx/nginx.conf nginx
推奨される例:
docker run -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf nginx
解決策4:壊れたシンボリックリンクを確認するDockerの procfd メカニズムはシンボリックリンクに敏感です。ホストのパスがシンボリックリンクを指している場合、そのリンクが壊れていないことを確認してください。Dockerがファイルを期待しているときにシンボリックリンクがディレクトリを指していると、マウントプロセスが即座にクラッシュします。
ls -l /path/on/host/config.conf でリンクを確認し、リンク先が存在し、正しいタイプであることを確認してください。
検証修正を適用した後は、ただ動くことを願うのではなく、次の3つのステップで検証してください。
- コンテナを起動する:
OCI runtimeエラーを通過し、running状態に達することを確認します。- マウントを検査する:docker inspect <id>を実行します。「Mounts」セクションで、「Source」と「Destination」が意図した通りになっていることを確認します。- アクセスをテストする:docker exec -it <id> head -n 5 /path/in/container/config.confを実行して、コンテナ内部からファイルの最初の5行が表示されるか確認します。## 予防のためのヒント- ファイルを事前に作成する: Dockerコマンドを実行する前に、touch config.envやmkdir -p dataを使用してファイルやディレクトリを準備しておきます。Dockerに推測させてはいけません。- 名前付きボリュームを優先する: ホスト上のファイルをリアルタイムで編集する必要がない限り、名前付きボリューム(例:-v app-data:/var/lib/app)を使用してください。これらはバインドマウントよりも堅牢です。- 明示的なDockerfile: Dockerfile内でRUN mkdir -p /app/configを使用して、ディレクトリ構造に関する曖昧さを排除します。

