DockerでDjango環境を立ち上げる時に、volumesのパーミッション問題でハマり倒したので解消方法をまとめます。
ディレクトリ構成はこちら。
. ├── Makefile ├── docker-compose.yml └── main ├── Dockerfile ├── entrypoint.sh └── requirements.txt
解決した問題
今回解消した問題は以下の2つです。
・Django用のコンテナにアタッチしてpip freezeコマンドを実行するとパーミッションエラーが発生する。
・コンテナにアタッチしている時に作成したファイルやディレクトリをホストから編集しようとするとパーミッションエラーが発生する。
原因
ホストのUIDとGIDが、コンテナの中のvolumesのUIDとGIDと一致していないことが原因でした。
ネットを探すといくつか解消方法がありましたが、今回はEntrypointでUIDとGIDを設定するシェルスクリプトを実行する方法で解消しました。
Entrypointとは
日本語の版Dockerドキュメントを参照しました。
ENTRYPOINT命令は、作成したシェルスクリプトなどを実行させることができ、コンテナ環境の構築の役に立つようです。
今回は、UIDとGIDを任意の値にするスクリプトを実行させます。
スクリプトはこちらの記事を参考にしました。感謝!
Docker Composeのvolumes使用時に出会うpermission deniedに対応する一つの方法
問題の解消方法
Dockerfileと同じディレクトリにentrypoint.shを作成して、以下のスクリプトを貼り付けます。
gosuというのは、GO言語製のsudoコマンドみたいなものらしいです。
初めて見ましたが、PosgreのDockerイメージでも使われているらしく、割と一般的なのかもしれません。
USER_IDとGROUP_IDには、ホストと同じ値を入れてあげてください。
僕の環境ではどちらも1000でした。
#entrypoint.sh
#!/bin/bash USER_ID=1000 GROUP_ID=1000 echo "Starting with UID : $USER_ID, GID: $GROUP_ID" useradd -u $USER_ID -o -m user groupmod -g $GROUP_ID user export HOME=/home/user exec /usr/sbin/gosu user "$@"
次に、Dockerfileに以下のスクリプトを追記します。
実行時に「WARNING: apt does not have a stable CLI interface. Use with caution in scripts.」みたいな警告がでますが、無視でOKです。
スクリプトに書くときはapt-getを使おうという警告なのですが、Debianがもうaptを推奨してるようなので、気にしなくていいかと思います。
#Dockerfile
RUN apt update && apt install gosu -y COPY entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
さて、これでコンテナを起動すれば、コンテナ側とホスト側で同じファイルの読み書きが問題無くできるかと思います。
まとめ
最近は環境構築に積極的にDockerを取り入れてます。
Dockerのトラシューばかりして中々開発が進んでいませんが、これはこれで面白いですね。