JavaのユニットテストでLocalStack Java Utils v0.1.22を使ってAWSサービスのテストをしていたが、Windows + Docker Desktopの環境で Cannot find docker executable. というエラーが発生するようになった。
CLIからの docker コマンドは通るのに、Javaのユニットテストでは失敗しており、結構ハマったので対応方法をメモ。
環境
Windows 10 64bit Pro, Docker Desktop v2.3.0.5 および v3.1.0, LocalStack Java Utils v0.1.22。
Docker DesktopはChocolateyを使い、 choco install docker-desktop でインストールした。
Docker Desktopは起動しており、 docker や docker-compose コマンドでのDockerイメージ操作やコンテナ起動は問題なく行える前提。
問題
@RunWith(LocalstackTestRunner.class) や、 cloud.localstack.docker.Container.createLocalstackContainer でLocalStackコンテナを起動しようとすると、以下の例外が発生し、コンテナ起動に失敗する。
Cannot find docker executable.
java.lang.IllegalStateException: Cannot find docker executable.
at cloud.localstack.docker.DockerExe.lambda$getDockerExeLocation$1(DockerExe.java:46)
at java.util.Optional.orElseThrow(Optional.java:290)
at cloud.localstack.docker.DockerExe.getDockerExeLocation(DockerExe.java:46)
at cloud.localstack.docker.DockerExe.<init>(DockerExe.java:37)
at cloud.localstack.docker.command.Command.<init>(Command.java:11)
at cloud.localstack.docker.command.PullCommand.<init>(PullCommand.java:18)
at cloud.localstack.docker.Container.createLocalstackContainer(Container.java:53)
原因
LocalStack Java Utilsの設定に記載があるが、 docker.exe の保存パスに制限がある模様。
NOTE: These utilities assume docker is installed in one of the default locations (
C:\program files\docker\docker\resources\bin\docker.exe,C:\program files\docker\docker\resources\docker.exe,usr/local/bin/dockerorusr/bin/docker). If your docker executable is in a different location, then use theDOCKER_LOCATIONenvironment variable to specify it.
コマンドプロンプトで where docker すると、以下のパスに保存されていた。
>where docker C:\ProgramData\DockerDesktop\version-bin\docker C:\ProgramData\DockerDesktop\version-bin\docker.exe
対応
環境変数 DOCKER_LOCATION に docker.exe のパスを指定する。今回の場合、 C:\ProgramData\DockerDesktop\version-bin\docker.exe 。
IDEやCLIからテストを実行している場合は、それらを再起動するなどで環境変数を再読み込みさせると、例外は発生しなくなった。
LocalStack Java Utils v0.2系について
LocalStack Java Utilsはv0.2系が出ており、バージョンをv0.2.7にしてみたところ、発生しなかった。
LocalStack Java UtilsのGitリポジトリにタグ付けされていないので、ソース確認はしていないが、 docker.exe にPATHが通っていれば動作するようになったのかな?
振り返り
もともと動いていたのに、Docker Desktopのバージョンを上げたら動かなくなったので、 docker.exe のパスが変わったのかな?
余談だが、 LocalStack に対して、LocalStack Java Utilsのクラス内では Localstack なの、なんでだろう...