Dockerのコンテナとホストで共有フォルダを設定する手順

公開日:2018/08/14 更新日:2018/08/14
Dockerのコンテナとホストで共有フォルダを設定する手順のサムネイル

はじめに

Dockerのホスト側(すなわち、自分のローカルPC)とコンテナ側で共有フォルダを作成すると、ホスト側で色々なファイルを編集したり追加したりして、コンテナ側でそのファイルを実行することができます。これならコンテナ側で使いたいコードをホスト側で好きなエディタを使って編集できます。ここでは、ホスト側とコンテナ側の共有フォルダを設定するための手順をメモします。

環境と手順概要

  • ホストOS : Ubuntu18.04
  • Docker version: 18.06.0-ce
ここでは詳しい説明は省略しますが、共有フォルダを設定するにあたってポイントとなるのは、ホスト側のユーザのUIDと、コンテナ側に作成するユーザのUIDを一致させることになります。ホストとコンテナはUIDとGID(グループID)が独立しているわけではなく共有しているため、このUIDを一致させることでホスト側のユーザの権限とコンテナ側のユーザの権限を一致させて共有できるようにします。この点については、以下の参考サイトに詳しく書かれており理解が深まりました。 Dockerコンテナ内のユーザとホストのユーザとの関係について Understanding how uid and gid work in Docker containers inanzzz | Running docker container with a non-root user and fixing shared volume permissions with Dockerfile

具体的な手順としては以下のようになります。

  • ホスト側のユーザのUIDを確認する
  • 同一のUIDを持つユーザを追加する設定をDockerfileに記述
  • 共有フォルダを指定してコンテナを作成、起動する

ホスト側のユーザのUIDを確認する

以下のように、idコマンドでUIDを確認します。

hostuser1@hostpc$ id
uid=1000(hostuser1) gid=1000(hostuser1) groups=1000(hostuser1)

hostuser1のUIDが1000となっているので、コンテナ側でもUIDが1000であるユーザを作成します。

UIDについて

Ubuntuで設定されるUIDは、通常だと1000からになります。これは、以下のように/etc/adduser.confというファイルにて設定されています。

/etc/adduser.conf
(・・・上省略・・・)
# package, may assume that UIDs less than 100 are unallocated.
FIRST_SYSTEM_UID=100
LAST_SYSTEM_UID=999

FIRST_SYSTEM_GID=100
LAST_SYSTEM_GID=999

# FIRST_[GU]ID to LAST_[GU]ID inclusive is the range of UIDs of dynamically
# allocated user accounts/groups.
FIRST_UID=1000
LAST_UID=59999

FIRST_GID=1000
LAST_GID=59999
(・・・下省略・・・)

システム用には100から、ユーザ用に1000からスタートしていることが分かります。

同一のUIDを持つユーザを追加する設定をDockerfileに記述

まず、適当なフォルダに移動して、そこでDockerfileを作成します。Dockerfileの中身は後述します。以下では/home/hostuser1/dockerという適当なフォルダにDockerfileを作成しています。

$ cd /home/hostuser1/docker
$ vi Dockerfile

Dockerfileの中身を以下のように記述します。

# ubuntuコンテナを元にする
FROM ubuntu

ENV user contuser1

RUN useradd -u 1000 -m -d /home/${user} ${user} \
 && chown -R ${user} /home/${user}

USER ${user}

CMD ["/bin/bash"]

上記のuserddコマンドでコンテナ側のユーザcontuser1を新規作成しています。useradd-u 1000にてuidを1000に指定しています。なお、useraddコマンドについては、useraddコマンドについて詳しくまとめました 【Linuxコマンド集】に詳しく説明が載っており大変参考になります。 また、上記で使用しているuseraddのオプションの説明をいかに載せます。その他のオプションについては、useraddマニュアルにまとめられており勉強になります。

-u UID 新規追加するユーザのUIDを指定します。
-m 新規追加するユーザのホームフォルダも一緒に作成します。
-d フォルダパス 新規追加するユーザのログイン時のデフォルトのフォルダを指定します。

以下のコマンドでビルドします。mydockerは適当につけたコンテナ名です。

$ sudo docker build -t mydocker .

これで後はDockerを起動します。

共有フォルダを指定してDockerを作成、起動する

以下のコマンドでホスト側とコンテナ側の共有するフォルダを指定してコンテナを作成、起動することができます。以下のコマンドでは、ホスト側のフォルダとして/home/hostuser1/docker、コンテナ側のフォルダとして/home/contuser1を共有フォルダとしてそれぞれ指定しています。以下に各オプションの説明を載せます。

$ sudo docker run -v /home/hostuser1/docker:/home/contuser1 -it mydocker bash
オプション 説明
-v ホストのフォルダパス:コンテナのフォルダパス ホストのフォルダパスとコンテナのフォルダパスを共有フォルダとして指定します。
-it シェルで操作するために入力待受状態にします。厳密には、-i-tと別々のオプションです。コンテナ内で操作したい場合は使います。

上記で必要な設定は完了です。ホスト側、コンテナ側で指定したフォルダにファイルを追加したり、ファイルを編集したりするとそれぞれのフォルダが同期されます。このようにホスト側とコンテナ側で共有フォルダを設定できれば、コードなどはホスト側の好きなエディタを使って編集し、そしてそのコードをコンテナ側で実行することが便利です。

dockerコマンドをsudoなしで使用するための設定

なお、dockerコマンドはデフォルトだと実行にroot権限が必要になります。ただ、毎度sudoをつけるのは面倒な上、セキュリティ上よろしくありません。そこで通常使用している一般ユーザをdockerグループに所属させることでroot権限なしにdockerコマンドを実行できるようにします。以下手順です。 まずdockerというグループが存在しているかを/etc/groupの中に含まれるかで確認します。すでに存在している場合は以下のようにdockerと記載されている部分を見つけられると思います。

$ vi /etc/group
(・・・上省略・・・)
docker:x:999:hostuser1

もしまだdockerというグループが存在しない場合はgroupaddで作成します。

$ sudo groupadd docker

そして一般ユーザをusermoddockerグループに所属させます。$USERにはいまログインしている一般ユーザ名が入ります。

$ sudo usermod -aG docker $USER

これで後はホストを再起動すれば、sudoなしでdockerを実行できるようになります。 なお、usermodコマンドにて-aオプションをつけずに-Gオプションのみで所属グループを指定してしまうと、指定したグループにのみ所属する状態となり、元々所属していたグループから外れるので注意してください。以下の参考サイトにusermodのオプション全般について詳しく書かれており大変勉強になりました。 【linux】 ユーザーをグループに追加する際は gpasswd -a か usermod -aG を使う方がいい usermodコマンドについて詳しくまとめました 【Linuxコマンド集】

まとめ

Dockerを使い始めてみると、これまで色々な環境構築にかかっていた時間を大幅に短縮でき、またローカル環境をいじる必要がないので精神的にもハードルが下がりました。環境構築手順に変更があっても、それに対応済のコンテナを持ってくれば良いのは楽です。

関連記事

開発アプリ

nanolog.app

毎日の小さな出来事をなんでも記録して、ログとして残すためのライフログアプリです。