経緯
Raspberry Pi で色々試したいとは思っているのですが、いざやろうと思うと
- イメージをダウンロードして
- microSDカード に焼いて
- Raspberry Pi 本体に諸々接続して実機で設定して
- SSHサーバ が建ったら、漸く開発環境から SSH で接続して操作する
……という段取りを踏むことになるので、それを考えると中々重い腰が上がらなくなってしまいました。
しかも、そこまでやって初めてスタートラインに立つ段階で、そこから諸々試すための環境構築が始まるわけです。
そこからさらに失敗するとやり直しをしたり……と考えるとさらに腰が重くなりがちです。
なので、まずは手軽に何度もトライアンドエラーできるように Docker (今回は Docker Desktop for Windows )でどうにかできないかと考えました。
ただし、 Raspberry Pi は ARM で、開発環境は Windows を想定……つまりアーキテクチャ x86-64 や AMD64 だったりするわけなので、アーキテクチャが異なるという壁を越えなければ実現できません。
ということで、今回はこの壁を越えたいと思います。
手順
手順としては以下の記事をほぼそのまま実施することで実現できました。
手順の概要としては以下のような流れになります。
- Debian の仮想環境を Docker 上に建てる
- 仮想の Debian 内で Raspberry Pi OS のイメージをダウンロード、マウント
- プロセッサエミュレータの QEMU (qemu-user-static) をインストールして x86-64 上で ARM を動かせるようにする
- 2.+3. の環境を Debian のコンテナからホスト側に持ち出す
- 4.で持ち出したイメージを Docker でインポートする
具体的な手順
まずは Debian のイメージを pull して、コンテナを起動します。
> docker pull debian:latest
## 略
> docker run -it --privileged debian
続いて Debian のコンテナに入り、作業していきます。
# apt update -y
## 略
# apt upgrade -y
## 略
# apt install -y wget sudo fdisk xz-utils
## 略
#
apt
でアップデート・アップグレードして、必要なパッケージをインストールします。
# cd /var/
# mkdir raspi
# cd raspi/
# wget https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2023-05-03/2023-05-03-raspios-bullseye-armhf-lite.img.xz
## 略
#
作業用ディレクトリを作成・移動して wget
で Raspberry Pi OS のイメージをダウンロードします。元記事ではまだ Raspbian でしたが、今は Raspberry Pi OS なのでその辺りは適宜ダウンロードリンクを差し替えて実行。
# xz -dv 2023-05-03-raspios-bullseye-armhf-lite.img.xz
## 略
#
ダウンロードした Raspberry Pi OS のイメージはxz形式で圧縮されているので、このイメージを展開します。
# fdisk 2023-05-03-raspios-bullseye-armhf-lite.img
Welcome to fdisk (util-linux 2.38.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p
Disk 2023-05-03-raspios-bullseye-armhf-lite.img: 1.83 GiB, 1967128576 bytes, 3842048 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x4c4e106f
Device Boot Start End Sectors Size Id Type
2023-05-03-raspios-bullseye-armhf-lite.img1 8192 532479 524288 256M c W95 FAT32 (LBA)
2023-05-03-raspios-bullseye-armhf-lite.img2 532480 3842047 3309568 1.6G 83 Linux
展開したイメージをマウントするため、 fdisk
コマンドで開始セクタを調べます。
# mkdir image
# sudo mount -o loop,offset=$((512*532480)) 2023-05-03-raspios-bullseye-armhf-lite.img image
#
作業用ディレクトリ image
を作成し、そこに先程の開始セクタの値を offset
として指定してイメージを image
ディレクトリ内にマウントします。
# apt install -y qemu-user-static
ここで今回の要、 qemu-user-static
をインストールします。
# mv image/etc/ld.so.preload image/etc/ld.so.preload.bak
# cp /usr/bin/qemu-arm-static image/usr/bin
#
設定を退避したり qemu-arm-static
を Raspberry Pi OS 内にコピーしたりします。
# cd image
# tar cf ../docker-image-2023-05-03-raspios-bullseye-armhf-lite.tar .
# cd ../
# ls
2023-05-03-raspios-bullseye-armhf-lite.img docker-image-2023-05-03-raspios-bullseye-armhf-lite.tar image
#
マウントした Raspberry Pi OS のディレクトリ内に移動して、 Raspberry Pi OS の一式を親ディレクトリ(先程までいた作業用ディレクトリ)に tar として圧縮します。
今回はこれで docker-image-2023-05-03-raspios-bullseye-armhf-lite.tar
ができ上がりました。
# exit
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
XXXXXXXXXXXX debian "bash" 4 hours ago Up 4 hours hogehoge_fugafuga
> docker cp XXXXXXXXXXXX:/var/raspi/docker-image-2023-05-03-raspios-bullseye-armhf-lite.tar docker-image-2023-05-03-raspios-bullseye-armhf-lite.tar
Successfully copied 1.16GB to PATH:\TO\PROJECT\docker-image-2023-05-03-raspios-bullseye-armhf-lite.tar
コンテナから出てホスト側に戻り、 Docker のコマンド(docker cp
)でコンテナ内のファイルをホスト側にコピーします。
そのために、まずは docker ps
でコンテナIDを調べ、そのIDを使用して先程作成した tar ファイルをパス指定してホスト側に持ち出します。
> docker import .\docker-image-2023-05-03-raspios-bullseye-armhf-lite.tar raspios-bullseye-armhf64-lite:2023-05-03
sha256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
最後に、 Docker のイメージとして先程持ち出した tar をインポートします。
これで作業は完了です。
起動
では、早速インポートしたイメージをコンテナとして起動してみます。
> docker run --name mariberrypi --privileged -it raspios-bullseye-armhf64-lite:2023-05-03 /bin/bash
root@XXXXXXXXXXXX:/# su pi
pi@XXXXXXXXXXXX:/ $ exit
exit
# cat /etc/issue
Raspbian GNU/Linux 11 \n \l
root@XXXXXXXXXXXX:/# apt update -y
Get:1 http://archive.raspberrypi.org/debian bullseye InRelease [23.6 kB]
Get:2 http://archive.raspberrypi.org/debian bullseye/main armhf Packages [314 kB]
Get:3 http://raspbian.raspberrypi.org/raspbian bullseye InRelease [15.0 kB]
Get:4 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf Packages [13.2 MB]
Fetched 13.6 MB in 17s (793 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
20 packages can be upgraded. Run 'apt list --upgradable' to see them.
# apt upgrade -y
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
base-files bind9-host bind9-libs libgstreamer-plugins-base1.0-0 libpam-systemd libssl1.1
libsystemd0 libudev1 libwebp6 libwebpdemux2 libwebpmux3 libx11-6 libx11-data openssl
raspberrypi-sys-mods rpi-eeprom systemd systemd-sysv systemd-timesyncd udev
20 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 16.4 MB of archives.
## 略
#
pi
ユーザになってみたり、バージョン確認してみたり、 apt update
や apt upgrade
してみましたが、至る所で Raspberry Pi だと分かりますね。
きちんと Docker Desktop for Windows 上で Raspberry Pi OS が動いたことが確認できました。検証成功です。
参考
イメージ
Raspberry pi OS を Docker で動かす
- docker + qemu で raspberry pi の開発環境構築 – Qbilinux 日記
- ★ ARM環境のRaspbianイメージをx86上のDockerで動かす – Qiita
- このやり方を基本的に踏襲
- Raspberry Pi OSをDocker上で動かす – Qiita
- RaspbianをDockerイメージに変換する – Qiita
- Raspberry Pi OSをx86_64 上のdockerで動かしたい – Qiita
- Windows環境でのRaspbianコンテナの起動|r
Docker コマンド
- [小ネタ] docker run コマンドではオプションの順番が大切 | DevelopersIO
- docker run — Docker-docs-ja 20.10 ドキュメント
- Docker privileged オプションについて – Qiita
Docker のコンテナからホストへファイルコピー
> docker ps
> docker cp XXXXXXXXXXXX:/var/owntemp/hoge.txt hoge.txt
QEMU
- GitHub – multiarch/qemu-user-static: :earth_africa: `/usr/bin/qemu-*-static`
- qemu-user と qemu-user-static のどちらを使うべきか
- Hyper-V と VirtualBox が共存できる条件について – Qiita
- 無料仮想化ソフト「QEMU 8.0」が公開 ~Windows版のインストーラーは64bit版のみに – 窓の杜
- Windows で Raspbian システムを起動(QEMU, qemu-rpi-kernel を使用)
- ARM用のDockerイメージをQEMUを使って作る | K’zlog
Debian 系での xz を扱うパッケージ
xz-utils
。
途中色々試したときのエラー内容や参考記事等
Error response from daemon: archive/tar: invalid tar header
Error response from daemon: archive/tar: invalid tar header
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: “/bin/bash”: stat /bin/bash: no such file or directory: unknown.
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: “/bin/bash”: stat /bin/bash: no such file or directory: unknown.
- Dockerコンテナを立ち上げようとして「OCI runtime create failed」「” 〜 permission denied”: unknown.」 と言われたとき – 箱のプログラミング日記。
- Docker – OCI runtime create failed エラー – Qiita
Failed to run image. Error invoking remote method ‘docker-run-container’: Error: (HTTP code 400) unexpected – No command specified
Failed to run image. Error invoking remote method ‘docker-run-container’: Error: (HTTP code 400) unexpected – No command specified
Docker Desktop for Windows で直接起動しようとした際のエラー。
mount: permission denied (are you root?)
multiarch/qemu-user-static
を起動しようとすると以下のメッセージが出力されてコンテナが終了してしまう。
mount: permission denied (are you root?)
- Dockerのvolumeでpermission deniedが発生した場合の解決法 – RAKUS Developers Blog | ラクス エンジニアブログ
- コンテナ内で作成したファイルをホストで操作するとPermission deniedが発生する – 頑張らないために頑張る
Windows で起きているのですが……?