先日のAWS re:Invent 2022で発表されたFinchを遅ればせながら使ってみたのでその感想文を書いておく。
Finchとは?
Finchはデスクトップ(ローカル)環境でコンテナをビルドして実行するための環境を提供するOSSであり、Docker Desktopの代わりとなり得る言われている。
Finchがデスクトップコンテナ環境を実現するために活用しているツールセットについて下記のような説明がある。
Finch provides a simple client which is integrated with nerdctl. For the core build/run/push/pull commands, Finch depends upon nerdctl to handle the heavy lifting. It works with containerd for container management, and with BuildKit to handle Open Container Initiative (OCI) image builds. These components are all pulled together and run within a virtual machine managed by Lima.
Source: https://github.com/runfinch/finch
- コアのbuild/run/push/pullコマンドはnerdctlを活用
- コンテナーランタイムにはcontainerdを活用
- Open Container Initiative (OCI) イメージビルドにBuildKitを活用
- 仮想マシン管理にLimaを活用
デスクトップコンテナ環境を実現するために上記ツールセット達がどのように連携しているのかについては記事「Container Tools, Tips, and Tricks - Issue #3」にとてもわかりやすい絵があるので紹介しておく。
Source: Container Tools, Tips, and Tricks - Issue #3
なお、いまのところFinchはmacOSのみサポートしており、WindowsやLinuxでは使えない。
また、当方FinchやDocker Desktop以外は使ったことがないが、他にもデスクトップコンテナ環境を実現するツールはいくつかあるのでここに紹介しておく。
などなど、ご参考までに。
Finchで試してみたこと
利用環境
- MacBook Pro (OS: Monterey)
- Processor 2.5 GHz Dual-Core Intel Core i7
- Memory 16 GB
finchのインストール
まずはbrewコマンドでfinchをインストールする。
brew install --cask finch
仮想マシンの起動
Finchの仮想マシン(以下、VM)を利用するためfinch vm init
コマンドで初期設定する必要がある。これは一回だけやればよい。これでVMが起動される。
finch vm init
なお、2回目以降は、VMの起動、停止をそれぞれ下記のコマンドで行う。
finch vm start
finch vm stop
Docker Hubのコンテナイメージをpullして実行してみる
それではコンテナの実行準備が整ったのでDocker Hubのコンテナイメージを下記のfinch run
コマンドで実行してみる。
サンプルのコンテナイメージとしてdocker-supermarioを利用する。基本的にdockerコマンドでやっていたのと同じオプションで実行可能であることが分かるかと思う。
finch run -d -p 8600:8080 docker.io/pengbai/docker-supermario:latest
コンテナ起動後にfinch ps
コマンドで起動しているコンテナ一覧を確認する。
finch ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
05a1aa06b301 docker.io/pengbai/docker-supermario:latest "catalina.sh run" 19 seconds ago Up 0.0.0.0:8600->8080/tcp docker-supermario-05a1a
ローカルポート8600でアクセスできることがわかるので、ブラウザでlocalhost:8600を開いてみる。
無事に期待通りの結果が表示された。
Dockerfileからイメージをビルドしてみる
次に、finch build
コマンドでイメージをビルドしてみる。
サンプルとして当方が作ったawspingツールのコンテナイメージをビルドしてみる。
まずはコードをcloneする。
git clone git@github.com:yokawasa/awsping.git
cd awsping
次のようにfinch build
コマンドでDockerfileからイメージをビルドする。
finch build -t awsping .
最後にビルドしたイメージを次のようにfinch run
コマンドで実行してみる。
finch run awsping
以下がコンテナ実行の出力結果。
finch run awsping
1. [ap-northeast-1] 80.342267ms
2. [ap-northeast-2] 120.614401ms
3. [ap-southeast-1] 210.190698ms
4. [us-west-2] 279.588928ms
5. [ap-southeast-2] 279.89593ms
6. [us-west-1] 280.23793ms
7. [ap-south-1] 328.27209ms
8. [ca-central-1] 401.566333ms
9. [us-east-2] 407.018351ms
10. [eu-west-2] 513.608706ms
11. [eu-west-1] 537.589785ms
12. [eu-west-3] 539.03179ms
13. [eu-central-1] 554.777842ms
14. [eu-north-1] 559.914859ms
ここでも、dockerコマンドでやっていたことを同じオプションでfinchコマンドで利用できた。
Docker Composeを使ってみる
先述のとおりFinchではbuild/run/push/pullなどのコアコマンドの実行にnerdctlを活用している。そして、このnerdctlはDocker Composeにも対応している。したがってfinchコマンドもDocker Composeにも対応しており、finch compose
コマンドで利用できる。
サンプルとしてawesome-composeリポジトリで管理されているnginx-golang-mysqlを利用する。
まずはコードをcloneする。
git clone git@github.com:docker/awesome-compose.git
cd awesome-compose/nginx-golang-mysql
同ディレクトリにあるDocker composeファイル(compose.yaml
)の内容は下記の通り。
services:
backend:
build:
context: backend
target: builder
secrets:
- db-password
depends_on:
db:
condition: service_healthy
db:
# We use a mariadb image which supports both amd64 & arm64 architecture
image: mariadb:10-focal
# If you really want to use MySQL, uncomment the following line
#image: mysql:8
command: '--default-authentication-plugin=mysql_native_password'
restart: always
healthcheck:
test: ['CMD-SHELL', 'mysqladmin ping -h 127.0.0.1 --password="$$(cat /run/secrets/db-password)" --silent']
interval: 3s
retries: 5
start_period: 30s
secrets:
- db-password
volumes:
- db-data:/var/lib/mysql
environment:
- MYSQL_DATABASE=example
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db-password
expose:
- 3306
proxy:
image: nginx
volumes:
- type: bind
source: ./proxy/nginx.conf
target: /etc/nginx/conf.d/default.conf
read_only: true
ports:
- 80:80
depends_on:
- backend
volumes:
db-data:
secrets:
db-password:
file: db/password.txt
それではfinch compose up
コマンドでDocker composeファイルを元にコンテナを作成・開始してみる。docker-composeと同じように-d
オプションでコンテナをバックグラウンドモードで開始できる。
finch compose up -d
finch compose ps
コマンドで立ち上げたコンテナ一覧をみる。
finch compose ps
NAME COMMAND SERVICE STATUS PORTS
nginx-golang-mysql_db_1 "docker-entrypoint.s…" db running
nginx-golang-mysql_backend_1 "/code/bin/backend" backend running
nginx-golang-mysql_proxy_1 "/docker-entrypoint.…" proxy running 0.0.0.0:80->80/tcp
ローカルポート80でアクセスできることがわかるので、curlコマンドでlocalhost:80を叩いてみる。
curl localhost:80
["Blog post #0","Blog post #1","Blog post #2","Blog post #3","Blog post #4"]
期待通りの結果が出力された。
さらに、docker-composeコマンドと同じようにfinch compose logs
コマンドでログをtailも可能。
finch compose logs -f
proxy_1 |/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
proxy_1 |/docker-entrypoint.sh: Configuration complete; ready for start up
backend_1 |10.4.4.3 - - [24/Dec/2022:10:35:37 +0000] "GET / HTTP/1.1" 200 77
proxy_1 |10.4.4.1 - - [24/Dec/2022:10:35:37 +0000] "GET / HTTP/1.1" 200 77 "-" "curl/7.79.1" "-"
雑ではあるがfinch compose
コマンドの動作を確認できたので最後に、下記コマンドでコンテナを停止・削除する。
finch compose down -v
INFO[0000] Removing container nginx-golang-mysql_proxy_1
INFO[0000] Removing container nginx-golang-mysql_backend_1
INFO[0000] Removing container nginx-golang-mysql_db_1
INFO[0001] Removing network nginx-golang-mysql_default
INFO[0001] Removing volume nginx-golang-mysql_db-data
注意点: Dockerfile構文の拡張について
今回、最初にawesome-composeリポジトリにあるnginx-golang-mysqlをcloneしてfinch compose up -d
を実行したら下記のようなエラーが出力された。
Dockerfile:1
--------------------
1 | >>> # syntax=docker/dockerfile:1.4
2 | FROM --platform=$BUILDPLATFORM golang:1.18-alpine AS builder
3 |
--------------------
error: failed to solve: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/tmp/buildkit-metadata3881195025" to rootfs at "/run/config/buildkit/metadata": mount /tmp/buildkit-metadata3881195025:/run/config/buildkit/metadata (via /proc/self/fd/6), flags: 0x1021: operation not permitted: unknown
FATA[0002] unrecognized image format
FATA[0003] error while building image nginx-golang-mysql_backend: exit status 1
FATA[0003] exit status 1
調べてみると、どうやらDockerfileの下記のシンタックスが悪さをしていることが分かったので、この一行を削除して再度finch compose up -d
を実行したら問題なくコンテナの作成・開始が完了した。
# syntax=docker/dockerfile:1.4
記事「Dockerfile v1.4.0 以降のヒアドキュメント機能を使うときにハマったこと」によると、この# syntax=docker/dockerfile:1.4
はDockerfileの拡張構文であり、BuildKitを有効にしたときにこの構文のあるDockerfileをビルドすると、docker/dockerfile:1.4
イメージがBuildKitフロントエンドとして使用され、Dockerfileはv1.4の文法で読み込まれるようである。
以上のことからfinch compose
ではこの構文はサポートされていないようなのでご注意ください。
CPUアーキテクチャを指定する
Finchは—platform
オプションでCPUアーキテクチャを指摘できる。たとえばApple Silicom M1システムにおいて、x86-64 CPUアーキテクチャ(ard64
)でコンテナを実行する場合は次のように次のように—platform
オプションでamd64
を指定する。
finch run --rm --platform=amd64 public.ecr.aws/amazonlinux/amazonlinux uname -ms
Finchの設定
Finchの設定ファイルは${HOME}/.finch/finch.yaml
となっており、最初の起動でこのファイルが作成される。
cat ~/.finch/finch.yaml
cpus: 2
memory: 4GiB
2022/12時点でcpuとmemoryだけが設定可能となっている。設定ファイルについて詳細はこちらを参照ください。
感想
今回簡単ではあるがfinchコマンドを使ってみて、ほぼdockerやdocker-composeコマンドとして利用できることが分かった。また、細かくは計測していないが体感的にDocker Desktopと比べ軽く占有メモリもかなり少なくなった印象がある。
一方、Finchリポジトリのissue一覧をみるかぎり、Docker Desktopと比べて利用できないコマンドがあったり、安定性の面などでいろいろ問題があるように見える。まだmacOSしかサポートされていないということもある。当方の利用ユースケース的にはFinchは十分Docker Desktopの代替になり得るのだが、一般的にこれをDocker Desktop代替というには時期尚早であるとは思う。
今後の進化に期待しよう。