Closed23

GoとSAMの開発環境をコンテナで構築するメモ

Sut103Sut103

devcontainer.jsonに以下追記

devcontainer.json
"features": {
		"ghcr.io/devcontainers/features/aws-cli:1": {},
		"ghcr.io/customink/codespaces-features/sam-cli:1": {}
	}

AWS CLIとSAM CLIが入る

Sut103Sut103

ベースをgoの開発用imageにしていたが、dind(dood)のimageにしたほうがいいかも。
(開発コンテナ内のsamでエミュレートする際にコンテナが必要なため)

Sut103Sut103

というわけでこう

devcontainer.json
"features": {
		"ghcr.io/devcontainers/features/aws-cli:1": {},
		"ghcr.io/customink/codespaces-features/sam-cli:1": {},
                "ghcr.io/devcontainers/features/docker-in-docker:2": {}
	}
Sut103Sut103

コンテナのdynamodb-local(ホストOS上のコンテナ)を使いたかったが、dind(開発コンテナ上のコンテナ)では接続できないかも?
doodに変更してみる。

Sut103Sut103

doodではsamを実行しているコンテナに接続する際にタイムアウトしてしまった。

$ sam local invoke
Invoking main (go1.x)                                                                                                                                                                                      
Local image is up-to-date                                                                                                                                                                                  
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.                                                                                                                                                
                                                                                                                                                                                                           
Mounting /workspaces/HCW-SS-Viewer/.aws-sam/build/xxxx as /var/task:ro,delegated, inside runtime container                                                                                          
Timed out while attempting to establish a connection to the container. You can increase this timeout by setting the SAM_CLI_CONTAINER_CONNECTION_TIMEOUT environment variable. The current timeout is 20.0 
(seconds).    
Hidden comment
Sut103Sut103

開発コンテナからsam local invoke するときにホストOSのIPアドレスを指定してやればいい?

とりあえず開発コンテナでhost.docker.internalを使えるようにしてみる。
手元でいじっている環境はdocker composeの開発コンテナなので、docker-compose.ymlに追記した。

./.devcontainer/docker-compose.yml
version: '3'
services:
  api:
    extra_hosts:
      - "host.docker.internal:host-gateway"

    volumes:
      - ..:/workspaces:cached
      
    command: /bin/sh -c "while sleep 1000; do :; done"

dokcerコンテナ単体の開発コンテナであれば、devcontainer.jsonに追記?

devcontainer.json
# docker-compose.yml無いとき
{
    "runArgs": ["--add-host=host.docker.internal:host-gateway"]
}

https://qiita.com/frozenbonito/items/b1de3980ee0553fb1c2f#ホスト経由でアクセスする

Sut103Sut103

開発コンテナをリビルドして、/etc/hostsを確認してみる。

$ cat /etc/hosts | grep internal
172.17.0.1      host.docker.internal

sam local invokeしてみる。
状況変わらず。

$ sam local invoke
Invoking main (go1.x)                                                                                                                                                                                                       
Local image is up-to-date                                                                                                                                                                                                   
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.                                                                                                                                                                 
                                                                                                                                                                                                                            
Mounting /workspaces/xxxx/.aws-sam/build/xxxx as /var/task:ro,delegated, inside runtime container                                                                                                           
Timed out while attempting to establish a connection to the container. You can increase this timeout by setting the SAM_CLI_CONTAINER_CONNECTION_TIMEOUT environment variable. The current timeout is 20.0 (seconds).  

--container-hostオプションをつけてhost.docker.internalを指定してみる。
状況変わらず。

$ sam local invoke --container-host host.docker.internal
Invoking main (go1.x)                                                                                                                                                                                                       
Local image is up-to-date                                                                                                                                                                                                   
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.                                                                                                                                                                 
                                                                                                                                                                                                                            
Mounting /workspaces/xxxx/.aws-sam/build/xxxx as /var/task:ro,delegated, inside runtime container                                                                                                           
Timed out while attempting to establish a connection to the container. You can increase this timeout by setting the SAM_CLI_CONTAINER_CONNECTION_TIMEOUT environment variable. The current timeout is 20.0 (seconds).  

--container-host-interfaceオプションもつけてみる。
お?

sam local invoke --container-host host.docker.internal --container-host-interface host.docker.internal
Invoking main (go1.x)                                                                                                                                                                                                       
Local image is up-to-date                                                                                                                                                                                                   
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.                                                                                                                                                                 
                                                                                                                                                                                                                            
Mounting /workspaces/xxxx/.aws-sam/build/xxxx as /var/task:ro,delegated, inside runtime container                                                                                                           
START RequestId: 3ae54bfb-f432-4c9d-a9ce-ce95bc8611db Version: $LATEST
fork/exec /var/task/main: no such file or directory: PathError
null
END RequestId: 3ae54bfb-f432-4c9d-a9ce-ce95bc8611db
REPORT RequestId: 3ae54bfb-f432-4c9d-a9ce-ce95bc8611db  Init Duration: 0.05 ms  Duration: 6.21 ms       Billed Duration: 7 ms   Memory Size: 512 MB     Max Memory Used: 512 MB
{"errorMessage":"fork/exec /var/task/main: no such file or directory","errorType":"PathError"}

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html

Sut103Sut103

ホストとコンテナ内のパスが一致していないとうまく動かないという話を見た。(どこで見たのか忘れてしまった...)
以下の通りdocker-compose.ymlを変更してみる。

.devcontainer/docker-compose.yml
version: '3'
services:
  api:
    extra_hosts:
      - "host.docker.internal:host-gateway"

    volumes:
      - .:/$PWD:cached
      
    command: /bin/sh -c "while sleep 1000; do :; done"
 

samでLambdaを実行できた雰囲気を感じる

sam local invoke --container-host host.docker.internal --container-host-interface host.docker.internal

        SAM CLI now collects telemetry to better understand customer needs.

        You can OPT OUT and disable telemetry collection by setting the
        environment variable SAM_CLI_TELEMETRY=0 in your shell.
        Thanks for your help!

        Learn More: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-telemetry.html

Invoking main (go1.x)                                                                                                                                                                                      
Local image is out of date and will be updated to the latest runtime. To skip this, pass in the parameter --skip-pull-image                                                                                
Building image....................................................
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.                                                                                                                                                
                                                                                                                                                                                                           
Mounting /home/sut103/dev/xxxx/.aws-sam/build/xxxx as /var/task:ro,delegated, inside runtime container                                                                                     
START RequestId: dc8f8445-7eae-4ce6-acf6-c735be684436 Version: $LATEST
2023/07/20 03:44:10 2023-07-20 03:44:10.070372981 +0000 UTC m=+0.238315686 getScreenshots():  operation error DynamoDB: Scan, https response error StatusCode: 400, RequestID: LRLVKH70JID3GTA6KCBIBOTPQRVV4KQNSO5AEMVJF66Q9ASUAAJG, api error UnrecognizedClientException: The security token included in the request is invalid.
{"statusCode":500,"headers":null,"multiValueHeaders":{"Content-Type":["application/json; charset=UTF-8"]},"body":"{\"message\":\"Internal Server Error\"}\n"}END RequestId: dc8f8445-7eae-4ce6-acf6-c735be684436
REPORT RequestId: dc8f8445-7eae-4ce6-acf6-c735be684436  Init Duration: 0.28 ms  Duration: 264.90 ms     Billed Duration: 265 ms Memory Size: 512 MB     Max Memory Used: 512 MB

SAM CLI update available (1.92.0); (1.90.0 installed)
To download: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html

エラーの出ている部分はDynamoDB-Localとの接続。(環境変数を入れてない)
接続情報を適切に入力しつつ、DynamoDB-Localと同じDocker networkにsam コンテナを接続してやればつながる。

Sut103Sut103

docker networkを合わせないで、host.docker.internalを使ってdynamodbに繋げられる方が便利そうだなぁ...。今のところ不明

Sut103Sut103

その他拡張機能や設定をカスタマイズしたい場合は以下に記載。

devcontainer.json
"customizations": {
		// Configure properties specific to VS Code.
		"vscode": {
			// Set *default* container specific settings.json values on container create.
			"settings": {},
			"extensions": [],
		}
}
Sut103Sut103

sam build -> sam local invoke すると以下の通りエラー

$ sam local invoke
Invoking main (go1.x)                                                                                                                                                                                      
Local image is up-to-date                                                                                                                                                                                  
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.                                                                                                                                                
                                                                                                                                                                                                           
Mounting /workspaces/xxx/.aws-sam/build/xxx as /var/task:ro,delegated, inside runtime container                                                                                          
START RequestId: 6f3e1509-3527-4d06-83a9-13e92304196d Version: $LATEST
/var/task/main: /lib64/libc.so.6: version `GLIBC_2.32' not found (required by /var/task/main)
/var/task/main: /lib64/libc.so.6: version `GLIBC_2.34' not found (required by /var/task/main)
2023/07/12 08:34:25 exit status 1
12 Jul 2023 08:34:25,127 [ERROR] (rapid) Init failed error=Runtime exited with error: exit status 1 InvokeID=
/var/task/main: /lib64/libc.so.6: version `GLIBC_2.32' not found (required by /var/task/main)
/var/task/main: /lib64/libc.so.6: version `GLIBC_2.34' not found (required by /var/task/main)
2023/07/12 08:34:25 exit status 1
END RequestId: 080c16ee-0b21-4eb7-b582-a298593d3fb7
REPORT RequestId: 080c16ee-0b21-4eb7-b582-a298593d3fb7  Init Duration: 0.05 ms  Duration: 11.52 ms      Billed Duration: 12 ms  Memory Size: 512 MB     Max Memory Used: 512 MB
Sut103Sut103

ビルド環境と実行環境でCライブラリのバージョンが異なるとうまく動作しないらしい。
本来は上記の環境変数CGO_ENABLED=0で無効化して差異が出ないようにしている。

Sut103Sut103

というわけでsam buildする前に開発コンテナ上に環境変数を設定してあげればok

export CGO_ENABLED=0
Sut103Sut103

開発コンテナの設定として書いてしまって良さそう。

devcontainer.json
"containerEnv": {
		"CGO_ENABLED":"0"
	}
このスクラップは2023/07/20にクローズされました