この投稿は、最初の記事を基にして、AWS SAM と Go を使用したアプリの構築 シリーズの続きです。 前の章では、冗長なコードを使用せずにスケーラブルな Go プロジェクトを構築するための AWS の限定的なガイダンスを強調しました。
この記事では、Dockerfile と Makefile を使用してビルド プロセスを管理する手法を説明します。
付属のコードは、https://www.php.cn/link/5655cf23be4dda7082c8bb3a8d8f8016から入手できます。 さまざまなユースケースに応じて、さまざまな Git ブランチを調べてください。
始めましょう!
新しいプロジェクト構造を開発した後、依存関係管理 (言語、ツール、ライブラリ) に Nix を選択しました。 Nix は、指定された依存関係を持つ一時シェルを作成することで動作します。
Nix シェル内でビルドされたバイナリを実行中にエラーが発生しました:
<code>libc.so.6 not found in /nix/23fj39chsggb09s.libc</code>
これにより、Lambda の実行が停止しました。 デバッグにより根本原因が明らかになりました。Go は、システム パスを指定して、C ライブラリを実行可能ファイルに動的にリンクすることがあります。 Nix で構築された実行可能ファイルにリンクされているライブラリは次のとおりです:
<code>$ ldd bootstrap linux-vdso.so.1 (0x00007ffff7fc4000) libresolv.so.2 => /nix/store/65h17wjrrlsj2rj540igylrx7fqcd6vq-glibc-2.40-36/lib/libresolv.so.2 (0x00007ffff7fac000) libpthread.so.0 => /nix/store/65h17wjrrlsj2rj540igylrx7fqcd6vq-glibc-2.40-36/lib/libpthread.so.0 (0x00007ffff7fa7000) libc.so.6 => /nix/store/65h17wjrrlsj2rj540igylrx7fqcd6vq-glibc-2.40-36/lib/libc.so.6 (0x00007ffff7c00000) /nix/store/65h17wjrrlsj2rj540igylrx7fqcd6vq-glibc-2.40-36/lib/ld-linux-x86-64.so.2 => /nix/store/65h17wjrrlsj2rj540igylrx7fqcd6vq-glibc-2.40-36/lib64/ld-linux-x86-64.so.2 (0x00007ffff7fc6000)</code>
Nix の非標準依存関係ストレージは、Lambda の分離された Docker コンテナと組み合わされて、Lambda がこれらのライブラリを見つけるのを妨げました。これらのライブラリはローカルの Nix インストールにのみ存在したためです。 コードをコンパイルし、ライブラリのリンクを管理する方法を AWS SAM に指示するためのソリューションが必要でした。
2 つの展開方法が存在します:
ローカルでコンパイルし、実行可能ファイルを .zip ファイルで AWS に送信します。 AWS は実行可能ファイルを Docker コンテナにコピーします。これにより、コールドスタートが最速になります。
実行 Docker コンテナ内でコンパイルする手順を AWS に提供します。これにより互換性が確保されますが、コールド スタートが遅くなります。
Nix の使用を続けるために Dockerfiles を選択しましたが、両方の方法を以下に示します。
Zip ファイルの場合は、次のプロジェクト構造を使用します (Makefile に注意してください):
<code>. ├── cmd/ │ ├── function1/ │ │ └── function1.go # contains main() │ └── function2/ │ └── function2.go # contains main() ├── internal/ │ └── SHAREDFUNC.go ├── Makefile ├── go.mod ├── go.sum ├── samconfig.toml └── template.yaml</code>
Makefile は、build-<function_name>
パターン (AWS SAM で必要) を使用して各関数のビルド コマンドを定義します。
<code>.PHONY: build build: sam build build-HelloWorldFunction: GOARCH=amd64 GOOS=linux go build -tags lambda.norpc -o bootstrap ./cmd/function1/main.go cp ./bootstrap $(ARTIFACTS_DIR) build-ByeWorldFunction: GOARCH=amd64 GOOS=linux go build -tags lambda.norpc -o bootstrap ./cmd/function2/main.go cp ./bootstrap $(ARTIFACTS_DIR)</code>
SAM にこのプロセスを通知します:
<code> HelloWorldFunction: Type: AWS::Serverless::Function Metadata: BuildMethod: makefile Properties: CodeUri: ./ Handler: bootstrap Runtime: provided.al2023 Architectures: - x86_64 Events: CatchAll: Type: Api Properties: Path: /hello Method: GET</code>
BuildMethod: makefile
は、CodeUri
が指定する場所にある Makefile を使用するように SAM に指示します。
ルート ディレクトリに Dockerfile
と .dockerignore
を作成します:
<code>. ├── cmd/ │ ├── function1/ │ │ └── function1.go # contains main() │ └── function2/ │ └── function2.go # contains main() ├── internal/ │ └── SHAREDFUNC.go ├── Dockerfile ├── .dockerignore ├── go.mod ├── go.sum ├── samconfig.toml └── template.yaml</code>
Dockerfile
はビルドステップを指定します。 ARG ENTRY_POINT
は、ビルド時のラムダ エントリ ポイントを指定します:
<code>FROM public.ecr.aws/docker/library/golang:1.19 as build-image ARG ENTRY_POINT # !IMPORTANT WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -tags lambda.norpc -o lambda-handler ${ENTRY_POINT} FROM public.ecr.aws/lambda/provided:al2023 COPY --from=build-image /src/lambda-handler . ENTRYPOINT ./lambda-handler</code>
template.yaml
を変更します:
<code>libc.so.6 not found in /nix/23fj39chsggb09s.libc</code>
Metadata
と PackageType: Image
に注意してください。 DockerBuildArgs
は ENTRY_POINT
から Dockerfile
を渡し、すべてのラムダに対して単一の Dockerfile
を許可します。
この詳細な説明では、Zip ファイルと Docker イメージの両方を使用して AWS SAM 内で Go ビルドを管理するための包括的なアプローチを提供します。 どちらを選択するかは、ビルド速度と展開の一貫性の優先順位によって決まります。
以上がDockerfile と Makefile を使用して AWS SAM で Go Build をカスタマイズするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。