October 23, 2022
Create a Docker image from scratch using an OS as base
For the purposes of this example, we’ll be using Raspberry Pi OS 64-bit as the base filesystem for our new Docker image. Since this operating system lacks an official one on Docker Hub, it feels like a good fit. However, the principles described here should work well enough for any OS.
Choose an image to download here and save it locally. With
unxz, uncompress the file.
Since Raspberry Pi OS is distributed as a disk image and not a partition image, we need to mount it with an offset to avoid getting data from the boot partition. Keep in mind that our goal here is to create a Docker image and, for that, we don’t need boot files.
Find the desired partition offset using
fdisk -l 2022-04-04-raspios-bullseye-arm64-lite.img
You’re likely to see an output similar to the following:
Disk 2022-04-04-raspios-bullseye-arm64-lite.img: 1,86 GiB, 2000683008 bytes, 3907584 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: 0x0ee3e8a8 Device Boot Start End Sectors Size Id Type 2022-04-04-raspios-bullseye-arm64-lite.img1 8192 532479 524288 256M c W95 FAT32 (LBA) 2022-04-04-raspios-bullseye-arm64-lite.img2 532480 3907583 3375104 1,6G 83 Linux
From this, we can see that the block size used is 512 and the start block for the root partition is 532480. Therefore, our offset will be
532480 * 512 = 272629760.
Now, let’s mount the relevant partition, gather its contents as a
tar file, generate the image and push it to a registry.
mkdir rootfs mount -o loop,offset=272629760 2022-04-04-raspios-bullseye-arm64-lite.img rootfs # Keep in mind that a container image is, under the hood, a tar file of tar files tar -C rootfs -c . | docker import --platform=linux/arm64 - laury/raspberry-pi-os:bullseye-20220404 docker push laury/raspberry-pi-os:bullseye-20220404 umount rootfs
Note: as the time of writing, the
--platform flag is ignored by
docker import (tested on version 20.10). So, the host architecture is used to determine the platform supported by the generated image. This bug will be resolved on the 22.06 release (see this PR for more information).