Posted at

Dockerコンテナを非rootユーザで実行する


rootユーザの問題


  • Dockerコンテナを実行するとrootユーザで実行される

  • ファイルを生成するコンテナを実行するとowner:groupがrootになる


    • -uオプションで回避できる場合もある



  • 一般ユーザでは生成されたファイルにアクセス権がない

  • ホスト側でマウントしたときなどに一般ユーザでなにかと困る



一般ユーザで実行してほしいもの例


  • ファイルを作成するコマンド

  • Jupyter

  • サイト/ドキュメントビルダ


    • pandoc

    • sphinx

    • etc





コンテナを実行してファイルを作成した例

$ docker run --rm -v /tmp:/tmp debian:stable-slim touch /tmp/a.txt

$ ls -n /tmp/a.txt
-rw-r--r-- 1 0 0 0 8月 10 16:35 /tmp/a.txt

一般ユーザからはファイルの書き込みができなくなる



run-non-root

Run Linux commands as a non-root user, creating a non-root user if necessary.

https://github.com/creemama/run-non-root



run-non-rootの機能


  • コンテナが一般ユーザで実行できる


    • 実行時にユーザが作成される

    • Dockerfileでハードコートする必要がない



  • UID:GIDが指定できる

  • USERNAME:GROUPNAMEが指定できる



run-non-rootの実行例

$ docker run --rm -v /tmp:/tmp creemama/run-non-root:latest -- touch /tmp/a.txt


Running ( exec su-exec nonroot:1000 touch /tmp/a.txt ) as uid=1000(nonroot) gid=1000(nonroot) groups=1000(nonroot) ...

$ ls -n /tmp/a.txt
-rw-r--r-- 1 1000 1000 0 8月 10 16:36 /tmp/a.txt

デフォルトではUID:GID=1000:1000で実行される



オプションでUID:GIDを指定

$ docker run --rm -v /tmp:/tmp creemama/run-non-root:latest -u 1001 -g 999 -- touch /tmp/a.txt


Running ( exec su-exec nonroot:999 touch /tmp/a.txt ) as uid=1001(nonroot) gid=999(ping) groups=999(ping) ...

$ ls -n /tmp/a.txt
-rw-r--r-- 1 1001 999 0 8月 10 16:36 /tmp/a.txt



環境変数でUID:GIDを指定

$ docker run --rm -v /tmp:/tmp -e RUN_NON_ROOT_GID=1001 -e RUN_NON_ROOT_UID=999 creemama/run-non-root:latest -- touch /tmp/a.txt


Running ( exec su-exec nonroot:1001 touch /tmp/a.txt ) as uid=999(nonroot) gid=1001(nonroot) groups=1001(nonroot) ...

$ ls -n /tmp/a.txt
-rw-r--r-- 1 999 1001 0 8月 10 16:37 /tmp/a.txt



run-non-rootのなかみ


  • su-exec

  • tini

  • run-non-root.sh



su-exec


  • 指定したユーザ権限でプログラムを実行

  • su, sudoが予測不可能なTTY、シグナル送信の問題を回避

  • gosuより軽い



tini


  • PID=1のプロセスがゾンビになることを回避

  • SIGTERMが正しく処理される

  • dockerの--initオプションで代用可?



run-non-root.sh


  • 一般ユーザでコンテナを実行するシェルスクリプト

  • 実行時にユーザを作成する


    • Dockerfileへのハードコート不要



  • 任意のユーザが扱える



つくったもの

https://hub.docker.com/r/driller/jupyter


  • run-non-rootを使ったJupyterを実行するDockerイメージ

  • 一般ユーザでJupyter Notebook/JupyterLabを実行



Jupyter Notebookの起動例

docker run --rm -v <path_to_work_dir>:/notebooks -p 8888:8888 -e RUN_NON_ROOT_UID=$(id -u) -e RUN_NON_ROOT_GID=$(id -g) driller/jupyter jupyter notebook --no-browser --ip="0.0.0.0"

<path_to_work_dir> にはマウントするPathを指定



Jupyter Labの起動例

docker run --rm -v <path_to_work_dir>:/notebooks -p 8888:8888 -e RUN_NON_ROOT_UID=$(id -u) -e RUN_NON_ROOT_GID=$(id -g) driller/jupyter jupyter notebook --no-browser --ip="0.0.0.0"

<path_to_work_dir> にはマウントするPathを指定