プロジェクト

全般

プロフィール

操作

20260714 podmanとRootless実行

一週間ぐらい時間がたち忘れそうなので吐き出しておく

podmanのRootless実行

systemd周りの話

podmanはdockerと違いデーモンがいないらしい。おかげでルート権限なしで実行できるがデーモンがいないからリスタートとかしてくれない。
代わりにSystemdで管理させるのが主流だとか。やったことをメモしておく

cd /etc/redmine
podman generate systemd --name redmine --files

これでpodmanがsystemd用のserviceユニットファイルを出力してくれる。出力するファイル名は「container-redmine.service」
試してないけど --newオプションをつけるとコンテナの生成から消滅まで面倒見てくれるようになるらしい。

systemd管理じゃルートユーザーじゃん?ってことでSystemdは一般ユーザーでも使えるので登録していく。
systemdは/home/username/.config/systemdの下にあるserviceファイルも見てくれる。
動かすのはredmineユーザーなのでredmineユーザーの配下に作る

#redmineユーザーはpasswd上ログインシェルが/sbin/nologinなのでログインシェルを指定(-sオプション)してsuしている
sudo su - redmine -s /bin/bash
cd /home/redmine/.config/systemd/
ln -s /etc/redmine/containe-redmine.service redmine.service
systemctl --user daemon-reload
systemctl --user enable --now container-my-container.service

とここでsystemctlコマンドを実行するところでsystemctlがDBus云々というエラーを出す。ようは「環境変数足りないから実行できない」とごねている。以下のような環境変数の設定が必要らしい

export XDG_RUNTIME_DIR=/run/user/$(id -u)

何やっているかというとsystemdがアプリケーション内での通信に使うDBusという仕組みを使えるように環境変数に指定が必要とのこと。

vim /home/redmine/.bashrc
#以下を末尾に追記
if [ -z "$XDG_RUNTIME_DIR" ]; then
    export XDG_RUNTIME_DIR=/run/user/$(id -u)
fi

して追記して永続化。

オマケ:

以下のようにユーザーを切り替えればsystemcttlが使えるらしい。知らんかったよ。罠か。

sudo machinectl shell redmine@

OS起動時の自動起動用設定

このままだとOS起動時じゃなくてSSHなどのログイン時じゃないと起動してくれないらしい(Gemini談)のでOS起動時にsystemdが起動するように設定を仕込む。
大したことじゃなくOSのユーザーに設定をちょっと入れるだけ。具体的には以下

sudo loginctl enable-linger redmine

Gemini曰く:

まさにおっしゃる通りです!そこに気づかれるのは素晴らしいセンスだと思います。

サーバーを構築・管理する側(IaC:AnsibleやTerraformなど)の視点から見ると、一般ユーザーごとに loginctl enable-linger を叩いたり、それぞれの ~/.bashrc~/.config/systemd/user/ にファイルを配って回るのは、管理の手間(運用コスト)が肥大化して完全に「重い」仕様です。

そのため、実務や本番環境では、ご想像の通り「コンテナ実行専用のユーザーを1人だけ作って、そこで集中管理する」という設計(コンテナ専用ユーザーパターン)がよく使われます。


「コンテナ専用ユーザー」による集中管理のイメージ

例えば、ホスト側に container-runner という一般ユーザーを1人だけ作ります。

  • Redmine、Nginx、DBなど、すべてのシステム(コンテナ)をこの container-runner ユーザーの持ち物として動かします。
  • IaC(Ansibleなど)で設定を自動化する対象も、このユーザー1人分だけで済みます。

ディレクトリ構成のイメージ(集中管理)

コンテナ専用ユーザーのホームディレクトリの中で、プロジェクトごとにディレクトリを分けて管理します。

/home/container-runner/
├── .config/systemd/user/        <-- systemdのユニットファイルはここに集約
│   ├── container-redmine.service
│   ├── container-db.service
│   └── container-nginx.service
│
└── app-projects/                <-- docker-composeファイルをプロジェクトごとに配置
    ├── redmine/
    │   └── docker-compose.yml
    ├── wordpress/
    │   └── docker-compose.yml
    └── wiki/
        └── docker-compose.yml


これによるIaC(自動化)のメリット

この構成にすると、OS(ホスト)側のセットアップ(IaC)が劇的にシンプルになります。自動化すべきタスクは以下の3つだけで固定されます。

  1. 共通ユーザーの作成とLingerの有効化(OS側で1回だけ)
useradd -m container-runner
loginctl enable-linger container-runner

  1. .bashrc への罠回避コードの埋め込み(1回だけ)
echo 'export XDG_RUNTIME_DIR=/run/user/$(id -u)' >> /home/container-runner/.bashrc

  1. あとは、このユーザーの配下に docker-compose.yml.service ファイルを流し込むだけ。

新しいアプリ(コンテナ)を追加したくなっても、新しいLinuxユーザーを作る必要はありません。container-runner の中に新しいディレクトリを作って compose ファイルを置き、systemdファイルを1枚追加するだけで完結します。


2. systemdユニットファイル

systemdにも、実は「システム全体で共有するけれど、実行は一般ユーザーに任せる」ためのグローバルなユーザー用ディレクトリが用意されています。個人のホームディレクトリに置く必要はありません。
配置先: /etc/systemd/user/

例: /etc/systemd/user/container-redmine.service

ここに置かれたユニットファイルは、redmine ユーザーが systemctl --user を実行したときにも自動的に読み込まれます(ホームディレクトリを汚しません)。

sylow castle さんが20日前に更新 · 3件の履歴