M1 Mac の Docker 動作確認

11 min read読了の目安(約10600字

やってみること

M1 Mac のDockerを確認してみる。確認してみるのは過去記事で取り扱った以下のもの。

  • Rails + Postgress
  • Wordpress
  • React

現状まとめ(2021/4/5時点)

  • 2021/04/01 に Docker Desktop RC 3がリリース
  • 今回動かした限りでは、Docker自体の問題はない
    • ただし gem や docker hub にあるイメージが対応してない場合がある
    • mysql とかはしばらくすれば対応されるだろうけど、 gem は厳しいものもありそう。このあたりは実際に業務で遭遇すると厳しい場合もあると思うので、M1 Mac で安心して開発を勧められる世界線は、もう少し先かも

環境

  • MacBook Air (M1, 2020)

インストール

プレビュー

https://matsuand.github.io/docs.docker.jp.onthefly/docker-for-mac/apple-m1/

ダウンロード: https://desktop.docker.com/mac/stable/arm64/62632/Docker.dmg

Rails + Postgres

以前書いた記事の内容が使えるか確認。

https://zenn.dev/mochiblock/articles/aaa4724c6267e6
簡単に必要なファイルを以下に列挙する。

Dockefile

Dockerfile
FROM ruby:3.0.0

ENV APP=/app
RUN mkdir -p ${APP}

WORKDIR ${APP}
COPY Gemfile Gemfile.lock ${APP}/

RUN set -x && \
    apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y --no-install-recommends curl less sudo

ENV LANK=C.UTF-8
RUN echo 'Asia/Tokyo' > /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata

ENV ENTRYKIT_VERSION 0.4.0
RUN set -x && \
    curl -sL https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz | tar zx -C /usr/local/bin --no-same-owner --no-same-permissions && \
    entrykit --symlink

ENV DOCKERIZE_VERSION v0.6.1
RUN set -x && \
    curl -sL https://github.com/jwilder/dockerize/releases/download/${DOCKERIZE_VERSION}/dockerize-linux-amd64-${DOCKERIZE_VERSION}.tar.gz | tar zx -C /usr/local/bin --no-same-owner --no-same-permissions

ENV DEPENDENCY="nodejs libpq-dev libsqlite3-dev libssl-dev libgeos-dev" \
    DEV_DEPENDENCY="build-essential"
ENV YARN_VERSION=1.22.4
RUN set -x && \
    curl -sL https://deb.nodesource.com/setup_15.x | bash - && \
    apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends ${DEPENDENCY} ${DEV_DEPENDENCY} && \
    bash -c "curl -sL --compressed https://yarnpkg.com/downloads/${YARN_VERSION}/yarn-v${YARN_VERSION}.tar.gz | tee >(tar zx -C /usr/local/ --strip=1 --wildcards yarn*/bin --no-same-owner --no-same-permissions) | tar zx -C /usr/local/ --strip=1 --wildcards yarn*/lib --no-same-owner --no-same-permissions" && \
    bundle install -j4 && \
    apt-get purge -y ${DEV_DEPENDENCY} && \
    apt-get autoremove -y && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
    truncate -s 0 /var/log/*log

COPY . ${APP}

CMD ["bin/rails", "s", "-b", "0.0.0.0"]

docker-compose.yml

docker-compose.yml
version: '3'
services:
  web:
    build: .
    command: ["bin/rails", "s", "-b", "0.0.0.0"]
    depends_on:
      - db
    entrypoint:
      [
        "prehook",
          "dockerize -wait tcp://db:5432 -timeout 60s",
          "rm -f /app/tmp/pids/server.pid",
          "--"
      ]
    ports:
      - "3000:3000"
    volumes:
      - .:/app:cached
      - /app/vendor
      - /app/tmp
      - /app/log
      - /app/.git
  db:
    image: postgres:13
    environment:
      POSTGRES_USER: "${DATABASE_USER:-foo}"
      POSTGRES_PASSWORD: "${DATABASE_PASS:-bar}"
    volumes:
      - db:/var/lib/postgresql/data:cached
    ports:
      - "5432:5432"
volumes:
  db:

エラー

entrykitで落ちる

docker-compose run --rm web rails new . --api --force --database=postgresql --skip-turbolinks --skip-test した時に以下のエラーが発生。

Step 10/17 : RUN set -x &&     curl -sL https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz | tar zx -C /usr/local/bin --no-same-owner --no-same-permissions &&     entrykit --symlink
 ---> Running in 6957f9f1c359
+ curl -sL https://github.com/progrium/entrykit/releases/download/v0.4.0/entrykit_0.4.0_Linux_x86_64.tgz
+ tar zx -C /usr/local/bin --no-same-owner --no-same-permissions
+ entrykit --symlink
runtime: failed to create new OS thread (have 2 already; errno=22)
fatal error: newosproc

runtime stack:
runtime.throw(0x84a820, 0x9)
	/usr/local/go/src/runtime/panic.go:527 +0x90
runtime.newosproc(0xc820028000, 0xc820037fc0)
	/usr/local/go/src/runtime/os1_linux.go:150 +0x1ab
runtime.newm(0x8e5980, 0x0)
	/usr/local/go/src/runtime/proc1.go:1105 +0x130
runtime.main.func1()
	/usr/local/go/src/runtime/proc.go:48 +0x2c
runtime.systemstack(0xa2b6e0)
	/usr/local/go/src/runtime/asm_amd64.s:262 +0x79
runtime.mstart()
	/usr/local/go/src/runtime/proc1.go:674

goroutine 1 [running]:
runtime.systemstack_switch()
	/usr/local/go/src/runtime/asm_amd64.s:216 fp=0xc820022770 sp=0xc820022768
runtime.main()
	/usr/local/go/src/runtime/proc.go:49 +0x62 fp=0xc8200227c0 sp=0xc820022770
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1696 +0x1 fp=0xc8200227c8 sp=0xc8200227c0
ERROR: Service 'web' failed to build : The command '/bin/sh -c set -x &&     curl -sL https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz | tar zx -C /usr/local/bin --no-same-owner --no-same-permissions &&     entrykit --symlink' returned a non-zero code: 2

エラーに対しての結論

詳しくはこちらの「entrykitがM1 mac(Apple Silicone)で実行できないときの対処法」という記事を見ると

  • entrykit本当にいるのかどうかよく考える
  • Multi stage build で代用する

ということで今回は動作確認ができればいいので、entrykit は使わない方向で進めた。

stdin: unexpected end of file

よくわからないけど、tarで落としてきた yarnが解凍出来なかった。

Setting up libgeos-dev (3.7.1-1) ...
Processing triggers for libc-bin (2.28-10) ...
+ bash -c curl -sL --compressed https://yarnpkg.com/downloads/1.22.4/yarn-v1.22.4.tar.gz | tee >(tar zx -C /usr/local/ --strip=1 --wildcards yarn*/bin --no-same-owner --no-same-permissions) | tar zx -C /usr/local/ --strip=1 --wildcards yarn*/lib --no-same-owner --no-same-permissions

gzip: stdin: unexpected end of file
tar: Child returned status 1
tar: Error is not recoverable: exiting now

gzip: stdin: unexpected end of file
tar: Child returned status 1
tar: Error is not recoverable: exiting now
ERROR: Service 'web' failed to build : The command '/bin/sh -c set -x &&     curl -sL https://deb.nodesource.com/setup_15.x | bash - &&     apt-get update &&     DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends ${DEPENDENCY} ${DEV_DEPENDENCY} &&     bash -c "curl -sL --compressed https://yarnpkg.com/downloads/${YARN_VERSION}/yarn-v${YARN_VERSION}.tar.gz | tee >(tar zx -C /usr/local/ --strip=1 --wildcards yarn*/bin --no-same-owner --no-same-permissions) | tar zx -C /usr/local/ --strip=1 --wildcards yarn*/lib --no-same-owner --no-same-permissions" &&     bundle install -j4 &&     apt-get purge -y ${DEV_DEPENDENCY} &&     apt-get autoremove -y &&     rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* &&     truncate -s 0 /var/log/*log' returned a non-zero code: 2

あれこれやろうと考えたけど、面倒だったので無理矢理 apt-get install で入れることにした。

最終的なDockerfile, docker-compose.yml

最終的なDockerfile, docker-compose.yml は以下のようになった。

Dockerfile

Dockerfile
FROM ruby:3.0.0

ENV APP=/app
RUN mkdir -p ${APP}

WORKDIR ${APP}
COPY Gemfile Gemfile.lock ${APP}/

RUN set -x && \
    apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y --no-install-recommends curl less sudo

ENV LANK=C.UTF-8
RUN echo 'Asia/Tokyo' > /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata

ENV DOCKERIZE_VERSION v0.6.1
RUN set -x && \
    curl -sL https://github.com/jwilder/dockerize/releases/download/${DOCKERIZE_VERSION}/dockerize-linux-amd64-${DOCKERIZE_VERSION}.tar.gz | tar zx -C /usr/local/bin --no-same-owner --no-same-permissions

ENV DEPENDENCY="nodejs libpq-dev libsqlite3-dev libssl-dev libgeos-dev yarn" \
    DEV_DEPENDENCY="build-essential"
RUN set -x && \
    curl -sL https://deb.nodesource.com/setup_15.x | bash - && \
    apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends ${DEPENDENCY} ${DEV_DEPENDENCY} && \
    bundle install -j4 && \
    apt-get purge -y ${DEV_DEPENDENCY} && \
    apt-get autoremove -y && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
    truncate -s 0 /var/log/*log

COPY . ${APP}

CMD ["bin/rails", "s", "-b", "0.0.0.0"]

docker-compose.yml

docker-compose.yml
version: '3'
services:
  web:
    build: .
    command: ["bin/rails", "s", "-b", "0.0.0.0"]
    depends_on:
      - db
    ports:
      - "3000:3000"
    volumes:
      - .:/app:cached
      - /app/vendor
      - /app/tmp
      - /app/log
      - /app/.git
  db:
    image: postgres:13
    environment:
      POSTGRES_USER: "${DATABASE_USER:-foo}"
      POSTGRES_PASSWORD: "${DATABASE_PASS:-bar}"
    volumes:
      - db:/var/lib/postgresql/data:cached
    ports:
      - "5432:5432"
volumes:
  db:

結論

上記の内容で rails s で起動できる。ただ、gemによってはうまく動かない・使えないということは往々にありそうなので、そこはその都度対応することになりそう。

Wordpress

以前書いた記事内容を出来るかやってみる。

https://zenn.dev/mochiblock/articles/0fc6bd37320080
試してみる docker-compose.yml は以下の通り。
docker-compose.yml
version: '3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     # ドキュメントに書いてある内容に、vlumesの部分だけ追記(任意)
     volumes:
       - .:/var/www/html
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:

エラー

docker-compose up をしてみたが、以下のようなエラーが出た。

❯ docker-compose up
Docker Compose is now in the Docker CLI, try `docker compose up`

Creating network "wordpress_test_default" with the default driver
Creating volume "wordpress_test_db_data" with default driver
Pulling db (mysql:5.7)...
5.7: Pulling from library/mysql
ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries

調べてみると同じことをして、同じエラーが出ている人を発見。

https://qiita.com/Nerosui777/items/dfef9612e4bbb86af3b5

改めて mysql の docker hub を見てみたが、現状(2021/04/05時点) ではまだarmには対応していない。
記事通り mariadb にしてみたら動いた。

結論

mysqlはまだarmに対応していない。

React

以前書いたこの記事通りやっていく

https://zenn.dev/mochiblock/articles/3af073ff13c6e2
使う Dockerfile と docker-compose.yml は以下の通り
Dockerfile
FROM node:15.10-alpine3.13

ENV APP=/app
RUN mkdir -p ${APP}

WORKDIR ${APP}
docker-compose.yml
version: '3'

services:
  app:
    build: .
    command: [yarn, start]
    ports:
      - '8080:8080'
    volumes:
      - .:/app:cached

結論

特に問題なし