M1 (M2) Mac上のDockerコンテナでChromeを動かす方法 2023年版

# はじめに

Intel Macで動作していたDocker利用のアプリケーションがM2に換えてから動かなくなりました🚑
アプリケーション内ではGoogle Chrome（Chrome）を利用しており、Python × Seleniumから利用しています。

結論から言うとDocker Desktop for MacのBeta機能`Use Rosetta for x86/amd64 emulation on Apple Silicon`を使うことで解消できました👨‍💻

:::note info
こちらの機能は2023年1月にリリースされました。これより以前の「AppleシリコンMac上でChromeとDockerを動かす」系記事を読む際には時系列をご留意いただくと良いかもしれません。
:::

## 環境
- Apple M2 Max / macOS Ventura
- Docker Desktop for Mac 4.16.2

## Dockerfileの構成とエラー

```Dockerfile:Dockerfile.example
FROM foo

# ...

RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
RUN apt-get -y update
RUN apt-get install -y google-chrome-stable

# ...
```

```sh:エラー
# コンテナ起動後アプリケーション内のChrome利用箇所でクラッシュ
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: crashed.
  (chrome not reachable)
  (The process started from chrome location /usr/bin/google-chrome-stable is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
```
どうもエラーの雰囲気として、Chromeプロセスがいないため落ちてそうです。

## 原因

少し話題が飛びますが、大前提としてDockerイメージは各CPUアーキテクチャに応じて作られます。
`docker pull`するとホストマシンのアーキテクチャに合わせたイメージが取得でき、Intel Macであれば`x86(amd64)`用が、Appleシリコンなら`arm64`用イメージが落ちてきます。

https://docs.docker.jp/docker-for-mac/multi-arch.html

ただし`arm64`向けがDocker Hub上に無い場合（例. [一昔前のMySQLイメージ](https://zenn.dev/tak848/articles/docker-mysql-arm64)）や、どうしても別CPUアーキテクチャのイメージが欲しい場合もあるかと思います。
その場合`platform`で別アーキテクチャを明示的に指定すれば取得することができます。
```docker-compose.yaml
# x86向けイメージが取得できる
platform: linux/x86_64
```

Docker Desktop for Mac内にはQEMUが同梱されているため異なるCPUアーキテクチャ向けイメージを動かせます。
QEMUとは何ぞや？という方はCPU等をエミュレートできる仕組みだとざっくり捉えてください。

https://valinux.hatenablog.com/entry/20230112

さてここからが本題です。
`arm64`向けのChromeバイナリは[現在提供されていない](https://github.com/SeleniumHQ/docker-selenium/issues/1076#issuecomment-1001055386)ため、AppleシリコンMacにてChromeを動かすためには`x86`向けのイメージ上で、`x86`向けのChromeを動かす必要があります。

ところが（Docker Desktop for Macにおける）QEMUは飽くまで[ベストエフォート動作](https://please-sleep.cou929.nu/clear-understandings-running-container-on-arm64.html)であるため時に不具合が発生します。
今回もQEMU起因でChromeがうまく立ち上がらないことがエラー原因になっているようです。

>ここで問題があり、QEMUのエミュレーションは完璧ではありません。一部の命令がサポートされておらず、それを使用するイメージは実行時にSegmentation Faultで終了します。
>
>Google Chromeもこれに該当し、M1 Macのlinux/amd64上で動かした場合には動作しません。
>
>[M1 MacのDockerでChromiumを使ったFeature Specを動かす](https://tech.gunosy.io/entry/docker_chromium_with_m1)

>Prior to this feature, the only option for running x86-based Docker images on Macs with Apple Silicon processors was through QEMU emulation, which could often result in compatibility issues and runtime crashes with particular images. However, with the integration of Rosetta 2 support, users can now expect a smoother experience when running their x86-based Docker images on Apple Silicon Mac systems.
>
>[Docker on Apple Silicon Mac: How to Run x86 Containers with Rosetta 2](https://levelup.gitconnected.com/docker-on-apple-silicon-mac-how-to-run-x86-containers-with-rosetta-2-4a679913a0d5)

## 解決策

4.16以降のDocker Desktop for MacにはQEMUの代わりにRosettaでエミュレートする機能が追加されています。
こちらをONにすることで正常に実行できました！

>現地時間2023年01月12日にDocker, Inc.が公開した「Docker Desktop for Mac v4.16」では、この新機能を利用し、macOS 13 Ventura以降のApple Silicon Mac上で、IntelベースのDockerイメージをエミュレートする機能がBetaサポートされているそうです。
>
>[macOS 13 VenturaのRosetta for Linuxを利用し、IntelベースイメージをApple SiliconでエミュレートすることをBetaサポートした「Docker Desktop v4.16」がリリース。](https://applech2.com/archives/20230114-docker-for-mac-support-rosetta-2-beta.html)

設定方法は至ってシンプルで`Docker Desktop > Dashboard > 設定(歯車アイコン) > Use Rosetta for x86/amd64 emulation on Apple Silicon`にチェックを入れます。
合わせて`設定 > General > Use Virtualization framework`にもチェックを入れておきましょう（こちらはデフォでチェック入っていると思います）。
Applyすると再起動するかと思いますので`docker compose up`なりで実行してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287774/5aaec22e-4dfb-75df-f7d7-b5e5d8ce299c.png)

## 終わりに

AppleシリコンMac上のDockerコンテナでChromeを動かす方法をまとめました。
Rosettaの利用でQEMU特有のバグを踏みづらくなるだけでなくパフォーマンスの向上も期待できるとのことです。

>Additionally, as Rosetta 2 is specifically designed by Apple for the macOS operating system and thanks to the optimizations Apple has integrated into its Apple Silicon CPUs, it is expected to provide improved performance and compatibility compared to QEMU emulation.
>
>[Docker on Apple Silicon Mac: How to Run x86 Containers with Rosetta 2](https://levelup.gitconnected.com/docker-on-apple-silicon-mac-how-to-run-x86-containers-with-rosetta-2-4a679913a0d5)

今回はDocker Desktop for Macを使いましたが、[様々な事情](https://www.itmedia.co.jp/news/articles/2201/31/news096.html)でRancher Desktop等を利用する場合もあるかと思いますので、その周辺もできれば調査したいと思います。