AWS Amplifyでカスタムビルドイメージを使う(2023年以降版)

AWS Amplifyを使っていると気になってくるのがビルドの速度です。

デフォルトで用意されているイメージは汎用的に作られているためイメージも重くビルドには時間がかかってしまいます。

しかしAmplifyでは自身で構築したDockerイメージをビルドに用いることができます。自分に必要な最小限の構成で、かつ必要なランタイムのバージョンを最初からインストールしておくことができ、ビルド時間を短縮することができそうです。

今回は実際に本サイトをビルドするためのカスタムビルドイメージ作成を例に取り、ローカルでHugoを動作させるDockerイメージを作りそれをECRのパブリックリポジトリに登録してAmplifyから使う手順を紹介します。

従来の方法

Amplifyのカスタムビルドイメージは、以前は公式のGitHubリポジトリにてテンプレートが公開されており、それを元にしてカスタムイメージを作る方法が案内されていました。しかしこの方法は現在は非推奨となっています。

以下を見ると2023年5月に非推奨としてサンプルのDockerfileは取り下げられ、Deprecated(非推奨)という扱いになったようです。

でかでかと書かれたDEPRECATEDの文字

参考: Commit diff

今は以下の公式ドキュメントで別の手順が紹介されているため、今回はこちらに沿って行っていこうと思います。

Dockerイメージの作成

Docker環境の準備

まずはローカルでDockerイメージをビルドするための環境を整えます。これは各環境に依存しますので各自でふさわしい方法を探して構築してください。

Dockerfileの準備

次にDockerfileを準備します。以下は本サイトをビルドするためのHugoの環境を作るDockerfileです。軽量化のためにマルチステージビルドを行っています。

FROM --platform=linux/x86_64 public.ecr.aws/amazonlinux/amazonlinux:2023.3.20240131.0 AS builder

USER root
ENV HOME=/root

###########################
#   Install OS packages   #
###########################

RUN dnf -y update && \
    dnf -y install \
        git \
        gcc-c++ \
        tar \
        wget && \
    dnf clean all

######################
#   Install golang   #
######################

ENV GO_PACKAGE_NAME=go1.21.6.linux-amd64.tar.gz
RUN wget https://go.dev/dl/${GO_PACKAGE_NAME} && \
    tar -C /usr/local -xzf ${GO_PACKAGE_NAME} && \
    rm ${GO_PACKAGE_NAME}
ENV PATH=$PATH:/usr/local/go/bin:${HOME}/go/bin

####################
#   Install Hugo   #
####################

ENV CGO_ENABLED=1
RUN go install -tags extended github.com/gohugoio/hugo@v0.122.0 && \
    go clean --modcache

##########################
#   Second Stage Build   #
##########################

FROM --platform=linux/x86_64 public.ecr.aws/amazonlinux/amazonlinux:2023.3.20240131.0-minimal

RUN dnf -y install git && \
    dnf clean all

COPY --from=builder /root/go/bin/hugo /usr/local/bin/

ENTRYPOINT [ "bash", "-c" ]

まずはカスタムビルドイメージで必要なものとして以下があります。

  • x86_64のLinuxイメージ
  • cURL
  • Git
  • OpenSSH
  • Bash and The Bourne Shell

参考: https://docs.aws.amazon.com/amplify/latest/userguide/custom-build-image.html

ドキュメントではNode.JS+NPMも強く推奨されていますが、今回の場合は無くても動くので入れていません。

ここで注意ですがFROMで指定したイメージにx86_64とarm64のバリエーションがある場合、ビルドする環境に応じて自動的に選ばれるようです。私はArm環境(M1 Mac)だったため以下のようなエラーが出てしまいました。

gcc: error: unrecognized command-line option '-m64'

なのでFROMに明示的に --platform=linux/x86_64 をつけています。

Hugo特有の設定

以下はHugoのビルドのために必要な内容です。違うフレームワークを使う場合はそれぞれに合わせた方法を取ってください。

まずGoのインストールは以下に手順があります。

以下より適切なパッケージを選択します。今回はx86_64のLinuxなので linux-amd64 とあるものの中から選びます。

Hugoのインストールは公式の以下の手順に従いました。

Hugoには g++ コマンドが必要です。

g++: exec: "g++": executable file not found in $PATH

AmazonLinux2013ではyumで gcc-c++ というパッケージ名を指定すれば大丈夫です。

上記の例では私の環境で使っているバージョンである0.122.0を指定していますが、実際には各環境に合わせて必要なバージョンを指定してください。インストールされたHugoのバイナリは ${HOME}/go/bin に格納されるので忘れずにPATHに追加しておきます。

Dockerイメージのビルド

では作成したDockerfileを使ってイメージをビルドします。

ここでは amplify-build-hugo という名前で作成しますがここは自由につけてください。

docker build -t amplify-build-hugo-test - < Dockerfile

ECRリポジトリへの登録

Dockerイメージが作れたら次はそのイメージをAmplifyから使えるようにリポジトリへ登録します。ECR (Elastic Container Registry) の Public Repository に登録することで、Amplifyでのカスタムビルドイメージとして指定ができるようになります。

以下の手順に沿っていけばよいのでここでは簡単に記載するのみとします。

ECRでパブリックリポジトリの作成

Webコンソールから作成すればOKです。

この画面からリポジトリを作成する

リポジトリへPush

Webコンソールの「プッシュコマンドを表示」に丁寧に手順が記載されているのでその通りに実施すればOKです。必要あればバージョンタグは適宜変えましょう。

カスタムビルドイメージの指定

あとはAmplifyのビルドの設定からカスタムイメージを指定します。

ビルド設定の変更画面

これで、今後のビルドはさきほど作成したカスタムイメージにて行われるようになりました。

結果

実際に速くなったのかどうか確認してみましょう。

まず手元のDockerイメージは313MBでした。

REPOSITORY           TAG      IMAGE ID       CREATED          SIZE
amplify-build-hugo   latest   afeea12d5ca4   9 minutes ago    312MB

ECRの画面から見ると199.83MBとあります。圧縮されているということでしょうか。

ECRの画面

これだけ見てもなんとも言えないので、実際にデプロイまでの時間を見てみます。

最初はビルドイメージはAmazonLinux:2013、ライブパッケージアップデートでHugoのバージョンを指定していたところ 1分36秒 かかっていたのですが、カスタムイメージを用いたところ 35~40秒 程度まで短縮されました。約1分の短縮、約3分の1の時間になりました!(ただ、たまに1分10秒くらいかかるときもあるようです。Dockerイメージのキャッシュが効くかどうかなどコントロール外の要因がありそうです。)

NetlifyやVercelなど静的サイトホスティングに特化したサービスと比較するとまだまだ速いとは言えない感じかなと思いますが、デフォルトでかかる時間に比べれば許容範囲になってくるのではないでしょうか。

さらにミニマムなイメージを作ることでさらに速くなる可能性もありますが、作る手間もあるため一旦これぐらいにしておこうと思います。特に今回はgitを入れるのに手こずってdnfでのインストールにしてしまったのは悔やまれるポイントです。

より高速化することができた方はぜひコメントいただけると嬉しいです。

まとめ

AWS Amplifyのビルド時間を短縮するべくカスタムビルドイメージを作ることに挑戦しました。軽量なDockerイメージを作ることで約3分の1まで時間を短縮することができました。より高速化するポイントも探っていきたいですが、正直なところAWSさんにもぜひ改善を願いたいところです。

最終更新 2024-02-06

広告

本記事はお役に立てたでしょうか。本ブログでは匿名でのコメントや少額から(15円~)の寄付などを受け付けております。もしお役に立てたのであればご支援いただけると大変励みになります。

Built with Hugo
テーマ StackJimmy によって設計されています。