Orange Pi 3 docker (debian buster systemd)

やはりdebian busterではsystemdは有効にならないようです。
セキュリティーの観点、運用からもdockerの1プロセス1コンテナ原則のようです。
但しローカル内での学習目的やちょっとした遊びにはsystemdが使えたほうが便利なこともあると思います。
docker hubにはdebian buster systemdのコンテナもあるのですが初心者(当サイト)には使い方がわかりませんでした。
systemdを有効にするためにここのくだりを参考にしました。
https://serverfault.com/questions/607769/running-systemd-inside-a-docker-container-arch-linux

debianの公式イメージには直接適用されないようなので一旦ssh serverコンテナを作成してみます。

openssh server

適当なディレクトリを作成してその中でDockerfileを実行します。

$ docker build -t buster-ssh ./

Dockerfile

FROM debian:latest
RUN apt-get update && apt-get -y upgrade && apt-get -y install openssh-server locales tzdata
RUN mkdir /var/run/sshd
RUN echo "root:xxxxxxxx" | chpasswd
RUN sed -i "33i PermitRootLogin yes" /etc/ssh/sshd_config
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
CMD ["/usr/sbin/sshd", "-D"]

イメージbuster-sshができるのでこれをsystemdでrunします。

$ docker container run -it --name openssh-server --cap-add SYS_ADMIN -v /sys/fs/cgroup:/sys/fs/cgroup:ro buster-ssh /bin/systemd


起動したままになるので別ターミナルからstop
docker container ls -aからopenssh-serverを確認して再度start
sshで接続

& docker container stop openssh-server
$ docker container start openssh-server
$ ssh root@172.17.0.2


systemdが有効になっていますね。
ロケールとタイムゾーンは設定されているはずです。
ほかに追加したい項目があればここで設定してcommitしておきます。
buster/openssh-server

& docker container stop openssh-server
$ docker container commit openssh-server buster/openssh-server

xorg

作成したbuster/openssh-serverを基にX関連を追加します。
vncはtightvncserver WMはdwmをインストール

$ docker build -t buster-xorg ./

Dockerfile

$ FROM buster/openssh-server:latest
RUN apt-get update && apt-get -y upgrade && \
apt-get -y install xserver-xorg xterm tightvncserver autocutsel dwm vim

CMD ["/bin/systemd"]

上記と同じくsystemdでrun

$ docker container run -it --name buster-X --cap-add SYS_ADMIN -v /sys/fs/cgroup:/sys/fs/cgroup:ro buster-xorg /bin/systemd

コンテナをリスタートdocker container execかsshから環境を設定します。

$ docker container stop buster-X
$ docker container start buster-X
$ ssh root@172.17.0.2
# vncpasswd
# vncserver -geometry 600x450 :2

当サイトはvnc接続したOrangePi3に構築しているのでポート番号は2以降を指定しています。

$ vncviewer 172.17.0.2:2


日本語フォントをインストール、fontconfigを設定.Xresourcesなど追加
/root/.vnc/xstartupを設定して最低限の起動画面を作成
ウインドウマネージャーは変更してもいいし後からいつでも変えられます。
設定が済んだらコミットします。

$ docker container commit buster-X buster/xorg

コミットしたbuster/xorgからnetworkを指定して運用するコンテナを作成

$ docker container run -it --net=orangepi3-network --ip=172.18.0.23 --name buster_dwm --cap-add SYS_ADMIN -v /sys/fs/cgroup:/sys/fs/cgroup:ro buster/xorg /bin/systemd

作成したコンテナが正常に起動できたらbuster/openssh-server buster/xorg以外の不要なコンテナ、イメージを削除

vncboot

vncbootを有効にしないとコンテナをスタート、ログインしてvncserverを起動しなければvncviewerから接続できません。docker cpでコピーするのが簡単と思います。
パーミッションはroot 実行権限を付けておきます。

$ docker cp vncboot /etc/init.d

ログインしてenable

# systemctl enable vncboot

vncbootにはポート番号が記載されています。2以降の任意の番号に変更するのがいいでしょう。vncviewerからその番号を指定します。

vncserverはtightvncserverをインストールしています。
tigervncserverはbuster(ARM64?)では起動しません。これはdebian系のbugのようです。
https://github.com/TigerVNC/tigervnc/issues/800
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=923962
現package versionも変更が無いことからまだ解決には至ってないようです。

buster_dwm


dwmをコンパイルしたdwm6.2に変更しています。
dwmは実行ファイル(59Kb)も小さく依存するファイルも必要ないことから/usr/local/binに放り込んでおくだけで問題なく使えます。dmenuは追加でインストールできます。
Xの確認また操作にある程度慣れていればそのまま十分実用になります。
但し今回はホストのOrangePi3でdwmを使っているためキーバインドは全てホスト側に摂られています。実質xstartup,xtermからのみコントロールすることになります。

buster_openbox

$ docker container run -it --net=orangepi3-network --ip=172.18.0.24 --name buster_openbox --cap-add SYS_ADMIN -v /sys/fs/cgroup:/sys/fs/cgroup:ro buster/xorg /bin/systemd


起動時メモリ消費量はdwm 30MB openbox+lxpanelで45MB位になるようです。
起動するアプリケーショやデーモンがあるとどんどん増えていきます。
pcmanfmからはドライブが見えなくなっています。


buster_dwmにsurfをインストール、xstartupから起動してmoode player,radikoを表示させてみました。
動作としては問題ないのですがraspbianに比べてメモリ消費量が大きくなるようです。
Xコンテナも用途によって使い分けたり新しくしたほうがいいようです。

buster_openssh

今回作成したコンテナはssh接続も可能ですがrunするとXも起動するためメモリ消費が多くなります。cliでssh接続するためbuster_opensshからコンテナを作成します。

$ docker container run -it --net=orangepi3-network --ip=172.18.0.22 --name buster_ssh --cap-add SYS_ADMIN -v /sys/fs/cgroup:/sys/fs/cgroup:ro buster/openssh /bin/systemd


各コンテナの起動タイミングはメモリの状況やOSなどの条件で接続はそれぞれ違ってきます。一つのボタンでコンテナをrunそして接続することは無理があります。
alpineだけはsleepに3秒入れておけば繋がるのですがほかのOSは初回起動時と以降の差が大きいのでsleepに1を入れて1回失敗させ(runだけしといて)再度間合いをおいて接続するようにしています。
この辺はもう少しスマートな方法がないか考えてみたいと思います。

docker kill(stop)ボタン
起動中の全コンテナを安全にストップします。

subprocess.run("docker container stop $(docker ps -q)", shell=True)

docker restart ボタン
作業中時折agettyを握って一つのcpuが100%に張り付いてしまうことがあります。
dockerをrestartしても直らないのですがagettyをkillするついでにdockerもrestartしています。

subprocess.run("sudo killall agetty", shell=True)
subprocess.run("sudo systemctl restart docker", shell=True)

コンテナの停止時間を充分見ていれば大丈夫かな(?)