- Download
2020-08-20-raspios-buster-armhf-lite.zip
from the official site - Install required tools
sudo pacman -S unzip util-linux docker
- Start Docker service
sudo systemctl start docker.service
Add yourself into the docker
group, otherwise permissions are needed
sudo usermod -aG docker $(whoami)
su - $(whoami)
QEMU setup
- Allow your computer to emulate ARM binaries permanently:
yay -S binfmt-qemu-static qemu-user-static
Verify emulation setup
grep enabled /proc/sys/fs/binfmt_misc/qemu-arm
# enabled
Alternatively, a temporary solution for most distributions:
docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3
Run privileged containers with caution, at least peek into the container's layers before running
yay -s dive
dive docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3
The tool displays some details about the files it is concerned with, a narrow layout
─────── ┃ ● Current Layer Contents ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Layer Permission UID:GID Size Filetree
0 drwxr-xr-x 0:0 1.1 kB ├── etc
1 drwxr-xr-x 0:0 1.1 kB │ └── binfmt.d
2 -rw-rw-r-- 0:0 1.1 kB │ └── 00_linuxkit.conf
drwxr-xr-x 0:0 17 MB └── usr
drwxr-xr-x 0:0 17 MB └── bin
-rwxr-xr-x 0:0 2.2 MB ├── binfmt
-rwxr-xr-x 0:0 4.1 MB ├── qemu-aarch64
-rwxr-xr-x 0:0 3.6 MB ├── qemu-arm
-rwxr-xr-x 0:0 3.9 MB ├── qemu-ppc64le
-rwxr-xr-x 0:0 3.2 MB └── qemu-s390x
Mount
- Extract the downloaded image from the archive
unzip <raspios-image>.zip
- Associate the image with a loop device
sudo losetup --read-only --show -fP <raspios-image>.img
# /dev/loop0
Inspect image partitions if needed
lsblk -o name,label /dev/loop0
Look for the rootfs label
NAME LABEL
loop0
├─loop0p1 boot
└─loop0p2 rootfs
- Mount the root filesystem partition, if not done automatically by your distribution
sudo mkdir /tmp/raspios
sudo mount -o ro /dev/loop0p2 /tmp/raspios
Import
- Create a Docker image from Raspios root filesystem
sudo tar c -C /tmp/raspios . | docker image import - raspios-lite-armhf:buster
- Create and run a Docker container from the image
docker run -it --name raspios_bare raspios-lite-armhf:buster /bin/bash
Enter the container again in case of an accidental exit
docker start -ai raspios_bare
- Clean
sudo umount /tmp/raspios
sudo losetup -d /dev/loop0
Container image manipulation
- When inside, install Node 14 and pkg from vercel globally
wget -qO- https://deb.nodesource.com/setup_14.x | bash -
apt install nodejs
npm i -g pkg
- Fetch a pre-built binary of Node for armhf from a repository
wget https://github.com/yao-pkg/pkg-binaries/releases/download/v1.0.0/fetched-v14.4.0-linux-armv6 -P /root/.pkg-cache/v2.6/
- Exit the container by pressing
Ctrl-D
or typing theexit
command - Commit the changes to the image for a reuse
docker commit raspios_bare raspios_node_pkg
You can safely remove the bare container now
docker rm raspios_bare
Packaging
- Create a sample script for packaging
echo 'console.log("Hello World")' > index.js
- Create a temporary container, mount a current folder as
/build
in it and package it for linux
docker run --rm -v $PWD:/build raspios_node_pkg pkg -t linux --out-dir /build /build/index.js
- An armhf Node executable named
index
is created in a current directory
file index
# index: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (GNU/Linux), ...
Make an executable script to streamline process and run i.e. like
armpkg index.js
#!/bin/bash
docker run --rm -v $PWD:/build raspios_node_pkg pkg -t linux --out-dir /build "/build/$1"
Done!
Links
- https://github.com/vercel/pkg-fetch/releases
- https://github.com/lukechilds/dockerpi
- http://kmdouglass.github.io/posts/how-i-built-a-cross-compilation-workflow-for-the-raspberry-pi/
- http://modernhackers.com/virtualize-raspberry-pi-3-s-to-run-docker-swarm-cluster-on-it/
- https://docs.docker.com/storage/volumes/#start-a-container-with-a-volume
- https://hub.docker.com/r/docker/binfmt/tags