Hateburo: kazeburo hatenablog

SRE / 運用系小姑 / Goを書くPerl Monger

PerlなプロジェクトをGithub Actionsでコンテナ化 (ARM64対応)

この記事は Perl Advent Calendar 2021 の6日目の記事です。

業務では日頃はGo、PerlPHPを使ってクラウドのバックエンドを作り、JavaScript/TypeScriptでフロントエンドを作っています

この記事は昔からherokuで動かしていたサービスをコンテナ化してGraviton2なEC2インスタンス上でk3sでシングルサーバクラスタを作成して動かしているよという紹介です。

対象は以下の2つ

tanzak.nomadscafe.jp

corelist.nomadscafe.jp

それぞれのGitHubのrepositoryはこちら

このサービスで使うDockerコンテナはGitHub Actionsで作成し、GitHubのContainer Registoryにあげています。

サーバがGraviton2なので、ARM64に対応したコンテナが必要となりますが、それもGitHub Actionsでビルドしています。

Dockerfile の用意

Perlの公式コンテナイメージは多くののプラットフォームをサポートし、ARM64にも対応しています。

hub.docker.com

f:id:kazeburo:20211206114527p:plain

なのでこれを元にするDockerfileを作成しました。

tanzakではこんな感じ

FROM perl:5.32
RUN mkdir -p /opt/app
RUN cpanm -n Carton
COPY ./cpanfile /opt/app/cpanfile
COPY ./cpanfile.snapshot /opt/app/cpanfile.snapshot
WORKDIR /opt/app
RUN carton install --deployment
EXPOSE 5000
COPY . /opt/app
CMD carton exec -- plackup -s Starlet --max-workers=3 --port 5000 -a app.psgi

workflowファイル

そしてDockerビルドするGitHub Actionsのworkflowファイルはこんな感じです

name: Build and Publish Docker

on:
  push:
    branches:
      - master

jobs:
  build_and_push:
    runs-on: ubuntu-latest
    env:
      IMAGE_NAME: tanzak
    steps:
      - name: checkout
        uses: actions/checkout@v2

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.CR_PAT }}

      - name: Get short SHA
        id: slug
        run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)"

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          push: true
          platforms: linux/amd64,linux/arm64
          tags: |
            ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest
            ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ steps.slug.outputs.sha8 }}

マルチアーキテクチャのビルドをするために、 docker/setup-qemu-action および docker/setup-buildx-action を利用し、docker/build-push-action で platformsとして linux/amd64,linux/arm64 を指定しています。

これでビルドはできました。

GitHub Container Registoryでも、amd64/arm64の2つのアーキテクチャでイメージが上がっているのが確認できます。

f:id:kazeburo:20211206114949p:plain

https://github.com/kazeburo/tanzak/pkgs/container/tanzak

はげしく便利ではあるのですが、すごーく時間がかかります

f:id:kazeburo:20211206114912p:plain

まとめ

PerlなプロジェクトでもGitHub Actionsを使いARM64のDockerイメージがビルドできました。これで昔々から動かしているサービスでもGraviton2の恩恵を受けてお安く運用できてます。

Graviton2を採用したAWSのEC2はx86系と比較して20%安くなっているとされています。各種マネージドサービスもそろってきました。開発環境やテスト環境がx86の場合の課題もありますが、うまく使っていけるとよさそうです。