JavaのユニットテストでLocalStackを使っているときに「Cannot find docker executable」が出たときの対応方法

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は起動しており、 dockerdocker-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/docker or usr/bin/docker). If your docker executable is in a different location, then use the DOCKER_LOCATION environment variable to specify it.

コマンドプロンプトwhere docker すると、以下のパスに保存されていた。

>where docker
C:\ProgramData\DockerDesktop\version-bin\docker
C:\ProgramData\DockerDesktop\version-bin\docker.exe

対応

環境変数 DOCKER_LOCATIONdocker.exe のパスを指定する。今回の場合、 C:\ProgramData\DockerDesktop\version-bin\docker.exe

IDECLIからテストを実行している場合は、それらを再起動するなどで環境変数を再読み込みさせると、例外は発生しなくなった。

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 なの、なんでだろう...