0. はじめに
- きっかけ:
Debian でいろいろと運用している。shiny-server は Debian のパッケージと、それとは別に入れたパッケージが混在して状態で運用していた。Debian 12 にしたときに、shiny-server が動かなくなった。このストレスから開放されるために、コンテナを利用する。 - この文章の目的:
- コンテナを扱ったことがなかった私の備忘録として
- docker でなく podman を使った場合の例として
- shiny-server を立ち上げる手順として
1. インストール
1.1 podman
apt update
apt upgrade
apt install podman
1.2 名前空間の設定
ファイルを編集して、次のような記述を追加する。この記述は、uid,gid それぞれ、500000から、65536個分という意味になる。すでにエントリーがある場合には、重ならないように設定する必要があるので注意する。先頭に# を入れればコメントになるので説明を入れておくと良い。username のところは、自分のログイン名とする。
# for podman
username:500000:65536
# for podman
username:500000:65536
設定を反映させるためにシステムを再起動する。(再起動させないで反映させる方法がありそうだけど。)
2. 基本操作
hello-world を例に、基本的な操作についてまとめる。
2.1 イメージの取得
podman pull docker.io/hello-world
2.2 イメージからコンテナを作成して実行
podman run hello-world
run では、pull(ダウンロード)したイメージから新しいコンテナを作成して実行する。(巷のdockerの解説に表示されているようなことが表示される。)
2.3 コンテナ一覧
- ps
podman ps
この段階では、実行中のものはない。hello-world は、文字列を表示して終了している。そこで何も表示されない。 - ps -a
podman ps -a
実行中でないものも含めてコンテナが表示される。そこで、ここではhello-world のコンテナが表示される。
2.4 停止と再稼働
- 停止
podman stop [コンテナIDか名前]
- 再稼働
podman start [コンテナIDか名前]
2.5 コンテナの削除
podman rm [コンテナIDか名前]
で、削除。イメージは削除されない。
2.6 イメージの操作
- イメージの一覧
podman images
- イメージの削除(コンテナを削除しないと削除できない)
podman rmi [イメージIDまたはイメージ名:タグ]
2.7 その他の重要な情報
- コンテナをデタッチモード(バックグラウンド)で実行
podman run -d ....
- コンテナのポートに外部からアクセス(ホストマシンのポートを転送)
podman run -p [ホストのポート]:[コンテナのポート] ....
- コンテナからホストのファイルにアクセス(マウント)
podman run -v [ホストのパス]:[コンテナのパス] ....
※ -v は複数指定できる。 - コンテナ内のbash を立ち上げる。
podman exec -it [コンテナ名またはID] bash
2.8 システム起動時に自動起動
systemd を利用する。具体例を以下のshiny-server の項で示す。
3. shiny-sever の導入
3.1 イメージそのままでの実行
これまでの情報だけで運用できるかな?
podman pull docker.io/rocker/shiny
podman -d -p 3838:3838 -v /srv/shiny-server:/srv/shiny-server rocker/shiny
これで、http://(podmanを動かしているマシン):3838/ にアクセスすれば、shiny-server が動いていることが確認できる。
良かった!すばらしい!ここまでは…。
3.2 カスタムイメージ
ところが、私は、R にいくつかのパッケージを入れて運用している。それを入れなければ動かない。起動する度に、bash で入ってパッケージを入れるのは困難だ。そこで、イメージをカスタマイズする。
適当なディレクトリで、次の Dockerfile を作成する。
# ベースイメージとしてrocker/shinyを使用
FROM rocker/shiny:latest
# 必要なシステム依存関係をインストール
RUN apt-get update && apt-get install -y \
libnetcdf-dev \
netcdf-bin
# Rパッケージをインストール
RUN R -e "install.packages('ncdf4', dependencies=TRUE)"
その上で、次のコマンドを実行する。
podman build -t custom-shiny-app .
これで、新しいイメージ custum-shiny-app
ができたので、これを run すれば良い。
注意:
- ファイル中の RUN 以降はコマンドになっている。rocker/shiny のベースのシステムは Ubuntu なので、apt を使っている。
- カスタムイメージを更に変更するには、
FROM
の部分をFROM localhost/custom-shiny-app
と、先程作ったイメージを指定すればよい。
3.3 自動起動
※ 以下に systemd を使う方法を書いたが、うまくいかない。→ とりあえず、crontab で起動時に実行するようにする。
→ crontab でもうまく動かないようだ。保留。
設定ファイルを作る
[Unit]
Description=My Shiny Container
[Service]
Restart=always
ExecStart=/usr/bin/podman start [コンテナIDか名前]
ExecStop=/usr/bin/podman stop [コンテナIDか名前]
[Install]
WantedBy=multi-user.target
この設定ファイルでは、一度、shiny-server のコンテナを作成して実行していることを前提としている。テストしてから自動起動に移行すると思うので、それで問題ないはず。
2. 登録
sudo systemctl daemon-reload
sudo systemctl enable myshiny.service
4. コメント
-
Debian のパッケージ vs コンテナ
コンテナは、動くことが(かなり)確実なので手軽に使える。しかし、手を加えようとすると敷居が高くなる。多くのパッケージ依存性があるアプリを、安定的に運用するのにはコンテナが良さそうだ。
-
自動起動で実行するのは root
自動起動にする場合には、スーパーユーザー(root)になってしまう。podman にした意味があまりないような気もする。