Docker bind mount permission denied: 먼저 확인할 것들
마지막 업데이트

Docker bind mount permission denied: 먼저 확인할 것들


Docker bind mount에서 permission denied가 뜰 때, 보통 문제는 Docker 자체보다 host ownership, container user identity, directory traversal permission, SELinux labeling 사이의 불일치에 있습니다.

짧게 말하면, 애플리케이션 코드를 바꾸기 전에 먼저 컨테이너가 어떤 UID/GID로 실행되는지 확인하고, 그 identity를 host path ownership과 parent directory 권한과 비교해야 합니다.


먼저 container identity와 host ownership을 비교하세요

bind mount는 host 파일을 컨테이너 안에 그대로 노출하기 때문에, host 권한 모델이 그대로 중요합니다.

즉 첫 질문은 “앱이 무엇을 하려는가”보다 “컨테이너 프로세스가 누구이며, 그 사용자가 host path에서 실제로 무엇을 할 수 있는가”여야 합니다.

bind mount permission error의 흔한 원인

1. container가 예상과 다른 UID/GID로 실행됨

원래 root로 돌던 image가 특정 non-root user로 바뀌었거나, 배포 설정에서 user:를 명시한 경우가 대표적입니다.

이 identity가 host path ownership과 맞지 않으면 read나 write가 바로 실패할 수 있습니다.

2. parent directory가 traversal이나 write를 막고 있음

팀은 종종 파일 권한만 보지만, 실제로는 상위 디렉터리에도 execute와 write 권한이 필요할 수 있습니다.

3. SELinux나 host labeling이 접근을 막고 있음

SELinux가 활성화된 host에서는 Unix mode가 맞아 보여도 label 때문에 mount가 막힐 수 있습니다.

4. image나 runtime 변경 뒤부터만 문제가 시작됨

기존에는 되던 bind mount가 갑자기 안 되는 이유는 image user, entrypoint, runtime user:, host path 위치가 바뀌었기 때문인 경우가 많습니다.

5. 실제 문제는 mount가 아님

컨테이너가 이미 다른 이유로 실패하고 있는데, 최근 mount를 건드렸다는 이유로 mount만 의심받는 경우도 있습니다.

실전 점검 순서

1. container가 실제로 어떤 user로 도는지 확인하세요

아래 명령이 가장 빠릅니다.

docker inspect <container> --format '{{.Config.User}}'
ls -ld <host-path>
id

Dockerfile 상의 예상 user가 아니라, 실제 runtime identity와 host path ownership을 비교해야 합니다.

2. mounted path와 상위 디렉터리를 같이 보세요

파일 하나는 읽혀 보여도 parent directory가 traversal이나 write를 막고 있을 수 있습니다. 이건 자주 놓치는 포인트입니다.

3. host가 SELinux를 쓴다면 label 요구사항을 확인하세요

ownership과 mode가 맞아 보이는데도 실패한다면 labeling이 강한 후보입니다.

4. 최근 image 또는 deployment 변경과 비교하세요

예전에는 됐다면 무엇이 달라졌는지 봐야 합니다.

  • image user
  • entrypoint
  • runtime user:
  • host path 위치
  • ownership이나 mount flag

이 비교가 mismatch를 빨리 드러내는 경우가 많습니다.

5. app logic보다 권한과 ownership을 먼저 고치세요

mount 자체가 막힌 상황에서는 애플리케이션 코드를 바꿔도 노이즈만 늘어나는 경우가 많습니다.

패턴을 찾은 뒤 어떻게 바꿀지

UID/GID mismatch가 원인인 경우

host ownership을 container user에 맞추거나, 보안 모델을 해치지 않는 범위에서 컨테이너 실행 identity를 조정하세요.

parent directory 권한이 문제인 경우

최종 파일만이 아니라 경로 전체의 traversal/write 권한을 고쳐야 합니다.

SELinux labeling이 문제인 경우

광범위한 권한 완화보다 host에 맞는 label 처리 방식을 써야 합니다.

실제로는 mount가 아닌 startup failure인 경우

그때는 Docker container keeps restarting로 넘어가 startup 자체를 먼저 봐야 합니다.

빠른 체크리스트

bind mount에서 permission denied가 뜰 때는 아래 순서가 가장 실용적입니다.

  1. container UID/GID를 확인한다
  2. mounted path의 host ownership을 비교한다
  3. parent directory execute/write 권한을 본다
  4. 필요하면 SELinux labeling을 확인한다
  5. 최근 image/deployment 변경을 비교한 뒤에만 권한을 바꾼다

FAQ

Q. root로 실행하면 가장 빨리 해결되나요?

대개 아닙니다. 문제를 가릴 수는 있지만 보안 모델을 약하게 만들고 새 ownership 문제를 만들 수 있습니다.

Q. 가장 빠른 첫 단계는 무엇인가요?

container의 runtime UID/GID와 host path ownership을 바로 비교하는 것입니다.

Q. image 업데이트 뒤부터 왜 시작됐나요?

image가 다른 user로 실행되거나 다른 filesystem layout을 기대하게 됐기 때문일 수 있습니다.

Q. 언제 SELinux를 의심해야 하나요?

Unix ownership과 mode가 맞아 보여도 access가 계속 denied 되는 SELinux host일 때입니다.

Sources:

먼저 읽어볼 가이드

검색 유입이 많은 핵심 글부터 이어서 보세요.