2022-12-22 12:35 根本的なミスが発覚したため、本文の趣旨を変更しました。
こんにちは。サービス部の武田です。
新しいMacのセットアップをしていたところ、Rancher Desktopをインストールしてdocker
コマンドは使えるようになったのに、CDKのビルドで失敗しました。いろいろ試してみたところ、Docker CLIを別途インストールすることで解決できました。Docker CLIのインストールでも解決できましたが、そもそもPATHの指定が間違っていました。
環境の前提
前提としてRancher Desktopはインストール済みです。
$ sw_vers
ProductName: macOS
ProductVersion: 12.6.2
BuildVersion: 21G320
$ docker -v
Docker version 20.10.21-rd, build ac29474
$ type docker
docker はハッシュされています (/Users/username/.rd/bin/docker)
$ docker info
Client:
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc., v0.9.1)
compose: Docker Compose (Docker Inc., v2.14.0)
Server:
Containers: 22
Running: 22
Paused: 0
Stopped: 0
Images: 17
Server Version: 20.10.20
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runtime.v1.linux runc io.containerd.runc.v2
Default Runtime: runc
Init Binary: docker-init
containerd version: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
runc version: 5fd4c4d144137e991c4acebb2146ab1483a97925
init version:
Security Options:
seccomp
Profile: default
Kernel Version: 5.15.78-0-virt
Operating System: Alpine Linux v3.16
OSType: linux
Architecture: aarch64
CPUs: 2
Total Memory: 3.829GiB
Name: lima-rancher-desktop
ID: IHQO:JWGB:5232:VBIQ:QLOL:VSSN:IGJ5:3UD5:T3QO:HME2:ZKFD:O2ND
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
CDKのビルド失敗
さて、この状態でユニットテストをしてみるとビルドに失敗します。
$ npm run test
> sample@0.1.0 test
> jest
FAIL test/sample.test.ts
● Snapshot Test
spawnSync docker ENOENT
68 |
69 | // Layers
> 70 | const layer = new lambdaPython.PythonLayerVersion(this, 'PythonLambdaLayer', {
| ^
71 | layerVersionName: 'python-lambda-layer',
72 | entry: path.resolve(__dirname, './layer'),
73 | compatibleRuntimes: [lambda.Runtime.PYTHON_3_9],
at dockerExec (node_modules/aws-cdk-lib/core/lib/bundling.js:1:5035)
at Function.fromBuild (node_modules/aws-cdk-lib/core/lib/bundling.js:1:3660)
at new Bundling (node_modules/@aws-cdk/aws-lambda-python-alpha/lib/bundling.ts:84:39)
at Function.bundle (node_modules/@aws-cdk/aws-lambda-python-alpha/lib/bundling.ts:55:44)
at new PythonLayerVersion (node_modules/@aws-cdk/aws-lambda-python-alpha/lib/layer.ts:63:22)
at new SampleStack (lib/sample-stack.ts:70:19)
at test/sample.test.ts:48:20
PASS test/sample-asset-bucket.test.ts
Test Suites: 1 failed, 1 passed, 2 total
Tests: 1 failed, 1 passed, 2 total
Snapshots: 1 passed, 1 total
Time: 3.434 s
Ran all test suites.
spawnSync docker ENOENT というエラーメッセージはDocker環境がない場合に出るエラーのようです。環境はあるはずなのに!ということでしばらくはまっていました。
Docker CLIをインストールして解決
Rancher Desktopを疑ったのですが、以前似た環境で動作していました。
当時の環境との差異を思い出してみて、以前はDockerをインストールしたあとでRancher Desktopをインストールしていました。というわけで、試しに次のコマンドを打ってインストールしてみました。
$ brew install docker
$ /opt/homebrew/bin/docker -v
Docker version 20.10.22, build 3a2c30b63a
再度実行。
$ npm run test
...
PASS test/sample.test.ts (33.107 s)
Test Suites: 2 passed, 2 total
Tests: 2 passed, 2 total
Snapshots: 2 passed, 2 total
Time: 33.339 s
Ran all test suites.
おお、動いた。
以下、追記
そもそもPATHの指定が間違っていた
Rancher Desktopをインストールした際、/Users/username/.rd/bin/
にPATHを通します。自動設定を選択した場合は、.bash_profile
などに追加されます。今回私の場合は.bashrc
管理の関係から手動で設定していました。
その際、次のように指定していました。
export PATH="~/.rd/bin/:$PATH"
しかしこれは間違いで、正しくは次のように指定します。
export PATH=~/.rd/bin/:$PATH
違いに気付いたでしょうか?"
の有無が違います。実はシェル(ここではbash)では~
を"
でくくるかどうかで出力が変わります。
$ echo "~"
~
$ echo ~
/Users/username
CDKの実行環境では~
のままでは正しくPATHが解決できず、それでdocker
コマンドを見つけられなかった。というのが真相のようです。
まとめ
似たモジュールであるLambda Nodejsでも同様のエラーが発生する可能性はあります。ただしNodejsの場合はesbuild
をインストールするという方法もあり、Dockerに依存しない解決が可能です。Pythonの場合はそういった代替がないためきちんとDockerの環境を整える必要があります。
なぜDocker CLIをインストールすると解決できるのか、具体的な理由は追っていません。おそらくCDK内部でのコマンドの探索方法に原因があるものと思われます。
相対パスではなく絶対パスで指定すれば問題なく実行できました。指定方法には気をつけましょう。
なお、そもそもdocker
コマンドではなく別の互換コマンドで実行したい場合にはCDK_DOCKER
を使用する方法があります↓。