Docker コンテナで snap コマンドを使う方法

困ったこと

Linux の新しめのパッケージマネージャとして Snap がある。 apt などのパッケージマネージャと違って、Snap によってインストールされるパッケージには必要な依存関係ごと含まているのが特徴である。いわば self-contained なパッケージマネージャである。

Snap のパッケージをインストールするとき snap install コマンドを叩くのだが、これを Docker コンテナ内で実行するとエラーが出ることが知られている。たとえば以下のページにその報告がある。

stackoverflow.com

この質問の回答にあるとおり、基本的には Docker コンテナ内で snap コマンドを叩くことはできない(厳密には snapd デーモンを起動できない)ようだ。困った。

解決方法

色々調べてみた結果、以下の GitHub リポジトリの資材を使うと snap install コマンドを叩ける Docker コンテナ(Ubuntu 18.04)を起動できた。そのやり方をここにメモる。ホストマシンは Ubuntu 20.04.3 LTS。

github.com

まずはこの Git リポジトリをクローンする。

$ git clone https://github.com/ogra1/snapd-docker.git
$ cd snapd-docker/

そしてスクリプトを実行する。

$ ./build.sh 

すると Docker コンテナが起動する。以下のコマンドで確認できる。

$ docker container ls
### ->
CONTAINER ID   IMAGE     COMMAND        CREATED          STATUS          PORTS     NAMES
1675068cffef   snapd     "/sbin/init"   57 seconds ago   Up 54 seconds             snappy

snappy という名前のコンテナが起動している。このコンテナは Ubuntu をベースイメージとしているので bash コマンドでコンテナに入ってみる。

$ docker exec -it snappy bash

コンテナ内のプロセスを確認してみる。

root@1675068cffef:/# ps aux
### ->
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.2  0.0 224772  8668 ?        Ss   15:01   0:00 /sbin/init
...
root         410  0.7  0.2 1550336 34212 ?       Ssl  15:02   0:00 /usr/lib/snapd/snapd
...

色々なプロセスが動いているが、snapd が起動していることが確認できる。

試しに snap install で pdftk という PDF の編集ツールのパッケージをインストールしてみる。

root@1675068cffef:/# snap install pdftk
pdftk 2.02-4 from Scott Moser (smoser) installed
root@1675068cffef:/# which pdftk
/snap/bin/pdftk

無事 pdftk を Docker コンテナ内にインストールできた。めでたし。

メモ

  • Docker コンテナのベースイメージを Ubuntu 以外にしたかったら build.sh 内で書き出している Dockerfile の内容を書き換えればよさそうだが、そんなに簡単にできるか分からない。
  • GitHub の README.md にあるとおり snapd-docker はセキュリティ面の制約を弱めている。セキュアな処理を実装するためには使わない方がよさそう。