🦜

FinchがGAになったのを機に使ってみる

2023/11/26に公開

1. はじめに

Docker Desktop 有料化の際に代替方法を探していたのですが、結局そのときは色々あって試さずに終わっていました。
先日 Finch のバージョンが1.0.0に上がっているのに気付いて試してみようと思いました。

1.1. 今回の環境

M2 Mac v14.1.1
$uname -ms
Darwin arm64

$sw_vers
ProductName:  macOS
ProductVersion:  14.1.1
BuildVersion:  23B81

2. Finch とは

Finch とは AWS が開発しているコンテナ開発用のオープンソースの CLI ツールです。
いくつかのオープンソースを組み合わせてコンテナ開発を支援することを目的にしているそうです。
現在は Mac のみで使えますが、Windows、Linuxでも使えるようにする計画のようです。

2.1. Finch構成

finch_architecture

  • Lima
    • Linux 仮想マシン
    • ざっくり言うと Windows での WSL2 のようなもの
  • nerdctl
    • Docker 互換の CLI
  • containerd
    • コンテナランタイム
    • デーモンとして動作し、イメージの転送と保存、コンテナの実行と監視、低レベルのストレージ・ネットワーク接続など、コンテナのライフサイクルを管理するもの
  • BuildKit
    • コンテナイメージのビルドツール

3. Finch インストール

  1. homebrew でインストール
brew install finch
出力
==> Downloading https://github.com/runfinch/finch/releases/download/v1.0.0/Finch-v1.0.0-aarch64.pkg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-2e65be/562778457/057c0f9d-8118-43cb-8b5f-443920fd
##################################################################################################################################### 100.0%
==> Installing Cask finch
==> Running installer for finch with sudo; the password may be necessary.
Password:
installer: Package name is Finch
installer: Installing at base path /
installer: The install was successful.
🍺  finch was successfully installed!
確認

最初にコマンド実行した時、~/.finch/finch.yaml が作成される

$ finch --version
INFO[0000] Using default values due to missing config file at "/Users/{username}/.finch/finch.yaml"
INFO[0000] "/Users/{username}/.finch" directory doesn't exist, attempting to create it
finch version v1.0.0

# Finchの設定ファイルが作成されている
$ cat ~/.finch/finch.yaml
cpus: 2
memory: 4GiB
vmType: qemu
rosetta: false

# 仮想マシンのステータスはまだ作成されていないので Nonexistent
$ finch vm status
Nonexistent

※インストーラー(.pkg)でインストールする方法もあります。

  1. 仮想マシンを初期化
finch vm init
出力
INFO[0000] binaries directory doesn't exist
INFO[0000] Requesting root access to finish network dependency configuration
Password:
INFO[0010] sudoers file not found: open /etc/sudoers.d/finch-lima: no such file or directory
INFO[0013] Initializing and starting Finch virtual machine...
INFO[0058] Finch virtual machine started successfully
確認
$ finch vm status
Running

3.1. (おまけ) Docker Desktop のアンインストール

  • DockerDesktopメニュー > Troubleshoot > Uninstall
  • アプリケーションディレクトリからDocker.appを削除

Docker Desktop のアンインストール — Docker-docs-ja 19.03 ドキュメント

4. コマンド実行確認

4.1. hello finch

finch run public.ecr.aws/finch/hello-finch:latest

トリさんのアスキーアートが表示されます。

出力
public.ecr.aws/finch/hello-finch:latest:                                          resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:a71e474da9ffd6ec3f8236dbf4ef807dd54531d6f05047edaeefa758f1b1bb7e:    done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:705cac764e12bd6c5b0c35ee1c9208c6c5998b442587964b1e71c6f5ed3bbe46: done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:6cc2bf972f32c6d16519d8916a3dbb3cdb6da97cc1b49565bbeeae9e2591cc60:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:ec080f7c92e9eb0227d60951f7c779648989116d97a5926f3e8684d4e46df196:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 4.5 s                                                                    total:  2.5 Ki (569.0 B/s)                                

                            @@@@@@@@@@@@@@@@@@@
                        @@@@@@@@@@@@    @@@@@@@@@@@
                      @@@@@@@                  @@@@@@@
                    @@@@@@                        @@@@@@
                  @@@@@@                            @@@@@
                 @@@@@                      @@@#     @@@@@@@@@
                @@@@@                     @@   @@@       @@@@@@@@@@
                @@@@%                     @     @@            @@@@@@@@@@@
                @@@@                                               @@@@@@@@
                @@@@                                         @@@@@@@@@@@&
                @@@@@                                  &@@@@@@@@@@@
                 @@@@@                               @@@@@@@@
                  @@@@@                            @@@@@(
                   @@@@@@                        @@@@@@
                     @@@@@@@                  @@@@@@@
                        @@@@@@@@@@@@@@@@@@@@@@@@@@
                            @@@@@@@@@@@@@@@@@@


Hello from Finch!

Visit us @ github.com/runfinch
確認
$ finch image list

REPOSITORY                          TAG       IMAGE ID        CREATED           PLATFORM       SIZE       BLOB SIZE
public.ecr.aws/finch/hello-finch    latest    a71e474da9ff    14 seconds ago    linux/arm64    1.8 MiB    1007.7 KiB

4.2. ポートを公開するコンテナの実行

nginx のコンテナを実行して 80 番ポートを公開

finch run --rm --publish 80:80 public.ecr.aws/nginx/nginx
出力
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/11/25 06:31:15 [notice] 1#1: using the "epoll" event method
2023/11/25 06:31:15 [notice] 1#1: nginx/1.25.3
2023/11/25 06:31:15 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2023/11/25 06:31:15 [notice] 1#1: OS: Linux 6.5.8-200.fc38.aarch64
2023/11/25 06:31:15 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1024:1024
2023/11/25 06:31:15 [notice] 1#1: start worker processes
2023/11/25 06:31:15 [notice] 1#1: start worker process 29
2023/11/25 06:31:15 [notice] 1#1: start worker process 30

http://localhost にブラウザでアクセスすると nginx の Welcome ページが表示される。
nginx

4.3. コンテナに対話型セッション開始

Amazon Linux コンテナで bash 実行

finch run -it --rm public.ecr.aws/docker/library/amazonlinux:latest

bash-5.2#
確認
bash-5.2# ls
bin  boot  dev etc  home  lib lib64  local  media  mnt  opt  proc  root  run sbin  srv  sys tmp  usr  var

bash-5.2# pwd
/

4.4. コンテナのビルド

Dockerチュートリアル用リポジトリを利用します。

# リポジトリをクローン
$ git clone https://github.com/docker/getting-started.git
$ cd getting-started

# Dockerfile からビルド
$ finch build --tag getting-started .

# 作成されたイメージを確認
$ finch image list

REPOSITORY         TAG       IMAGE ID        CREATED              PLATFORM          SIZE         BLOB SIZE
getting-started    latest    9ab669a01660    55 seconds ago       linux/arm64       57.6 MiB     23.1 MiB
# 実行
$ finch run -dp 80:80 getting-started
269cc3020e20ea6aee021aa3d385f0ac90f622f81e9ced3e8748f590e16e484e

http://localhost にブラウザでアクセスするとチュートリアルドキュメントページが表示されます。

docker_getting-started

docker-compose に相当する finch compose でもコンテナを実行可能でした。

$ finch ps --all

CONTAINER ID    IMAGE                                       COMMAND                   CREATED          STATUS    PORTS                 NAMES
269cc3020e20    docker.io/library/getting-started:latest    "/docker-entrypoint.…"    2 minutes ago    Up        0.0.0.0:80->80/tcp    getting-started-269cc

# いったんコンテナを削除
$ finch stop 269cc3020e20
$ finch rm 269cc3020e20
finch compose up
出力
INFO[0000] Creating network getting-started_default
INFO[0000] Building image getting-started-docs
[+] Building 4.4s (8/9)
[+] Building 4.5s (9/9) FINISHED
 => [internal] load build definition from Dockerfile                                                                                   0.0s
 => => transferring dockerfile: 1.22kB                                                                                                 0.0s
 => [internal] load metadata for docker.io/library/python:alpine                                                                       2.9s
 => [internal] load .dockerignore                                                                                                      0.0s
 => => transferring context: 67B                                                                                                       0.0s
 => [base 1/4] FROM docker.io/library/python:alpine@sha256:a5d1738d6abbdff3e81c10b7f86923ebcb340ca536e21e8c5ee7d938d263dba1            0.0s
 => => resolve docker.io/library/python:alpine@sha256:a5d1738d6abbdff3e81c10b7f86923ebcb340ca536e21e8c5ee7d938d263dba1                 0.0s
 => [internal] load build context                                                                                                      0.0s
 => => transferring context: 37B                                                                                                       0.0s
 => CACHED [base 2/4] WORKDIR /app                                                                                                     0.0s
 => CACHED [base 3/4] COPY requirements.txt .                                                                                          0.0s
 => CACHED [base 4/4] RUN pip install -r requirements.txt                                                                              0.0s
 => exporting to docker image format                                                                                                   1.5s
 => => exporting layers                                                                                                                1.1s
 => => exporting manifest sha256:ad8e13f3cbb3430387421ad78d865542064ca94234b84ad903a8999954d1359f                                      0.0s
 => => exporting config sha256:ddc446958f772bcd3b520a15e9ade0cace95de3eca7aff727c90ac72781cfdfb                                        0.0s
 => => sending tarball                                                                                                                 0.4s
Loaded image: docker.io/library/getting-started-docs:latest
INFO[0004] Creating container getting-started-docs-1
INFO[0005] Attaching to logs
docs-1 |INFO     -  Building documentation...
docs-1 |WARNING  -  Config value: 'dev_addr'. Warning: The use of the IP address '0.0.0.0' suggests a production environment or the use of a proxy to connect to the MkDocs server. However, the MkDocs' server is intended for local development purposes only. Please use a third party production-ready server instead.
docs-1 |INFO     -  Cleaning site directory
docs-1 |INFO     -  The following pages exist in the docs directory, but are not included in the "nav" configuration:
docs-1 |  - index.md
docs-1 |INFO     -  Documentation built in 0.29 seconds
docs-1 |INFO     -  [08:15:37] Watching paths for changes: 'docs', 'mkdocs.yml'
docs-1 |INFO     -  [08:15:37] Serving on http://0.0.0.0:8000/
docs-1 |INFO     -  [08:15:50] Browser connected: http://0.0.0.0:8000/tutorial/

http://0.0.0.0:8000/tutorial/ と表示されているので、ブラウザでアクセスすると同様にチュートリアルドキュメントページが表示されます。

5. Finch アンインストール

Homebrew でインストールしている場合は、Homebrew でアンインストールします。

brew uninstall finch

~/.finch/ は削除されなかったので手動で削除しておきます。

rm -rf ~/.finch

6. (おまけ) AWS SAM のローカル実行機能を使おうとしたけど、できなかった

AWSが開発するOSということなので、AWSと関連するワークフローの一つとして AWS SAM のローカル環境実行機能(sam local 系コマンド)を使ってみます。

雛形作成時にできる HelloWorld API を起動してみます。
SAM の環境準備については以下の記事参照

sam local invoke HelloWorldFunction
Error: Running AWS SAM projects locally requires Docker. Have you got it installed and running?

Docker が必要と言われて実行できません。

公式のトラブルシューティングでは Docker インストールしてとしか書かれていません。
多分、Finch はサポートされていないです。

調べてみると unix.socket (Dockerデフォルトは /var/run/docker.sock) にソケットが作成されていないため SAM からコンテナが取り扱えないようです。

--debug付きで実行
$ sam local invoke HelloWorldFunction --debug

# 省略

2023-11-25 18:10:44,954 | Docker is not reachable
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/aws-sam-cli/1.95.0/libexec/lib/python3.8/site-packages/urllib3/connectionpool.py", line 714, in urlopen
    httplib_response = self._make_request(
  File "/opt/homebrew/Cellar/aws-sam-cli/1.95.0/libexec/lib/python3.8/site-packages/urllib3/connectionpool.py", line 415, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.95.0/libexec/lib/python3.8/site-packages/urllib3/connection.py", line 244, in request
    super(HTTPConnection, self).request(method, url, body=body, headers=headers)
  File "/opt/homebrew/Cellar/python@3.8/3.8.17_1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/http/client.py", line 1256, in
request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/opt/homebrew/Cellar/python@3.8/3.8.17_1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/http/client.py", line 1302, in
_send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/opt/homebrew/Cellar/python@3.8/3.8.17_1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/http/client.py", line 1251, in
endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/opt/homebrew/Cellar/python@3.8/3.8.17_1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/http/client.py", line 1011, in
_send_output
    self.send(msg)
  File "/opt/homebrew/Cellar/python@3.8/3.8.17_1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/http/client.py", line 951, in send
    self.connect()
  File "/opt/homebrew/Cellar/aws-sam-cli/1.95.0/libexec/lib/python3.8/site-packages/docker/transport/unixconn.py", line 27, in connect
    sock.connect(self.unix_socket)
FileNotFoundError: [Errno 2] No such file or directory

Finch はソケットを公開していないので、SAM は Finch をサポートしていないとのことでした。
残念。。

以上

Discussion