はじめに
こんにちは。dd_fortです。
前回に引き続き、Dockerについての話になります。
Dockerの学習中に詰まった権限についての問題と、その解決法を紹介します。
ボリューム(Data Volume)とは
ボリュームとは、データを永続化できる場所を指します。
Dockerのコンテナ内部のデータはコンテナ破棄をすると消えてしまうため、
データを永続化させるための手段として ボリューム(volume) が存在します。
コンテナ内部の永続化の詳しい内容については、こちらの記事を参照ください。
permission denied が発生する問題
Linux上でDockerコンテナ内でボリュームをマウントした際に、ホストからアクセスした場合に パーミッションの問題が発生することがあります。
ホストOSで使っているユーザとコンテナ内で使っているユーザのUIDとGIDが不一致になることが原因のようです。 そのため、Docker for Mac/Windowsではほとんど発生しません。
$ id uid=1000(test) gid=1000(test) groups=0(test) # (コンテナ内) # id uid=0(root) gid=0(root) groups=0(root)
発生する環境
解決法
解決法1:マウントしたボリュームの権限を書き換える
permission deniedが発生したディレクトリ、ファイルの権限を直接書き換えることで解決することができます。
$ chmod 777 /var/project
しかし、permission denied が発生しているファイル、フォルダのすべての権限を書き換えないといけないため、根本的な解決にはなりません。
解決法2:ユーザ情報の書かれたファイルを読み込み専用でマウントする
コンテナ内のUIDとGIDがホストOSと同じになるように、コンテナ起動時にUIDとGIDを指定します。
また、/etc/passwd
との不整合が起きないようにホストOSの/etc/passwd
をマウントする必要があります。
最後に、コンテナから/etc/passwd
を書き換えないようにread only (:ro
) でマウントします。
$docker run \ -u "$(id -u $USER):$(id -g $USER)" \ -v /etc/passwd:/etc/passwd:ro \ -v /etc/group:/etc/group:ro \ -it ubuntu
実行結果
$ id uid=1000(test) gid=1000(test) groups=1000(test) # (コンテナ内) test@hogehoge:~$ id uid=1000(test) gid=1000(test) groups=1000(test)
問題なくコンテナ内とホストOSでユーザ情報が共通化されていることが確認できました。
ただしこの方法のデメリットとして、別プラットフォーム間ではDockerファイル等を共有することができなくなります。
解決法3:コンテナ作成時にユーザとグループを追加する
ホストOSのユーザ(UID)、グループ(GID)を環境変数として渡し、コンテナ内でユーザとグループを追加します。
# Dockerfile FROM ubuntu:latest RUN apt update \ && apt -yq dist-upgrade \ && apt install -yq --no-install-recommends \ sudo COPY entrypoint.sh /var/tmp CMD bash -E /var/tmp/entrypoint.sh && /bin/bash
コンテナが終了しないように/bin/bash
で対話モードで動かし続けます。
# docker-compose.yml version: "3" services: override: image: example/override-ids build: . container_name: override environment: - USER_NAME - USER_ID - GROUP_NAME - GROUP_ID volumes: - ./:/mnt/working tty: true
環境変数で、ユーザ(UID)、グループ(GID)を渡すように設定します。
# entrypoint.sh useradd -s /bin/bash -m ${USER_NAME} export HOME=/home/${USER_NAME} usermod -u ${USER_ID} ${USER_NAME} groupadd -g ${GROUP_ID} ${GROUP_NAME} usermod -g ${GROUP_NAME} ${USER_NAME}
useradd
、groupadd
でユーザとグループを追加。
usermod
でユーザとグループを設定。
コンテナをビルドして実行します。
$ docker-compose build $ USER_NAME=$(id -un) \ USER_ID=$(id -u) \ GROUP_NAME=$(id -gn) \ GROUP_ID=$(id -g) \ sudo -E docker-compose up -d
実行結果
$ id uid=1000(test) gid=1000(test) groups=1000(test) $ docker exec -it override su - $(id -un) test@hogehoge:~$ id uid=1000(test) gid=1000(test) groups=1000(test)
まとめ
Dockerのコンテナ内にvolumeをマウントする際は、UID/GIDを正しく設定しなければなりません。
簡単な手段としての解決法は1,2ですが、解決法3を使うとほとんどの問題を解決することができます。
Dockerではまだまだ勉強を始めたばかりなので学習を進めていこうと考えています。
エンジニア中途採用サイト
ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
ご興味ありましたら是非ご確認をお願いします。
https://career-recruit.rakus.co.jp/career_engineer/カジュアル面談お申込みフォーム
どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
以下フォームよりお申込みください。
rakus.hubspotpagebuilder.comラクスDevelopers登録フォーム
https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/イベント情報
会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
◆TECH PLAY
techplay.jp
◆connpass
rakus.connpass.com