Intel Macで動作するDockerのNodeアプリを Apple Silicon Mac (M1) で動かすためにやったこと
Intel Mac で動作する Dockerfile を、Apple Silicon Mac (M1) で利用したら、イメージのビルドが失敗したり、docker 内の node のアプリ (react, gatsby, puppeteer) が動作しなくなったりしたので、その際に行った対処を書き残す。
サマリ
- node のイメージタグを
*-buster
に変更する。 xdg-utils
をインストールする。- (puppeteer を使う場合のみ)
- chromium をインストールする。
- node のイメージタグを
*-alpine
に変更する。
元ファイル
Intel Mac では動作する Dockerfile。
FROM node:14.17.0-slim # Localize into Japanese RUN apt-get update \ && apt-get install -y locales \ && locale-gen ja_JP.UTF-8 \ && echo "export LANG=ja_JP.UTF-8" >> ~/.bashrc # Install Chrome (only to use for puppeteer) RUN apt-get install -y wget gnupg \ && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ && apt-get update \ && apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \ --no-install-recommends # Install wget and curl RUN apt-get install -y \ wget \ curl \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
発生したエラー
spawn xdg-open ENOENT
npx create-react-app [project name] --template typescript
が完了後、npm start
コマンド実行時に以下が発生。
events.js:353 throw er; // Unhandled 'error' event ^ Error: spawn xdg-open ENOENT at Process.ChildProcess._handle.onexit (internal/child_process.js:269:19) at onErrorNT (internal/child_process.js:467:16) at processTicksAndRejections (internal/process/task_queues.js:82:21) Emitted 'error' event on ChildProcess instance at: at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12) at onErrorNT (internal/child_process.js:467:16) at processTicksAndRejections (internal/process/task_queues.js:82:21) { errno: -2, code: 'ENOENT', syscall: 'spawn xdg-open', path: 'xdg-open', spawnargs: [ 'http://localhost:3000' ] } npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! front@0.1.0 start: `react-scripts start` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the front@0.1.0 start script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /home/node/.npm/_logs/2022-04-10T07_46_46_139Z-debug.log
一部の deb パッケージが 404 Not Found
上記エラーの xdg-open
は xdg-utils
パッケージに内包されているので、Dockerfile に RUN apt-get install -y xdg-utils
を追加してみたが、docker compose build
コマンド実行時に以下が発生。
E: Failed to fetch http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.1_1.1.0l-1~deb9u4_arm64.deb 404 Not Found [IP: 151.101.2.132 80] E: Failed to fetch http://security.debian.org/debian-security/pool/updates/main/o/openssl/openssl_1.1.0l-1~deb9u4_arm64.deb 404 Not Found [IP: 151.101.2.132 80] E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing? 1 error occurred: * Status: The command '/bin/sh -c apt-get install -y xdg-utils' returned a non-zero code: 100, Code: 100
調べてみると、元としているイメージ node:14.17.0-slim
は、debian の通称 "stretch" (Debian 9) から作られているが、debian の現在の安定版は "buster" (Debian 10) とのこと。
https://www.debian.org/releases/index.ja.html
ついでに node のバージョンもアップデートしたいので、イメージとして node:16.14.2-buster-slim
を選択してみた。
再度 docker compose build
を実行するとエラーは出ず、npm start
で問題なくアプリが起動した。
chrome がインストールできない
Puppeteer を実行するためにはコンテナに chrome をインストール必要があるが、docker compose build
コマンド実行時に以下が発生。
E: Package 'google-chrome-stable' has no installation candidate
現状、arm64 Linux 用の Chrome は存在しない模様。代わりに chromium を使う必要があるとのこと。
https://askubuntu.com/questions/1383789/install-chrome-on-ubuntu-debian-with-arm64
そこで、Dockerfile を以下のように書き換えて、
... # Install Chrome (only to use for puppeteer) RUN apt-get install -y chromium chromium-browser ...
再度 docker compose build
コマンド実行すると以下が発生。
E: Package 'chromium-browser' has no installation candidate
これに対して、snap コマンドを使ってインストールする方法がありそうだが、debian で Chromium を動かすことがあまり推奨されていないとのこと。
https://forum.pine64.org/showthread.php?tid=12497
特に Debian であることに拘りも無いため、alpine 版の node に chromium を追加して利用することにした。こちらは以下の追加のみで、pupeteer が問題なく動作した。
FROM node:16.14.2-alpine3.14 RUN apk add chromium ...
変更後のファイル
Docker on Apple Silicon Mac (M1) で動作確認済み。
通常用
FROM node:16.14.2-buster-slim RUN apt-get update \ && apt-get install -y locales \ && locale-gen ja_JP.UTF-8 \ && echo "export LANG=ja_JP.UTF-8" >> ~/.bashrc # 追加部分 RUN apt-get install -y xdg-utils RUN apt-get install -y \ wget \ curl \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
Puppeteer 用
# apt系 (Debian) から apk系 (alpine) に全面書き換え FROM node:16.14.2-alpine3.14 ENV TZ=Asia/Tokyo ENV LANG=C.UTF-8 RUN apk update \ && apk add chromium \ && apk add bash tzdata wget curl