M1 MacでDocker環境を作った記録

M1 Mac向けのDockerが新しくなったので、インストールしてみました。
先月チャレンジした時はどうやっても動きませんでした。今度こそ！

#環境
MacBook Air (M1, 2020)
OS:Big Sur Ver11.2

#Dockerインストール
この記事から、[Apple M1チップ対応のDocker Desktop、同梱のKubernetesも実行可能に － Publickey](https://www.publickey1.jp/blog/21/apple_m1docker_desktopkubernetes.html)

Dockerの開発ブログに行って、[Apple Silicon Tech Preview | Docker Documentation](https://docs.docker.com/docker-for-mac/apple-m1/) `Docker Desktop RC 2`をダウンロードしました。

>Docker Desktop RC 2🔗
>2021-03-26

できたてほやほやですね！

Docker.dmgをダブルクリックして実行。アプリケーションにコピーして起動。

#エラーになった！

![スクリーンショット 2021-03-27 22.38.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872219/3dfdf8e9-b796-7fda-233d-663d2507b345.png)


```
[   14.057444] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
[   14.057511] Mem abort info:
[   14.057517]   ESR = 0x86000005
[   14.057568]   Exception class = IABT (current EL), IL = 32 bits
[   14.057608]   SET = 0, FnV = 0
[   14.057647]   EA = 0, S1PTW = 0
[   14.057674] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000ff152e3f
[   14.057705] [0000000000000000] pgd=00000000da451003, pud=0000000000000000
[   14.059417] Internal error: Oops: 86000005 [#1] PREEMPT SMP
[   14.059451] Modules linked in: xfrm_user xfrm_algo vmw_vsock_virtio_transport vmw_vsock_virtio_transport_common vsock
[   14.059493] Process 010-onboot (pid: 275, stack limit = 0x0000000028742d26)
[   14.059555] CPU: 2 PID: 275 Comm: 010-onboot Tainted: G                T 4.19.121-linuxkit #1
[   14.059620] pstate: 20401085 (nzCv daIf +PAN -UAO)
[   14.059624] pc :           (null)
[   14.063044] lr : __wake_up_common+0xc0/0x174
[   14.063089] sp : ffff0000098d3bc0
[   14.063108] x29: ffff0000098d3bc0 x28: 0000000000000000 
[   14.063120] x27: 0000000000000000 x26: ffff800098244d88 
[   14.063140] x25: 0000000000000000 x24: 0000000000000000 
[   14.063156] x23: 0000000000000001 x22: 0000000000000000 
[   14.063182] x21: ffffffffffffffe8 x20: ffff000009aebb80 
[   14.063196] x19: ffff0000098d3c70 x18: 0000000000000000 
[   14.063211] x17: 0000000000000000 x16: 0000000000000000 
[   14.063238] x15: 0000000000000000 x14: 0000000000000000 
[   14.063257] x13: 0000000000000000 x12: 0000000000000000 
[   14.063286] x11: 0000000000000000 x10: 0000000000000000 
[   14.063304] x9 : 0000000000000000 x8 : ffff0000098d3df8 
[   14.063367] x7 : 0000000000000000 x6 : 0000000000000003 
[   14.063383] x5 : ffff0000098d3c70 x4 : 0000000000000000 
[   14.063408] x3 : 0000000000000000 x2 : 0000000000000000 
[   14.063443] x1 : 0000000000000001 x0 : ffff000009aebb80 
[   14.063459] Call trace:
[   14.063466]            (null)
[   14.063478]  __wake_up_common_lock+0x84/0xc8
[   14.063495]  __wake_up+0x40/0x50
[   14.063522]  sock_def_wakeup+0x48/0x58
[   14.064996]  unix_release_sock+0x140/0x228
[   14.065042]  unix_release+0x28/0x3c
[   14.065056]  __sock_release+0x48/0xb0
[   14.065071]  sock_close+0x24/0x34
[   14.065117]  __fput+0xec/0x1e0
[   14.065173]  ____fput+0x20/0x2c
[   14.065197]  task_work_run+0x8c/0xb0
[   14.065210]  do_notify_resume+0xf4/0x11c
[   14.065241]  work_pending+0x8/0x10
[   14.065260] Code: bad PC value
[   14.066906] ---[ end trace 5717b31f77e4ee04 ]---
```

pgtableってなんだろう？？？

#とりあえずRestertボタンを押してみる

上のバーに船のマークが出たぞ・・・起動した・・・？？？

#`docker pull continuumio/anaconda3:2019.03`実行

dockerのイメージを引っ張ってきます。

```
(base) [22:52:17 9 JPX]$ docker pull continuumio/anaconda3:2019.03
2019.03: Pulling from continuumio/anaconda3
c5e155d5a1d1: Pull complete 
86534c0d13b7: Pull complete 
5764e90b1fae: Pull complete 
ba67f7304613: Pull complete 
Digest: sha256:2342379103968c3a45c8f49517ab2dff7638dd6a3842cb9cff9792acd92fa928
Status: Downloaded newer image for continuumio/anaconda3:2019.03
docker.io/continuumio/anaconda3:2019.03
(base) [23:00:00 10 JPX]$ 
```

#Dockerイメージをつくる
こちらの記事を参考にしました。
[【画像で説明】DockerでAnaconda環境をつくり、コンテナの中でVSCodeを使う - Qiita](https://qiita.com/komiya_____/items/96c14485eb035701e218)

## `Dockerfile`を作る
イメージの置き場所に移動して、
こちらを`Dockerfile`というファイル名で保存します。

```Dockerfile
# ベースイメージ名:タグ名
FROM continuumio/anaconda3:2019.03

# pipをアップグレードし必要なパッケージをインストール
RUN pip install --upgrade pip && \
    pip install autopep8 && \
    pip install Keras && \
    pip install tensorflow 

# コンテナ側のルート直下にworkdir/（任意）という名前の作業ディレクトリを作り移動する
WORKDIR /workdir

# コンテナ側のリッスンポート番号
# 明示しているだけで、なくても動く
EXPOSE 8888

# ENTRYPOINT命令はコンテナ起動時に実行するコマンドを指定（基本docker runの時に上書きしないもの）
# "jupyter-lab" => jupyter-lab立ち上げコマンド
# "--ip=0.0.0.0" => ip制限なし
# "--port=8888" => EXPOSE命令で書いたポート番号と合わせる
# ”--no-browser” => ブラウザを立ち上げない。コンテナ側にはブラウザがないので 。
# "--allow-root" => rootユーザーの許可。セキュリティ的には良くないので、自分で使うときだけ。
# "--NotebookApp.token=''" => トークンなしで起動許可。これもセキュリティ的には良くない。
ENTRYPOINT ["jupyter-lab", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root", "--NotebookApp.token=''"]

# CMD命令はコンテナ起動時に実行するコマンドを指定（docker runの時に上書きする可能性のあるもの）
# "--notebook-dir=/workdir" => Jupyter Labのルートとなるディレクトリを指定
CMD ["--notebook-dir=/workdir"]
```

##Dockerイメージをビルドする

ビルドしたい場所(イメージの置き場所、Dockerfileと同じ場所)に移動して、
`docker build -t jpx_image_file .`  を実行します。

```
(base) [23:03:45 13 JPX]$ docker build -t jpx_image_file .
[+] Building 100.8s (4/6)                                                       
 => [internal] load build definition from Dockerfile                       1.0s
 => => transferring dockerfile: 1.60kB                                     0.1s
 => [internal] load .dockerignore                                          1.1s
 => => transferring context: 2B                                            0.0s
 => [internal] load metadata for docker.io/continuumio/anaconda3:2019.03   3.8s
 => [1/3] FROM docker.io/continuumio/anaconda3:2019.03@sha256:23423791039  2.0s
 => => resolve docker.io/continuumio/anaconda3:2019.03@sha256:23423791039  0.1s
 => [2/3] RUN pip install --upgrade pip &&     pip install autopep8 &&    93.4s
 => => # ckages (from h5py->Keras) (1.12.0)                                    
 => => # Installing collected packages: Keras                                  
 => => # Successfully installed Keras-2.4.3                                    
 => => # Collecting tensorflow                                                 
 => => #   Downloading tensorflow-2.4.1-cp37-cp37m-manylinux2010_x86_64.whl (39
 => => # 4.3 MB)                                                               
(base) [23:06:04 14 JPX]$ 
```

##docker-compose.ymlを作る

Dockerのイメージを起動するスクリプトです。
これも同じところに置いておきます。

```docker-compose.yml
version: '3'　# docker-composeファイルの書式バージョン。最新の’３’を指定（2019/6/27現在）
services:
  dev: # 任意の名前（ディレクトリ名 + dev がコンテナ名となります）
    build:
      context: .
      dockerfile: Dockerfile
    image: jpx_image_file
    ports:
    - "8080:8888"
    volumes:
    - .:/workdir
```

##コンテナ起動

`docker-compose up`で起動します。

```

(base) [23:14:27 17 JPX]$ docker-compose up
Docker Compose is now in the Docker CLI, try `docker compose up`

Building dev
[+] Building 188.4s (7/7) FINISHED                                              
 => [internal] load build definition from Dockerfile                       0.9s
 => => transferring dockerfile: 1.60kB                                     0.0s
 => [internal] load .dockerignore                                          0.7s
 => => transferring context: 2B                                            0.0s
 => [internal] load metadata for docker.io/continuumio/anaconda3:2019.03   2.7s
 => CACHED [1/3] FROM docker.io/continuumio/anaconda3:2019.03@sha256:2342  0.0s
 => [2/3] RUN pip install --upgrade pip &&     pip install autopep8 &&   174.8s
 => [3/3] WORKDIR /workdir                                                 0.8s
 => exporting to image                                                     8.5s 
 => => exporting layers                                                    8.3s 
 => => writing image sha256:c2bcf94244cead2c36628487e76b3bf6009ffd87de2ae  0.0s 
 => => naming to docker.io/library/jpx_image_file                          0.0s 
Successfully built c2bcf94244cead2c36628487e76b3bf6009ffd87de2ae78877f65ad6c13ba082
WARNING: Image for service dev was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating jpx_dev_1 ... 
Creating jpx_dev_1 ... error

ERROR: for jpx_dev_1  Cannot start service dev: driver failed programming external connectivity on endpoint jpx_dev_1 (2c8f5cb93aa49a9ab121ae2004db0b8b0a69ccbb44b63d2f8caffe76427fd14b): exec: "docker-proxy": executable file not found in $PATH

ERROR: for dev  Cannot start service dev: driver failed programming external connectivity on endpoint jpx_dev_1 (2c8f5cb93aa49a9ab121ae2004db0b8b0a69ccbb44b63d2f8caffe76427fd14b): exec: "docker-proxy": executable file not found in $PATH
ERROR: Encountered errors while bringing up the project.
(base) [23:17:48 18 JPX]$ 
```

なんと、ここまできたのに起動しない！

##`exec: "docker-proxy": executable file not found in $PATH`

エラーでぐぐってみる。`docker-proxy`を有効にすればいいらしい。

[linux - How to enable docker-proxy - Stack Overflow](https://stackoverflow.com/questions/52922212/how-to-enable-docker-proxy)

まず、docker-proxyがあるかどうか。

```
(base) [23:31:16 8 ~]$ sudo find / -name \*docker-proxy 2> /dev/null
Password:
(base) [23:32:57 9 ~]$ 
```
ないなあ。

#冷静になる

開発ブログをもう一度眺めてみると、`Known issues`がありました。
[Apple Silicon Tech Preview | Docker Documentation](https://docs.docker.com/docker-for-mac/apple-m1/)


>The following issues are not expected to be resolved in the final GA build for Apple Silicon.
>
>You must install Rosetta 2 as some binaries are still Darwin/AMD64. To install Rosetta 2 manually from the command line, use this command:
>
>  `softwareupdate --install-rosetta`
>We expect to fix this in a future release.

##`softwareupdate --install-rosetta`実行

```
(base) [23:32:57 9 ~]$ softwareupdate --install-rosetta
I have read and agree to the terms of the software license agreement. A list of Apple SLAs may be found here: http://www.apple.com/legal/sla/
Type A and press return to agree: A
2021-03-27 23:45:08.664 softwareupdate[28887:1698436] Package Authoring Error: 071-00840: Package reference com.apple.pkg.RosettaUpdateAuto is missing installKBytes attribute
Install of Rosetta 2 finished successfully
```

## `docker-compose up`再実行

```

(base) [23:30:25 21 JPX]$ docker-compose up
Docker Compose is now in the Docker CLI, try `docker compose up`

Starting jpx_dev_1 ... 
Starting jpx_dev_1 ... error

ERROR: for jpx_dev_1  Cannot start service dev: driver failed programming external connectivity on endpoint jpx_dev_1 (1a56d12eecfe523f0778c71ccf53ef893980a4ecbce8f7f17a697853d6a55903): Bind for 0.0.0.0:8080 failed: port is already allocated

ERROR: for dev  Cannot start service dev: driver failed programming external connectivity on endpoint jpx_dev_1 (1a56d12eecfe523f0778c71ccf53ef893980a4ecbce8f7f17a697853d6a55903): Bind for 0.0.0.0:8080 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
```

>Bind for 0.0.0.0:8080 failed: port is already allocated

もう割り振られている・・・？？？
Dockerを再起動でいいのかな・・・？？？

##`Restart Docker`
上のバーの船マークをクリックして`Restart Docker`を実行しました。

##`docker-compose up`再々実行
```
(base) [23:47:45 22 JPX]$ docker-compose up
Docker Compose is now in the Docker CLI, try `docker compose up`

Starting jpx_dev_1 ... done
Attaching to jpx_dev_1
dev_1  | [I 14:47:50.292 LabApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret
dev_1  | [W 14:47:53.878 LabApp] All authentication is disabled.  Anyone who can connect to this server will be able to run code.
dev_1  | [I 14:47:53.945 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.7/site-packages/jupyterlab
dev_1  | [I 14:47:53.946 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
dev_1  | [W 14:47:53.950 LabApp] JupyterLab server extension not enabled, manually loading...
dev_1  | [I 14:47:53.956 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.7/site-packages/jupyterlab
dev_1  | [I 14:47:53.957 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
dev_1  | [I 14:47:53.958 LabApp] Serving notebooks from local directory: /workdir
dev_1  | [I 14:47:53.958 LabApp] The Jupyter Notebook is running at:
dev_1  | [I 14:47:53.958 LabApp] http://(643f31ccb6a3 or 127.0.0.1):8888/
dev_1  | [I 14:47:53.958 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
dev_1  | [I 14:48:26.258 LabApp] 302 GET / (172.18.0.1) 10.91ms
dev_1  | [W 14:48:27.699 LabApp] Could not determine jupyterlab build status without nodejs
dev_1  | [W 14:48:28.215 LabApp] 404 GET /lab/api/workspaces/lab?1616856507013 (172.18.0.1): Workspace 'lab' ('lab-a511') not found
dev_1  | [W 14:48:28.216 LabApp] Workspace 'lab' ('lab-a511') not found
dev_1  | [W 14:48:28.216 LabApp] 404 GET /lab/api/workspaces/lab?1616856507013 (172.18.0.1) 10.26ms referer=http://localhost:8080/lab?
```

いい感じです！

##`localhost:8080`
ブラウザのアドレスバーに　localhost:8080　を入力しEnter。

#Jupyter Labが開きました！！！

ばんざい！！！

#追記:くっそ重い
なんでだろう？
ファイルの読み込みが終わらない。
何をするのも遅い。
どうしたらいいんだろう。