Docker

Docker環境でpip freezeに失敗|volumesのパーミッション問題を解消する方法について

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のトラシューばかりして中々開発が進んでいませんが、これはこれで面白いですね。

COMMENT

メールアドレスが公開されることはありません。