Dockerfile –build-arg option

도커 컨테이너를 띄울 때 volume을 설정해서 persistence를 잡아 줄 때, 컨테이너에 마운팅되는 방식이 머신별로 차이가 있는 것을 발견하였다.

필자는 php:7.1.10-fpm-alpine 이미지를 이용하여 컨테이너를 띄웠다.

볼륨을 마운트하면, 마운팅 된 디렉토리의 UID와 GID가 계속 1000으로 나오는 것이었다.

컨테이너에서 php-fpm을 띄우는 사용자는 www-data로 세팅해 놓았고, www-data 사용자의 UID와 GID는 둘 다 기본으로 82로 잡혀 있었다.

www-data 사용자로는 마운팅된 디렉토리에 쓰기 permission이 주어지지 않았으니 기록을 못하는 것이 당연하다.

그래서 찾아낸 것이 Dockerfile을 빌드할 때 주는 옵션이 있다는 것을 알게 되었다. 바로 “–build-arg 변수명=변수값”이다. 컨테이너 내의 사용자인 www-data의 UID를 Host에서 현재 docker를 사용하는 사용자의 UID로 바꾸면 된다.

docker build \
  --build-arg HOST_UID=$(id -u) \
  --build-arg HOST_GID=$(id -g)

위와 같이 UID와 GID를 설정하고 Dockerfile에는 아래와 같은 내용을 추가하였다.

ARG HOST_UID
ARG HOST_GID

RUN usermod -u ${HOST_UID} www-data
RUN groupmod -u ${HOST_GID} www-data

도커 이미지를 생성한 후 컨테이너의 www-data 사용자의 UID가 바뀐 것을 확인하였다.

이렇게 하면, 개발자마다 로그인하여 사용하는 PC의 UID가 다르더라도 각자의 환경에 맞게 적용이 가능하다.

필자는 개발용 머신으로 우분투 17.10을 사용 중인데, 별 문제 없이 잘 되었다. 하지만, MacOS에서는 Group 이름이 staff이며 GID는 20이라서 다음과 같이 충돌이 발생한다.

groupmod: GID '20' already exists

테스트 해 본 결과 Mac에서는 GID를 변경하지 않아도, Host의 파일의 권한이 Host의 UID와 GID로 유지된다. 하지만 Host가 리눅스인 경우 GID를 변경하지 않으면 컨테이너의 www-data 그룹의 기본 id인 82로 세팅되는 것을 확인하였다.

따라서 Mac에서는 빌드 시에 다음과 같이 GID 세팅을 빼 주면 된다.

docker build \
  --build-arg HOST_UID=$(id -u)

Dockerfile에서는 GID 변경 부분을 제외한다.

ARG HOST_UID

RUN usermod -u ${HOST_UID} www-data

작성하고 보니, 이 부분들도 쉘 스크립트를 작성하면 중복을 제거하고 하나의 파일로 구동이 가능할 것 같다. 이 부분은 독자의 몫으로 남겨놓겠다.

Leave a Comment