LoginSignup
1
1

More than 1 year has passed since last update.

Dockerコンテナ内でホストと同じユーザで作業(sudoコマンド有り)

Posted at

目的

ホストのUID/GIDで作業可能なsudo付きDockerコンテナをDockerfileを作成せず、かつ出来るだけ制約の少ない方法で立ち上げる。

背景

Dockerコンテナを開発環境として使っていると、デフォルトがrootユーザなせいで、ファイルのownerの問題にぶち当たる。

よくあるパターンが、ディレクトリをマウントして作成したファイルのownerがrootになってて、がホスト側から編集出来ない、とかいうケース。

Dockerコンテナを開発環境に使ってると、よくこのパターンにハマり、ownerを変更するためだけにコンテナを起動したりすることも...。

回避方法として-u $(id -u):$(id -g)のオプションを付ける方法あるが、これだけではホスト側のユーザIDと一致しなかったり、sudoが使えなかったりと困ることも多い。

じゃあ、sudoインストールしたりuseraddしたりするDockerfileを作るというのもあるが、いちいちpullしてきたイメージに対してそれをやるのも面倒。

というわけで、できるだけ簡単にホストユーザのsudo付きDockerコンテナを立ち上げるコマンドの紹介。

方法

UbuntuとCentOSで若干違うので分けて記載。

Ubuntu

コンテナ名は適当にtest-user-with-sudoとでもしときます。

CNAME=test-user-with-sudo

まずは、コンテナ起動。

ubuntu
docker run -it --name ${CNAME} \
    -u $(id -u):$(id -g) \
    -v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro \
    -v ${HOME}/src:${HOME}/src -w ${HOME} \
    ubuntu:20.04 bash
  • -u $(id -u):$(id -g) : ユーザ:グループを指定
  • -v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro:ホスト側との整合性(リードオンリー)
  • -v ${HOME}/src:${HOME}/src:お好み。私の場合はソースコードとか大抵ホームディレクトリに置いてるので。
  • -w ${HOME}:お好み。コンテナ入る度にホームディレクトリに移動するのが面倒なので。

このままだと、

$ sudo apt update
bash: sudo: command not found

のようにsudoが使えないため、使えるようにする。
コンテナ起動後、一旦C-p C-qで抜ける。

ubuntu
docker exec -it -u root ${CNAME} \
    bash -c "apt update && apt install sudo -y \
    && ( echo $(id -nu):$(id -nu) | /usr/sbin/chpasswd ) \
    && ( echo \"$(id -nu) ALL=(ALL:ALL) NOPASSWD: ALL\" | tee /etc/sudoers.d/$(id -nu) )"
  • apt install sudo -ysudoをインストール
  • echo $(id -nu):$(id -nu) | /usr/sbin/chpasswd:パスワードを設定(パスワードにユーザ名を使用している)。
    • 一見すると/etc/passwdroなので実行できなそうに見えるが、実際パスワードは/etc/shadowに保存されており、こちらはマウントしていないため問題なく実行できる。
  • echo \"$(id -nu) ALL=(ALL:ALL) NOPASSWD: ALL\" | tee /etc/sudoers.d/$(id -nu) )sudoをパスワード無しで実行できるようにする。
    • パスワード無しはセキュリティ的に...と感じるかもしれないが、上記のコマンドから分かるように、そもそも横から簡単にrootで実行できちゃうため、ここでは気にしない。
    • 今回はあくまで開発環境など性善説的な場面を想定しており、セキュリティ面を気にする場合はrootlessモードを使うのが良さそう。

パスワード無しsudoなので「パスワードの設定」は不要そうだが、パスワード設定をしておかないとsudoコマンドが使えなかったため設定。

動作確認。

# ホスト
$ docker attach ${CNAME}
-----
# コンテナ内
$ sudo apt update

CentOS

パスワードの設定方法が若干違うが、基本的に同じ。

CNAME=test-suer-with-sudo

docker run -it --name ${CNAME} \
    -u $(id -u):$(id -g) \
    -v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro \
    -v ${HOME}/src:${HOME}/src -w ${HOME} \
    centos:8 bash

# C-p C-q で抜ける

docker exec -it -u root ${CNAME} \
    bash -c "yum install sudo passwd -y \
    && ( echo $(id -nu) | passwd --stdin $(id -nu) ) \
    && ( echo \"$(id -nu) ALL=(ALL:ALL) NOPASSWD: ALL\" | tee /etc/sudoers.d/$(id -nu) )"

最後に

Dockerコンテナを開発環境として使うと、ツールのインストールやビルド済みのイメージが使えたりしていろいろ便利です。

マシンが自分しかログインしない場合には、${HOME}を丸ごとマウントしてsshの設定などを引き継ぐ、みたいな使い方もできます。ただし、コンテナにアタッチされるとホームディレクトリが丸見えなので、使用の際にはご注意を。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1