Docker on Stretch for RPi Zero W
🐒 2019/10/30 更新
従来通りのインストール手順でラズパイ Zero でも Docker をインストールできるようになりました!
- Issue #709: Docker-CE need updating for raspbian buster | Docker for Linux @ GitHub
これでOK!curl https://get.docker.com | sh
🐒 2020/03/22 更新
Stretch Lite では未検証なのですが Buster Lite では以下で docker-compose もインストールできました。やはりコンテナよりは若干起動が速いので、ダメ元で試してみる価値はあると思います。docker-composeapt install docker-compose
各種注意点やNG の場合は、下記 docker-compose のインストール手順は変わらないので、引き続き本記事をご覧ください。
2019/09/29 現在、RPi Zero W
(ARMv6l
) の Stretch
に Docker
と docker-compose
をインストールする手順です。(Docker=v18.06.2-ce, docker-compose=v1.25.0dev)
- Raspbian Buster に Docker を入れたいかたはこちら。
🐒 【所感】ラズパイ・ゼロで Docker を動かすの、ここまで大変だとは思いませんでした。。。
まとめると、これだけなのに...情報がバラバラだし、どの記事もラズパイ Zero W で動きませんでした。公式のインストール・スクリプトも「Scratch, ラズパイ・ゼロ対応」とか言いながら動かないし。全ての原因は、みんな開発が速いのでちょっとでもバージョン違うとダメだということ。この記事も適宜更新して行きたいと思います。
Raspberry Pi Zero W に Docker-CE をインストール
Docker インストール手順
ラズパイ Zero W の型番と RaspbianOS のバージョンが同じか確認してから作業を始めることをオススメします。(記事下部の「実績環境」参照)
$ # GPG 鍵を追加
$ curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo apt-key add -
OK
$ # ラズパイ用のカーネルヘッダの追加
$ sudo apt install raspberrypi-kernel-headers
$ # Docker 用の apt リポジトリを追加(docker.list を作成して追加)
$ sudo vi /etc/apt/sources.list.d/docker.list
...
$ # docker.list の内容確認(これを上記で記載する)
$ cat /etc/apt/sources.list.d/docker.list
deb [arch=armhf] https://download.docker.com/linux/raspbian stretch stable
$ # アップデート
$ sudo apt update
...
$ # apt でインストール可能なパッケージを確認
$ apt list -a docker-ce
...
$ # 実績のあるパッケージをインストールする(ここまで長かった。。。)
$ sudo apt-get install docker-ce=18.06.2~ce~3-0~raspbian
...
Docker を触ってみる
Docker のバージョンを確認する
$ sudo docker version
Client:
Version: 18.06.2-ce
API version: 1.38
Go version: go1.10.3
Git commit: 6d37f41
Built: Sun Feb 10 03:57:32 2019
OS/Arch: linux/arm
Experimental: false
Server:
Engine:
Version: 18.06.2-ce
API version: 1.38 (minimum version 1.12)
Go version: go1.10.3
Git commit: 6d37f41
Built: Sun Feb 10 03:53:01 2019
OS/Arch: linux/arm
Experimental: false
Hello-World を試す
$ # ARMv6 用の Hello-World イメージをダウンロードする
$ sudo docker pull hypriot/armhf-hello-world
...
$ # Hello-World を実行する
$ sudo docker run --rm hypriot/armhf-hello-world
Hello from Docker.
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker Hub account:
https://hub.docker.com
For more examples and ideas, visit:
https://docs.docker.com/userguide/
Alpine Linux イメージのコンテナを試してみる
$ # ARMv6用の Alpine Linux のイメージをダウンロード
$ docker pull arm32v6/alpine
...
$ # Alpine の OS バージョンを表示してみる
$ docker run --rm arm32v6/alpine cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.10.2
PRETTY_NAME="Alpine Linux v3.10"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
sudo を付けるのが面倒な場合の設定
$ # 毎回コマンドに sudo を付けるのが面倒な場合
$ # ====================================
$ # docker グループに追加する
$ sudo gpasswd -a $USER docker
ユーザ pi をグループ docker に追加
$ # サービスを再起動してグループを反映させる
$ sudo systemctl restart docker
$ # 下記を実行するかログインしなおしてユーザをグループに反映させる
$ source ~/.bashrc
$
$ # 動作テスト
$ # ====================================
$ # sudo なしでバージョン表示されるか確認
$ docker version
Client:
Version: 18.06.2-ce
API version: 1.38
Go version: go1.10.3
Git commit: 6d37f41
Built: Sun Feb 10 03:57:32 2019
OS/Arch: linux/arm
Experimental: false
Server:
Engine:
Version: 18.06.2-ce
API version: 1.38 (minimum version 1.12)
Go version: go1.10.3
Git commit: 6d37f41
Built: Sun Feb 10 03:53:01 2019
OS/Arch: linux/arm
Experimental: false
$ # ARM 用の Hello-World を sudo なしで実行してみる
$ docker run --rm hypriot/armhf-hello-world
Hello from Docker.
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker Hub account:
https://hub.docker.com
For more examples and ideas, visit:
https://docs.docker.com/userguide/
docker-compose のインストール手順
docker-compose
も使えます。色々試しましたが、docker in docker でビルドしたコンテナを使うのが楽でした。しかし、ラズパイ Zero W だとビルドに 2 時間以上かかるので、ビルド済みのイメージをアップしました。自身でビルドしたい場合は、リポジトリの Dockerfile と Build スクリプト をご覧ください。
sudo docker pull keinos/docker-compose:arm32v6
$ # イメージのダウンロード
$ sudo docker pull keinos/docker-compose:arm32v6
arm32v6: Pulling from keinos/docker-compose
5308e891d68f: Pull complete
268669cbddb5: Pull complete
d7cb24fe6c79: Pull complete
3281aaa24af1: Pull complete
Digest: sha256:d62977420f60796d7c0a5fa9df50db98e28f549b48c194b43210fdc9ce82d3df
Status: Downloaded newer image for keinos/docker-compose:arm32v6
$ # 実行例(コンテナ呼び出し)
$ sudo docker run --rm keinos/docker-compose:arm32v6 version
docker-compose version 1.25.0dev, build unknown
docker-py version: 4.0.1
CPython version: 3.7.4
OpenSSL version: OpenSSL 1.1.1d 10 Sep 2019
$ docker-compose
と、コマンドとして使えるようにシェル・スクリプトも用意しました。以下の2行を実行するとインストールできます。
sudo curl -L --fail https://keinos.github.io/Dockerfile_of_Docker-Compose_for_ARMv6l/run.sh -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
$ # ダウンロードとインストール
$ sudo curl -L --fail https://keinos.github.io/Dockerfile_of_Docker-Compose_for_ARMv6l/run.sh -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1710 100 1710 0 0 3912 0 --:--:-- --:--:-- --:--:-- 3922
$ # アクセス権の変更(実行権限を与える)
$ sudo chmod +x /usr/local/bin/docker-compose
$ # 実行テスト
$ sudo docker-compose version
docker-compose version 1.25.0dev, build unknown
docker-py version: 4.0.1
CPython version: 3.7.4
OpenSSL version: OpenSSL 1.1.1d 10 Sep 2019
- Dockerfile @ GitHub
- Docker Image @ Docker Hub
- 参考文献:「Raspberry Pi用docker-composeの構築」@ Qiita
Docker Hub の Docker イメージ取り使い時の注意(docker pull
時)
Dockerfile の
FROM
には、なるべく ARM32v6 の公式イメージを使う
- https://hub.docker.com/u/arm32v6
- 例)
$ docker pull arm32v6/alpine
ラズパイ Zero W の Docker を使う場合、アーキテクチャ(CPU の種類)を念頭に置くことが重要と実感しました。と言うのも、悲しいことに Docker Hub の大半のイメージがラズパイ Zero の Docker で動きません。
ARM
タグが付いていても動かないものも多くあります。これは、大半がラズパイ 3 などの ARMv7
系用にビルドされており、ラズパイ Zero W は ARMv6
系だからです。また、ラズパイ Zero にも ARMv6
と ARMv6l
の2種類があるらしく内容によっては動きません。(v6l
の l
は Little Endian の意味らしくメモリ上のデータの並び順に違いがあるそうです)
docker pull myname/myimage:arm # <- ARMv6 なのに ARMv7 用がダウンロードされる
もちろん ARMv6
用、ARMv7
用と各々のイメージにタグを付けて提供されている場合は問題ありません。
$ docker pull myname/myimage:armv6 <- ARMv6用イメージ
$ docker pull myname/myimage:armv7 <- ARMv7用イメージ
希望するイメージが ARMv6 用に提供されているか悩んだ場合、公式の ARMv6 専用のリポジトリがあるので、まずはそこにベースイメージが提供されているかチェックします。
問題は、他のリポジトリで multi-arch
イメージとして1つのタグで提供している場合です。
docker pull myname/myimage:latest
「multi-arch
」イメージとは1つのタグで複数アーキテクチャのイメージを提供するものを言います。代表的なものに alpine:latest
があります。
基本的な仕組みとしては、myname/myimage:latest
というイメージを作成する代わりに、manifest
と呼ばれる JSON ファイルを作成して Docker リポジトリに設置します。
このマニフェストには、OS やアーキテクチャに対応したイメージの情報が記載されています。つまり、実イメージではなくエイリアスというか紐付けファイルといった感じのものです。
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 529,
"digest": "sha256:2335c729b8a6764c52a3cbfe43d1450d5e782638c986d237ffc30ca33881c3e3",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 529,
"digest": "sha256:956077792b12d730494cd54eacb497b86ef732434dda6cb67d300c283c19322b",
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v6"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 529,
"digest": "sha256:acc143d95320fe0b572ca8677e18aea3e9306b3b9f94a26fc1e084ec4361f104",
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v7"
}
}
]
}
上記マニフェストは AMD64
ARMv6
ARMv7
の3つのイメージに対応した例で、これらのイメージは同じリポジトリにあらかじめ置いて(docker push
して)おく必要があります。各々イメージのタグ名はわかりやすければ何でも構いません。イメージのハッシュ値(上記 JSON の digest
の値)で判断するためです。
$ docker pull myname/myimage:latest
すると、まず上記 manifest
がダウンロードされ、対応したアーキテクチャのイメージをダウンロードします。
通常は、ローカルのアーキテクチャにあわせてダウンロードしますが、ARM の場合に不具合が発生します。
2019/09/26 現在、ARM の Docker は上記 JSON の variant
の値、つまりCPU のバージョン情報を加味しないため、linux/arm
が2つヒットしてしまいます。そして、仕様として複数ヒットする場合、最初にヒットした ARM アーキテクチャのイメージをダウンロードしてしまうのです。
- Issue #34875 manifest list (multiarch) picks wrong arch on ARMv7 Docker 公式 @ GitHub
対処法として「頻度の多いバージョンを上に記載する」しか方法がなく、偶然にもバージョンが合えばいいのですが、ラズパイ Zero の場合は期待薄でしょう。
そのため、ラズパイ3 にも Zero にも対象にした multi-arch
イメージを使った汎用 Dockerfile
を作成することは現時点で難しそうです。Dockerfile_arm32v6
など別途提供した方が無難そうです。
実績環境
- SSH 作業側情報
- macOS Mojave (OSX 10.14.6)
- 接続: Wi-Fi + SSH で作業
- ラズパイ側情報
- 型番:
Model: Zero W
Hardware: BCM2835
Revision: 9000c1
- 対象 OS: Raspbian 9 (Stretch Lite)
- イメージ: 2019-04-08-raspbian-stretch-lite.zip [ダウンロード・ページ @ 公式]
- SD 書き込みアプリ: balenaEtcher(旧 Etcher, ラズパイ推奨)
- SD 初期化アプリ: SD Card Formatter(SD Association 公式, Mojave 動作確認済み)
- 事前作業:
- SD カードは以下の手順で初期化
- 設定:
ssh
公開鍵接続とsudo raspi-config
でローケル類を日本語/日本に設定済み。 - アップデート:
sudo apt update
sudo apt upgrade
のみ。 - ファームウェアアップデート: なし(
sudo rpi-update
してません) - 追加インストール:
sudo apt install vim
のみ。
- 型番:
バージョン情報
$ sudo docker version
Client:
Version: 18.06.2-ce
API version: 1.38
Go version: go1.10.3
Git commit: 6d37f41
Built: Sun Feb 10 03:57:32 2019
OS/Arch: linux/arm
Experimental: false
Server:
Engine:
Version: 18.06.2-ce
API version: 1.38 (minimum version 1.12)
Go version: go1.10.3
Git commit: 6d37f41
Built: Sun Feb 10 03:53:01 2019
OS/Arch: linux/arm
Experimental: false
$ # ファームウェア
$ vcgencmd version
Aug 15 2019 12:06:42
Copyright (c) 2012 Broadcom
version 0e6daa5106dd4164474616408e0dc24f997ffcf3 (clean) (release) (start)
$ # ハードウェア
$ cat /proc/cpuinfo
processor : 0
model name : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS : 697.95
Features : half thumb fastmult vfp edsp java tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xb76
CPU revision : 7
Hardware : BCM2835
Revision : 9000c1
Serial : 00000000xxxxxxxx
$ rev=$(awk '/^Revision/ { print $3 }' /proc/cpuinfo) && curl -L perturb.org/rpi?rev=$rev
Revision : 9000c1
Model : Zero W
Memory : 512 MB
Overvolt : No
Released : Q1 2017
Notes : (Mfg by Sony)