ちょっとしたサービスを作りたいと思い、勉強しながらConoHa VPS上でDocker環境を構築中です。
Dockerコンテナとホスト側でvolumeによりファイルを共有したとき、特に何も設定しなければ、コンテナ内で作成したファイルがホスト側でもroot権限で作成されてしまいます。
ホスト側でそのファイルを使うときに不便なので、ホスト側のユーザIDとグループIDをDockerコンテナ側に設定する方法についてまとめたいと思います。
やり方は幾つかありようですが、この記事では、「docker-compose.ymlのcommandでフォルダのユーザIDとグループIDを設定するscriptを実行させる」方法についてまとめたいと思います。
※その他の方法は「ホスト側のユーザIDとグループIDをコンテナ側に設定する方法について調べてみた!」のブログを参考ください。
目次
事前準備
この記事では、以下の準備ができている想定です。
- Linux上にDocker、Docker Compose環境が構築できていること
もし準備がまだの方は、以下にConoHa VPS(仮想専用サーバ)上にDocker、Docker Compose環境の構築方法をまとめましたので、ご参考にしてください。
Dockerコンテナをホスト側のユーザIDとグループIDで生成する方法
「docker-compose.ymlのcommandでフォルダのユーザIDとグループIDを設定するscriptを実行させる」ような設定をしていきます。
環境は以下です。
- ConoHa VPS (メモリ 1GB/CPU 2Core/SSD 100GB)
- Ubuntu 18.04.4 LTS
- Docker: 19.03.8 (2020/3/22 執筆時点の最新)
- Docker Compose: 1.25.4 (2020/3/22 執筆時点の最新)
また、以下のようなディレクトリ構成とし、djangoコンテナにホスト側のユーザIDとグループIDを設定することを想定しています。
work
|-- django
| `-- script
| `-- setUserGroup.sh
`-- docker-compose.yml
「~/work/dokcer-compose.yml」の設定
「~/work/dokcer-compose.yml」に以下の設定をします。
volumes:
でホスト側のscriptをコンテナにマウントcommand:
でscriptを実行environment:
に環境変数として、ユーザID、グループIDを設定
version: '3.5'
services:
django:
volumes:
- ./django/script:/script:ro
command: >
bash -c "
source /script/setUserGroup.sh &&
[既存のコマンド]
"
environment:
- USER_ID=[ユーザID]
- USER_NAME=[ユーザ名]
- GROUP_ID=[グループID]
- GROUP_NAME=[グループ名]
- 既存の設定があったら、そこに
volumes:
、command:
、envrionment:
配下の設定を追加します。 volumes:
の./django/script
はこの後作成します。[既存のコマンド]
がある場合は、bash -c " "
内の&&
でlコマンドをつなげることで複数のコマンドを実行できるようになります。[ユーザID]
、[ユーザ名]
、[グループID]
、[グループ名]
はご自分の環境に合わせて設定してください。なお、ご自分のユーザID等を確認する方法を、「補足 ユーザID、グループIDを確認するコマンド」でまとめたので、よろしければそちらを参考ください。
「~/work/django/script/setUserGroup.sh」の設定
ユーザID、グループIDの設定を行うために、以下のようなscriptを作成します。
#!/bin/bash -e
SHELL_NAME='setUserGroup.sh'
echo "[$SHELL_NAME] START"
# グループID、グループ名の設定
if getent group "$GROUP_ID" > /dev/null 2>&1; then
echo "[$SHELL_NAME] GROUP_ID '$GROUP_ID' already exists."
else
echo "[$SHELL_NAME] GROUP_ID '$GROUP_ID' does NOT exist. So execute [groupadd -g \$GROUP_ID \$GROUP_NAME]."
groupadd -g $GROUP_ID $GROUP_NAME
fi
# ユーザID、ユーザ名の設定
if getent passwd "$USER_ID" > /dev/null 2>&1; then
echo "[$SHELL_NAME] USER_ID '$USER_ID' already exists."
else
echo "[$SHELL_NAME] USER_ID '$USER_ID' does NOT exist. So execute [useradd -m -s /bin/bash -u \$USER_ID -g \$GROUP_ID \$USER_NAME]."
useradd -m -s /bin/bash -u $USER_ID -g $GROUP_ID $USER_NAME
fi
echo "[$SHELL_NAME] FINISH"
exec $@
作成後、以下のコマンドで実行権限を設定するのを忘れずにしてください。
$ chmod +x ~/work/django/script/setUserGroup.sh
コンテナを起動する
コンテナを起動させると、ユーザIDとグループIDが設定されていない場合は以下のようなログが表示されると思います。
django | [setUserGroup.sh] START
django | [setUserGroup.sh] GROUP_ID 'XXXX' does NOT exist. So execute [groupadd -g $GROUP_ID $GROUP_NAME].
django | [setUserGroup.sh] USER_ID 'XXXX' does NOT exist. So execute [useradd -m -s /bin/bash -u $USER_ID -g $GROUP_ID $USER_NAME].
django | [setUserGroup.sh] FINISH
- ユーザIDとグループIDを設定するためにはroot権限が必要なため、この設定を行うときにはrootユーザで実行してください。
- XXXXにはグループID、ユーザIDが入ります。
この後は、docker-compose run -u [ユーザ名]
やdocker exec -u [ユーザ名]
などのように-u
オプションによってユーザ名を指定すれば、設定したユーザID、グループIDでコンテナ内に入ることができます。
そのため、移行は-u
オプションを定義すれば、コンテナ内のファイルもホスト側と同じユーザ権限で作成することができるようになります。
補足 ユーザID、グループIDを確認するコマンド
# ユーザID確認
$ id -u
# ユーザ名確認
$ id -un
# グループID確認
$ id -g
# グループ名確認
$ id -gn
関連情報
ホスト側のユーザIDとグループIDをコンテナ側に共有する方法は幾つかあるようです。
以下のブログに調査した内容をまとめましたので、よろしければご覧ください。
ConoHa上でDockerを導入したり、Webアプリを立ち上げたりした内容を以下の記事でまとめました。こちらもよろしければご覧になってください。
広告
Dockerをやるなら以下の書籍がオススメです。
Dockerとは何か?から複数のコンテナを管理することができるDocker Compose、Kubernetesまでまとめられています。
ConoHa VPS
は初期費用不要で月に数百円で利用できる仮想サーバのサービスです。以下のような方には非常にオススメのサービスとなっています!
- 勉強がてらLinuxの環境をちょっと触ってみたい
⇒管理者権限が実行可能なLinuxサーバ環境が構築可能です! - スモールスタートでサービスを提供して、うまくいったら規模をスケールアップしたい
⇒後からメモリサイズやCPU数などのスケールアップ/スケールダウン可能です! - AWSやGCPなどのクラウドサービスは高いので、もっと安くサーバ構築したい
⇒初期費用なし、月数百円(1時間単位も可)で利用可能です!
以上!
コメント