🦴

Debian系開発コンテナ用ユーザー切り替えスタートスクリプト書いた

2024/06/30に公開

はじめに

以下の記事で Jupyter 公式のユーザー切り替え機能だけ抜き出した。

https://zenn.dev/wsuzume/articles/1be3aee84d1cb2

しかし以下のような点が使いにくかった。

  • マルチステージのうちひとつのステージだけをリポジトリとして抜き出しても配置やビルドがけっこう面倒臭い[1]
  • 既存のユーザーを削除して作り直したり、グループを無理やり重複させたりとけっこう破壊的な操作をしている。

これらの欠点を解消するために、以下のような改良を施したスタートアップスクリプトを書き直した。

  • コンテナに対する変更は /usr/local/bininit.sh を作成するのみである
  • Dockerfile 中でコンテナに簡単にインストールできる
  • 指定したユーザーはコンテナ内に既にあればそれが使われ、存在しないときのみ作成される

https://github.com/wsuzume/devel-entrypoint

Install

Debian系のベースイメージにのみ対応しています[2]

ユーザー切り替え機能を追加したいイメージの Dockerfile に以下のスクリプトを追加するだけです。

RUN git clone https://github.com/wsuzume/devel-entrypoint.git \
    && cd devel-entrypoint \
    && /bin/bash install.sh

ただし上記のスクリプトを走らせるために git, ca-certificates が必要であり、init.sh の実行のために sudo が必要である。これらのツールがインストールされていないのであれば、下記のスクリプトを手前に追加する。

RUN apt-get update --yes \
    && apt-get upgrade --yes \
    && apt-get install --yes --no-install-recommends \
        sudo git ca-certificates \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

たとえば Ubuntu にインストールする例は以下です。

https://github.com/wsuzume/devel-entrypoint/blob/main/example/ubuntu/Dockerfile

Usage

init.sh を経由してコマンドを実行するときは、コンテナ起動時のユーザーが root である必要があります。-u root オプションなどで root ユーザーになる準備をしてから Docker コンテナ起動時の環境変数に以下を指定してください。

環境変数 機能 デフォルト値
INIT_USER ユーザー名 morgan
INIT_UID ユーザーID 1000
INIT_GROUP グループ名 (存在しないGIDを指定した場合は INIT_USER と同じ)
INIT_GID グループID 100
GRANT_SUDO sudo権("yes"で追加) -

たとえばホスト側と同じユーザーID、グループIDで起動したい場合は、以下のコマンドを実行してみてください。

docker container run -it --rm -e INIT_UID=`id -u` -e INIT_GID=`id -g` your_image init.sh

何か実行したいコマンドがある場合は、init.sh のあとに追記してください。たとえば以下のようにコマンドを実行すると、次のようなアウトプットが返るはずです。

docker container run -it --rm -e INIT_UID=`id -u` -e INIT_GID=`id -g` your_image init.sh id
output
your_image init.sh id
Entered init.sh with args: id
Create specified group: 'morgan' (5000)
Create specified user: 'morgan' (5000)
Running as morgan: id
uid=5000(morgan) gid=5000(morgan) groups=5000(morgan),100(users)

おしまい

適当に使い回してね!

脚注
  1. 自分で書く部分のほうを git で管理している場合は debian-stacks-foundation の部分を submodule としてサブディレクトリ配置するか、または別のどこかにクローンしてから git 管理から外して自分のリポジトリにコピーする必要がある。また、ビルドするにしてもステージごとに名前をつけなければならず、考えるのが面倒臭い。なるべく手間を減らすために作ったのに本末転倒感が否めない。 ↩︎

  2. 開発用であれば普通は Debian 系でよいし、本番用だとしても Debian 系の slim イメージでよいのではないかと思っている。ディストロが異なると微妙な違いからハマったときに沼るので基本は Debian 系に統一しておき、Alpine などを選択するかどうかはイメージサイズを最適化する必要性に迫られたときに初めて検討すべきであると思う。 ↩︎

Discussion