Skip to content

Dockerコンテナ実行時のパーミッションエラー解決方法

問題の原因

Dockerでビルドしたコンテナを実行する際、以下のエラーが発生します:

docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "./deployment-service": permission denied: unknown

このエラーの根本的な原因は、コンテナ内で実行しようとしているバイナリファイル(deployment-service)に実行権限がないことです。特にalpineベースの軽量イメージを使用する場合、ファイルのパーミッションが適切に設定されていないとこのエラーが頻発します。


効果的な解決方法

方法1: 実行権限を明示的に設定(推奨)

Dockerfileにchmodコマンドを追加し、バイナリファイルに実行権限を付与します:

dockerfile
# マルチステージビルドの最終ステージ
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/

COPY --from=builder /workspace .

# 実行権限の付加
RUN chmod +x deployment-service

ARG DEFAULT_PORT=8080
ENV PORT $DEFAULT_PORT
EXPOSE $PORT

CMD ["./deployment-service"]

方法2: ENTRYPOINTを使用した実行

ENTRYPOINTで直接実行すると、ファイルの実行権限が暗黙的にチェックされます:

dockerfile
ENTRYPOINT ["./deployment-service"]

補足事項

Alpineイメージ特有の注意点

Alpine Linuxではbashがデフォルトでインストールされていません。bashを使用している場合、スクリプト内でshに変更する必要があります:

dockerfile
# 間違った例(bashは存在しない)
CMD ["bash", "-c", "java -jar app.jar"]

# 正しい例(shを使用)
CMD ["sh", "-c", "java -jar app.jar"]

権限設定のベストプラクティス

  1. ビルドステージで権限を設定:マルチステージビルドの場合、ビルドステージではなく最終ステージで権限設定を行う
  2. root以外のユーザー使用時:ユーザー切り替え(USER命令)のに権限設定を完了させる

よくある間違った対処法

よく提案される以下の方法は根本解決にならないため注意が必要です:

bash
docker system prune -a  # キャッシュ削除(一時的な回避策)

このコマンドはキャッシュをクリアしますが、根本的なパーミッション問題は解決しません。Dockerfileの修正が必須です。


修正後の実行コマンド例

環境変数を使った実行コマンドの例(修正後も変化なし):

bash
docker run --name=${CONTAINER_NAME} -d --rm \
  -p ${PORT}:80 \
  -e DEPLOYMENT_SERVICE_DATABASE_CONNECTION_URI=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_CONTAINER_NAME}:27017/ \
  -e DEPLOYMENT_SERVICE_SERVER_SECRET_KEY=${SECRET_KEY} \
  -e ANSIBLE_CONFIG='./jam-ansible/ansible.cfg' \
  -e DEPLOYMENT_SERVICE_ANSIBLE_SUBMISSION_ROOT=${DEPLOYMENT_ROOT} \
  -v ${DEPLOYMENT_VOLUME}:${DEPLOYMENT_ROOT} \
  --network=${NETWORK_NAME} \
  server:latest

権限設定を適切に行えば、permission deniedエラーは解消されコンテナが正常に起動します。