GitHub Actions上でARMを利用するDockerを使った方法
やりたいこと
やりかた
やり方はdocker runする前に以下のdocker/setup-qemu-actionをするだけ。
code:yml
...
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- run: |
docker run --rm -i -v $PWD:/ws arm32v7/ubuntu:18.04 bash <<'EOF'
set -xeu
cd /ws
uname -a
apt update
EOF
参考:
docker runについて
docker run以降にARM上で動かしたい処理を書いている。
docker run --rm -i -v $PWD:/ws arm32v7/ubuntu:18.04 bash <<'EOF'は、複数行を実行するために<<'EOF'をしている。シングルクォート'にする理由は内部の文字列に$MY_ENVのような文字列があったときにコンテナ外部のホスト環境の環境変数を取り込まないようにするため。そういう意図はあっても良いが行数が増えると保守しづらくなる。ホスト環境の環境変数を渡したい時はdocker runの-eで明示的に渡す。
またカレントディレクトリをコンテナ内で利用するために-v $PWD:/wsにして、EOF内でcd /wsしている。
set -xeuはなくても好みでつけておりなくても良い。オプションの説明としては-xで実行するコマンドの表示、-eはexit codeが0ではない時に終了させるため、-uは未定義の環境変数を利用したときにエラーさせる。
実際のログ
以下が実際のGitHub Actionsのログだが、uname -aのところで「... armv7l armv7l armv7l ...」と表示されていることが確認できる。
https://scrapbox.io/files/616b7a44d2b72e001d1bd668.png
arm64v8/ubuntu:18.04も動くことを確認した。
実際のworkflow
実際のGitHub Actionsのworkflowは以下にある。
おまけ: 詳細
上記まででやり方の説明は完了。もう少し詳細の説明。
ARM向けのDockerイメージに関しては、以下のDocker公式にあるように、https://hub.docker.com/u/arm32v6/、arm32v7/、arm64v8/は公式がサポートしている。
仮にdocker/setup-qemu-actionをしない場合はdocker run実行時に「 standard_init_linux.go:228: exec user process caused: exec format error」というエラーが出てdocker runが実行できた。
以下はDocker for Macの説明ではあるが、qemu-staticでamd64 (x64)でもARM向けのDockerイメージを実行することができる。 Docker for Mac 仮想マシン が qemu-static を使うので、コンテナ内で特別な設定は不要です。これにより、 busybox イメージの arm32v7 や ppc64le に対応した ARM コンテナを実行可能です。
Dockerイメージarm32v7/ubuntu:18.04を使う意外の方法として、
docker run --platform linux/arm/v7 ...のように--platformを指定することが出来る。つまり以下のように実行できる。
code:yml
- run: |
docker run --platform linux/arm/v7 -i -v $PWD:/ws ubuntu:18.04 bash << EOF
...
EOF
おそらく、上記の--platformは、Docker HubのTagsの「OS/ARCH」と対応しているのだと思う。
https://scrapbox.io/files/616b7f10b52058001de2ab42.png
おまけ: 経緯
GitHub ActionsでARMの環境が欲しくなった経緯について。
Piping ServerのポータブルなARMのバイナリも自動化してGitHub Releasesで提供したくなり、CI上にARM環境が必要になった。arm32v7/node:14というNode.jsのARMのDockerイメージがあるのでそれを利用した。 以下がARMバイナリを生成するための実際のコミット:
vercel/pkgでARM対応するにはarm64を指定するが、arm64でもarm32v7/ubuntu:18.04のようなarm32で動くのはどういうことなのかまだ不明。