CDKのLambda Pythonを使う場合にRancher Desktopだけで動かなかったがPATHの指定方法が間違っていた
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
を使用する方法があります↓。