概要
こんにちは。サーバーサイドエンジニアの窪田です。 先日、Finchという名前のOSSがAWSから発表されましたね!
FinchはLinuxコンテナのビルドや起動等ができるコマンドラインクライアントで、 Docker Desktopに代わるコンテナ管理できるツールとして期待されています。 英単語のFinchは小鳥の総称の意味らしいです。ロゴも小鳥っぽいですね!
今回はFinchを触ってみると同時に、普段使っているヤプリのプロダクト群の開発環境は動かせるのか調べました。
ヤプリの開発環境
ヤプリでは以下のコンテナをdockerで管理しています。
- nginx(web サーバ)
- php-fpm (php アプリケーションサーバ)
- MySQL
- Redis
- LocalStack
- MailHog
また、人によっては
- grpcサーバ(Goアプリケーション)
- envoy
- その他いろいろ
もdockerの上で動作させて開発しています。 自分はgrpcサーバについてはMacの上で起動させています。
docker-compose.ymlでこれらのサービス群を管理しています。 docker-compose.ymlの雰囲気は以下です。
version: '3.7' services: app: platform: linux/amd64 build: . shm_size: 256m volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf ports: - "8084:80" environment: SQS_ENDPOINT: http://localstack:4566 networks: my_network: depends_on: - redis - mysql redis: image: redis:3 networks: my_network: ports: - "6379:6379" mysql: platform: linux/amd64 image: mysql:5.7 volumes: - ./db/data:/var/lib/mysql networks: my_network: ports: - "13306:3306" environment: MYSQL_ROOT_PASSWORD: password localstack: image: localstack/localstack:1.0 ports: - "4566:4566" networks: - my_network networks: my_network:
内部情報が書かれていたので部分的に消していたり、書き換えたりしています。 あくまで雰囲気を感じ取っていただけたらと思います。
app serviceのbuild用DockerfileはRUNコマンドでphpやnginxのインストールを行い, CMDコマンドでwebサーバ、アプリケーションサーバを起動するというごく一般的な内容です。
これを
~$ docker-compose up
によって開発に必要なサーバ等を起動しています。
Finchを使ってみる
下準備
finchのインストールはGUIでreadmeに従い行いました。 紹介している他記事がたくさんあるので省略します。
~$ finch -v finch version v0.1.0
でインストールが確認できました。
readmeに従い仮想マシンを起動します
~$ finch vm init
以降finch vm start
, finch vm stop
で仮想マシンの起動、停止は行えます。
finch compose upを試す
docker-composeはdockerと別にインストールが必要なのに対し、 Finchはcomposerをデフォルトで備えています。
docker-compose up
の代わりに
~$ finch compose up --build
を実行すると...失敗しました(惜しい)。
対応したことを残します。
env fileは明確に指定する必要がある
.envrcなどで定義している環境変数を渡したい場合
finch compose up --env-file=.envrc
のように明示する必要がありました。
mysql:5.7 イメージについて、platform, uidを明示する必要がある
結論的には以下の変更をdocker-compose.ymlに対して行いました。
(略) mysql: platform: linux/amd64 // <-----追記 image: mysql:5.7 volumes: - ./db/data:/var/lib/mysql networks: my_network: ports: - "13306:3306" user: 1000:1000 // <-----追記 environment: MYSQL_ROOT_PASSWORD: password (略)
mysql:5.7のbaseはRHELで、defaultの最小uidである1000を指定しました。 指定しないと、コンテナ内部でroot権限が得られずpermission denied エラーが発生しました。
驚くことに、対応したのはこれらだけでした。
ほぼそのままdocker-compose.ymlを使うことができました。
MySQL, Redis, LocalStack等もdocker-compose up
で起動した時と同様に開発環境で動かすことができました。
もちろんvolumeやnetworkも同じように使えます。
~$ finch volume ls ~$ finch network ls
で新規volume, networkが作成されていることを確認できました。
おまけ・その1: コンテナからホストへアクセスしたい時の注意
envoyを例に取ります。 ヤプリではgrpcサーバで提供されるプロダクトがあるのでenvoyが必須になります。 開発環境では、grpcサーバ(Goアプリケーション)をMacの上に立てて、その上流にenvoyをdockerで立てることがあります。 その場合、アクセスは外部-> envoy(on docker)-> grpcサーバ(on mac)の経路になります。 この時、使うenvoy.yamlは以下のようになります。
static_resources: listeners: -----------省略-------------- clusters: - name: local_service -----------省略-------------- load_assignment: cluster_name: cluster_0 endpoints: - lb_endpoints: - endpoint: address: socket_address: address: host.docker.internal port_value: 50051
ポイントはaddress: host.docker.internal
でホスト(今回の場合Mac)の50051ポートへ転送しています。
これをそのままFinchで使うと動きません。
Finchは内部的にLimaという仮想マシンを使っています。 github.com
そのため、Finchで使うためにはaddress: host.lima.internal
を指定する必要があります。
static_resources: listeners: -----------省略-------------- clusters: - name: local_service -----------省略-------------- load_assignment: cluster_name: cluster_0 endpoints: - lb_endpoints: - endpoint: address: socket_address: address: host.lima.internal port_value: 50051
おまけ・その2: Hot Reloadが効かない
これは試したみただけで、細かい原因までは辿り着けていませんが、Finchで起動したコンテナの上ではHot Reload(厳密にはファイル変更検知)が効きませんでした。 試したのは Goのair github.com
とNestjsというTypeScript FWのwatchモードで試しました。 docs.nestjs.com 結果的に両方の場合、docker-compose ではHot Reloadが効きましたがFinchでは効きませんでした。
airで試した際のdocker-compose.ymlとDockerfileは以下です。
version: '3' services: app: platform: linux/amd64 build: . working_dir: /var/work/go-container user: root volumes: - type: bind source: . target: /var/work/go-container
FROM golang:1.19.3-alpine RUN go install github.com/cosmtrek/air@latest RUN adduser docker -D CMD ["air"]
volumeとしてマウントしていて、lessコマンド等で確認する限りファイル変更はされます。 また、サーバを再起動すれば変更は反映されるので、Hot Reloadさえ気にしなければ開発には全く支障はないと思います。 airはファイル変更を sys/unix packageで検知する仕様です。 pkg.go.dev このパッケージはシステムコールレベルまでアクセスして変更を検知していてその仕様とFinchのvolumeマウントの仕様を知る必要がありそうです。 この辺りは調べられたら別記事にまとめようと思います。
まとめ
AWSが発表して話題になっていたFinchですが、思ったよりも少ない手間で今開発環境で使っているdocker-compose.ymlに対応させることができることがわかりました。 今後も動向を追っていこうと思います。 ヤプリでは開発環境はdockerで構築しています。(というかサービスが多すぎてdockerがないと厳しい。) 本番サービスについても大部分がコンテナで運用しています。 このあたりの話に興味が少しでもあればぜひカジュアル面談にお越しください。