M1 Mac に colima をインストールして IntelliJ で実行できるようにするまで
M1 Mac に Docker Desktop の 代わりに colima をインストールし、IntelliJ IDEA からdocker
と docker compose
コマンドを使って実行できるようにした
今回試したバージョンとスペック
- M1 Mac
- chip: M1 Pro
- memory: 16GB
- OS: Sonoma 14.2.1
- IntelliJ IDEA
- Ultimate 2023.3.2
- Homebrewでインストールしたパッケージ
- colima: 0.6.7
- docker: 24.0.7
- docker-compose: 2.23.3
- docker-credential-helper: 0.8.0
要約すると以下の通り(コンテナ Runtime は Docker を採用)
1. colima, docker client を インストール
> brew install colima docker
2. docker-compose を インストール
> brew install docker-compose
> mkdir -p ~/.docker/cli-plugins
> ln -sfn /opt/homebrew/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose
3. docker-credential-helper をインストール
> brew install docker-credential-helper
> vim ~/.docker/config.json
{
"auths": {},
"credsStore": "osxkeychain",
"currentContext": "colima"
}
intelliJ IDEA の 設定
- Settings > Build, Execution, Deployment > Docker
- Serviceを追加して接続先に Colimaを選択する
- Settings > Build, Execution, Deployment > Docker > tools
- docker と docker compose の両方の実行パスに
/opt/homebrew/bin/docker
を指定する
以上
MacOS を 15(Sequoia) に変えたところ qemu
のインストールが別途必要になった模様で、brew で install を求められた。(以前は依存関係として自動でインストールされていた?)
恐らくこのIssueが関係しているようで、colima 0.8.0 から依存関係に追加されている。ただ brew で自動でインストールされなかったので、個別に qemu をインストールして対応した
colima の githubを見る感じ、最新の0.8.0 なら qemu を別途インストールしなくても良いのかなと思ったんだけどダメっぽいので、とりあえず qemu もインストールしたままにしておく
homebrewでcolimaを1回削除して、最新の0.8 1に入れ直したところqemuの別途インストールは不要だった
先に インストール済みだった Docker Desktop をアンインストールする
- homebrew を使ったので
brew rm --cask docker
を実行する -
$HOME/.docker/cli-plugins
ディレクトリに docker desktop アプリのプラグインへのsymbolicリンクが残っていたので cli-plugins ディレクトリごと削除する
colima をインストールする
ドキュメント通り、homebrew install colima
を実行する
インストール後、colima start
を実行すると エラーが出ており 起動はしているが正常に動作しない状態だったので、colima delete
でインスタンスを一旦削除した後、再度 colima start
を実行したら今度は正常に起動できた
brew services start colima
を実行し、Mac起動時に colimaを自動起動するようにした
コンテナランタイムは Docker を利用するため、brew install docker
で cli をインストールする
containerd も使ってみようかと思ったが、IntelliJ IDEA から実行(nerdctl
での実行)できるか不明だったので試していない
IntelliJ IDEA の Dockerプラグインがサポートしているのは dockerd だけだった
自分が勘違いしていて、Colima が使う Container runtime はDocker Engine (docker daemon) 互換をcolimaが持っていて、デフォルトではそれを使う。
homebrew で インストールしている docker は Docker client (Docker CLI) なだけで、docer engineは含まれていなかった。
実際に colimaを止めて docker version
を実行すると clientの情報は表示されるけど、serverの方は表示されなくなり、起動してるか聞かれる。
IntelliJ IDEA から 利用できるようにする
Settings > Build, Execution, Deployment > Docker から、Serviceを追加し、Connect to Docker daemon with から Colima
を選択する
Tools で、Docker executable と Docker Compose executable のPathを設定する。
尚、画像は最後の状態なので Docker compose の実行パスを認識しているが、実際にはまだDocker composeをインストールしていないので実行パス入力時は認識していない旨のメッセージが表示される
brew docker-compose
で、Docker compose を インストールする
インストール時にターミナルにも注意表示が出るが Docker compose は Docker plugin として扱われるため、以下の通り .docker/cli-plugins
に シンボリックリンクを追加することで docker compose
コマンドとして認識される。 IntelliJ からも 利用できるようになる
❯ mkdir -p ~/.docker/cli-plugins
❯ ln -sfn /opt/homebrew/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose
❯ docker compose version
Docker Compose version 2.23.3
シンボリックリンクでも動くけど、今見たら以下のように記載されていたので、 ~/.docker/config.json に homebrew でインストールした cli-plugins を extra_dirs として指定してあげるだけでも良さそう
Compose is a Docker plugin. For Docker to find the plugin, add "cliPluginsExtraDirs" to ~/.docker/config.json:
"cliPluginsExtraDirs": [
"$HOMEBREW_PREFIX/lib/docker/cli-plugins"
]
IntelliJ から 既存の compose.yml を実行した所、以下のようなエラーが出力された。どうやら Imageのダウンロードで失敗した模様。
Error saving credentials: error storing credentials - err: exec: "docker-credential-desktop": executable file not found in $PATH, out: ``
Colimaの Issue に同様の問題がありそのコメント内でリンクされていた stackoverflowの回答を元に brew docker-credential-helper
をインストールし、~/.docker/config.json
の credsStore
を Desktop
から osxkeychain
に変更したら解決した
{
"auths": {},
"credsStore": "osxkeychain",
"currentContext": "colima",
"plugins": {
"-x-cli-hints": {
"enabled": "true"
}
}
}
Stackoverflowの回答では、最後に Docker Hub へのログインを行なっていたが 今回は特に不要だと思う。
("思う" なのは、一旦ログインしてしまったので確証がまだ無いため)
また、docker-credential-helper
をインストールせずに、 config.json の creadsStore
プロパティ自体を削除するだけでもアクセスできそう
以上で、Docker Desktop for mac を使っていた時と同様の状態にはなったので、しばらくこの環境で使ってみる
Colima で起動するVMインスタンスのデフォルトスペックは CPU: 2, Memory: 2GB, Disk: 60GB だそう。変更したい場合は、colima 起動時に colima start --cpu 4 --memory 8 --disk 10
のように指定できる
もしくは config ファイルで 設定できそう
~/.colima/<profile-name>/colima.yaml
で、プロファイルごとの設定を定義することができる。
初期は default プロファイルだけが作成されているので、このファイルで設定を変更したり、新たなプロファイルを用意してColimaを再起動する。再起動するときに -p or --profile <profile-name>
を付ければ指定したプロファイルで起動してくれそう
今回は default プロファイルの Memoryを変更する事にした
# Number of CPUs to be allocated to the virtual machine.
# Default: 2
cpu: 2
# Size of the disk in GiB to be allocated to the virtual machine.
# NOTE: changing this has no effect after the virtual machine has been created.
# Default: 60
disk: 60
# Size of the memory in GiB to be allocated to the virtual machine.
# Default: 2
memory: 4
# Architecture of the virtual machine (x86_64, aarch64, host).
# Default: host
arch: aarch64
# Container runtime to be used (docker, containerd).
# Default: docker
runtime: docker
# Set custom hostname for the virtual machine.
# Default: colima
# colima-profile_name for other profiles
hostname: colima
......
Dockerコンテナは正常に起動しているのにアクセスが出来なくなった場合は、colima restart
で再起動してコンテナを立ち上げ直すと繋がった
今日 brew update で lima を更新したところ、colimaが自動起動されなくなり restartを実行したところ FATA[0004] error starting vm: error at 'starting': exit status 1
が出力された
Issueを調べたところ colima delete
で一旦 VMを削除して colima start
で作り直す必要があった模様。
起動するようにはなったが、profileもリセットされたので修正を行った
VM作り直したから コンテナもイメージもボリュームもみんな消えたので再作成が必要
開発環境なので致命的ではないが必要なら vm 削除前に少なくともボリュームはバックアップしておかないと
今日は colima delete
を行っても次のようなエラーが出て先に進めなかった
failed to stop usernet "user-v2": Get "http://lima/services/dhcp/leases": dial unix /Users/***/.colima/_lima/_networks/user-v2/user-v2_ep.sock: connect: connection refused FATA[0003] error during teardown of vm: exit status 1
Issueを見たところ次のコメントの通り rm -rf ~/.colima/_lima/_networks/user-v2
を行ってから colima start
で起動することができた! ひょっとしたら colima delete
は不要だったかもしれないので次回同様の問題が起こった時に確認する
rm -rf ~/.colima/_lima/_networks/user-v2
を行ってから colima start
で大丈夫だった
Javaのテストコードで Testcontainers を使っているときに Caused by: java.lang.IllegalStateException: Could not find a valid Docker environment. Please see logs and check configuration
というエラーが出る。
これは Testcontainer 側から Dockerを実行しようとして Colimaへのパスが参照できていないのが問題みたい。
GitHub の Issue の このコメント の通り、環境変数を2つ定義すれば実行してくれるようになる
export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock
export DOCKER_HOST="unix://${HOME}/.colima/docker.sock"
IntelliJ IDEA から テストを実行する場合は、実行Configurationのこれらの環境変数を追加すること
その際、DOCKER_HOST
の方は unix://$HOME$/.colima/docker.sock
とする
Testcontainerの 公式ドキュメント だと、export TESTCONTAINERS_HOST_OVERRIDE=$(colima ls -j | jq -r '.address')
も必要になっているが 無くてもいけそうなので設定しないことにする。
ちなみに 必要だと colima start --network-address
と アドレスを有効にする必要があるのと、IntelliJの環境変数設定で $(colima ls -j | jq -r '.address')
で アドレスが取れずにエラーとなるため、事前にアドレスを抽出する手間があるのも設定しない理由(方法があれば知りたい)
ntelliJ IDEA から テストを実行する場合は、実行Configurationのこれらの環境変数を追加すること
Configuration Template で、JUnit の 実行に対して追加すると テスト設定ごとに追加する必要がないので便利
colimaの versionが上がって、環境変数が少し変わったが、以下の設定で gradle でテスト実行はできた
export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock
export DOCKER_HOST="unix://${HOME}/.colima/default/docker.sock"
ただ IntelliJ の TestConfigurationで 設定しても /var/run/docker.sock
が見つからないとでる。公式のFAQのようにシンボリックリンクを付けても同じな状態でテストが通らない状況。 CLIからは実行できるので IntelliJ から gradle test を実行した時に docker.sock を参照できていない?
[Test worker] ERROR org.testcontainers.dockerclient.DockerClientProviderStrategy -- Could not find a valid Docker environment. Please check configuration. Attempted configurations were:
UnixSocketClientProviderStrategy: failed with exception InvalidConfigurationException (Could not find unix domain socket). Root cause NoSuchFileException (/var/run/docker.sock)
DockerDesktopClientProviderStrategy: failed with exception NullPointerException (Cannot invoke "java.nio.file.Path.toString()" because the return value of "org.testcontainers.dockerclient.DockerDesktopClientProviderStrategy.getSocketPath()" is null)As no valid configuration was found, execution cannot continue.
参考
Buildx をインストールして BuildKitが利用できるようにする
Colima の FAQ にあるように、homebrew で docker-buildx をインストールした後に、pluginに追加する
brew install docker-buildx
mkdir -p ~/.docker/cli-plugins
ln -sfn $(which docker-buildx) ~/.docker/cli-plugins/docker-buildx
docker buildx version # verify installation
Zscaler の 環境下で Docker Buildしたときに 証明書エラーでイメージがダウンロードできない場合は、以下のようにdocker registry などの証明書を インポートした後に、Macの証明書を更新してあげることで対応できた
- docker registry の証明書を 取得する
export CERTS=~/.ca-certificates
export URL=registry-1.docker.io:443
mkdir -p $CERTS
openssl s_client -showcerts -connect $URL </dev/null 2>/dev/null|openssl x509 -outform PEM >$CERTS/docker-com.pem
openssl s_client -showcerts -verify 5 -connect $URL </dev/null 2>/dev/null | sed -ne '/-BEGIN/,/-END/p' >$CERTS/docker-com-chain.pem
- colimaの設定ファイル に以下を追加して、Colima起動時に証明書を更新する
provision:
- mode: system
script: |
CERTS="${HOME}/.ca-certificates"
cp ${CERTS}/* /usr/local/share/ca-certificates/
update-ca-certificates
systemctl daemon-reload
systemctl restart docker
- colima を再起動する
colima restart
こちらの issue の コメントを参考にしました
イメージPullでまた認証エラーが発生するようになった
以下で実行ができそう
- docker registry の証明書を 取得する 時に
.pem
ではなくて.crt
にする
export CERTS=~/.ca-certificates
export URL=registry-1.docker.io:443
mkdir -p $CERTS
openssl s_client -showcerts -connect $URL </dev/null 2>/dev/null|openssl x509 -outform PEM >$CERTS/docker-com.crt
openssl s_client -showcerts -verify 5 -connect $URL </dev/null 2>/dev/null | sed -ne '/-BEGIN/,/-END/p' >$CERTS/docker-com-chain.crt
# zscalerのルート証明書も Colimaにセットする場合はこのコマンドで crtファイルを取得して一緒にコピーする
security find-certificate -p -c "ZScaler Root CA" > .ca-certificates/zscaler-root-cert.crt
.crt
に変換しなくても、 x509 -outform PEM
と形式を指定して出力すれば、 .pem
でも大丈夫な気はしてる
- 起動中のcolimaに sshで入り、1で取得した 証明書をコピーして反映する
# hostで取得した証明書をコピーする
colima ssh -- sudo cp ${CERTS}/* /usr/local/share/ca-certificates/
# proxyのアップデート
colima ssh -- sudo update-ca-certificates
# docker再起動
colima ssh -- sudo systemctl daemon-reload
colima ssh -- sudo systemctl restart docker
.colima/default/colima.yml
に追記していたprovision時のscriptは crtファイルがコピーできなかったので設定自体、Yamlから削除した
- colima を再起動する
colima restart
最初はうまくいかなかったのですが、
rm -rf ~/.colima/_lima/_networks/user-v2
でネットワーク設定を初期化したり、colima ssh
して /usr/local/share/ca-certificates
の中身を削除したりして、綺麗な状態にしてから再度試したらうまくいった
zscalerが proxyとなっていると colimaからdocker hub などにアクセスする際のTLSハンドシェイクで、zscalerのサーバー証明書を提示するが colima内部のTrust Store にはこの証明書に対するZscalerのルート証明書がインポートされていないので信頼できない証明書としてエラーになっている模様。
このためホストのTrust Store (Mac の keychain)にインストールされている Zscaler の ルート証明書を Colimaの Trust StoreにインストールすることでTLS ハンドシェイクを通すようにしている。
この場合、以前のこの設定との関連性がよくわかっていない。この操作でもMac の KeychainをTrust Storeとして参照できるようにしている気もするが。こっちは credential だから認証情報であって証明書とは関係ないってことかな