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"]
権限設定のベストプラクティス
- ビルドステージで権限を設定:マルチステージビルドの場合、ビルドステージではなく最終ステージで権限設定を行う
- 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
エラーは解消されコンテナが正常に起動します。