From Docker to Boot: Creating a Bootable Disk Image and Running It in QEMU with Internet Access
In this tutorial, I'll guide you through the process of creating a bootable disk image using a Docker container running Alpine Linux. This guide will cover everything from setting up the Docker environment to configuring the image for booting.
Prerequisites
- A system with Docker installed (Docker Desktop or Docker Engine).
- Basic knowledge of Docker and Linux commands.
- An M2 chip Mac (if applicable) for cross-platform compatibility.
Step 1: Create a Docker Image with Alpine Linux
First, we need to create a Docker image based on Alpine Linux with the necessary packages installed.
Run the following command to build the Docker image:
docker build -t myalpine .
Step 2: Run the Docker Container
Next, we will run the Docker container and prepare it for export.
docker run --platform linux/amd64 -it myalpine sh
Step 3: Export the Docker Container
Get the container ID using:
docker ps
Then, export the Docker container to a tar file:
docker export <container_id> -o alpine.tar
To avoid the permission issues, try extractingthe folder in Mac [This should solve the read only file system issue]
Step 4: Create the Bootable Disk Image
Now we will set up a new Docker container to build the bootable disk image.
Run a New Debian Container
Use the following command to start a new Debian container with necessary permissions:
docker run --platform linux/amd64 -it -v `pwd`:/os:rw --privileged --cap-add SYS_ADMIN amd64/debian:bullseye bash
Install Required Packages
Inside the Debian container, run:
apt-get -y update
apt-get -y install extlinux fdisk qemu-utils
Create Disk Image
Now, execute the following commands in the Debian container to create a bootable disk image:
领英推荐
# Define the size and create an empty image
IMG_SIZE=$(expr 1024 \* 1024 \* 1024 / 512)
dd if=/dev/zero of=/os/myalpine.img bs=${IMG_SIZE} count=512
# Set up partitioning
sfdisk /os/myalpine.img <<EOF
label: dos
label-id: 0x5d8b75fc
device: new.img
unit: sectors
linux.img1 : start=2048, size=2095104, type=83, bootable
EOF
# Create a filesystem
OFFSET=$(expr 512 \* 2048)
losetup -o ${OFFSET} /dev/loop0 /os/myalpine.img
mkfs.ext4 /dev/loop0
# Mount the filesystem
mkdir /os/mnt
mount -t auto /dev/loop0 /os/mnt/
Extract the Alpine Files
Extract the contents of the exported Alpine tar file into the mounted directory:
cp -r /os/alpine/* /os/mnt/
Configure Boot Loader
Install the SYSLINUX bootloader:
extlinux --install /os/mnt/boot/
Create SYSLINUX Configuration
Create the SYSLINUX configuration file:
cat > /os/mnt/boot/syslinux.cfg <<EOF
DEFAULT linux
SAY Now booting the kernel from SYSLINUX...
LABEL linux
KERNEL /boot/vmlinuz-virt
APPEND ro root=/dev/sda1 rootfstype=ext4 initrd=/boot/initramfs-virt
EOF
Configure Networking - To Allow access to internet
Set up networking configuration by adding the following lines:
echo "auto eth0" > /os/mnt/etc/network/interfaces
echo "iface eth0 inet dhcp" >> /os/mnt/etc/network/interfaces
echo "::sysinit:/bin/sh -c 'ifconfig eth0 up; udhcpc -i eth0'" >> /os/mnt/etc/inittab
Unmount and Cleanup
After everything is set up, unmount the filesystem and detach the loop device:
umount /os/mnt
losetup -D
Install the Master Boot Record
Finally, install the Master Boot Record to your disk image:
dd if=/usr/lib/syslinux/mbr/mbr.bin of=/os/myalpine.img bs=440 count=1 conv=notrunc
You have now successfully created a bootable disk image from a Docker container running Alpine Linux. This disk image can be used in virtualization environments or written to a USB drive for booting.
Next Steps
qemu-system-x86_64 -drive file=/Users/srikanth/Desktop/blog/myalpine.img,index=0,media=disk,format=raw -netdev user,id=mynet0 -device virtio-net-pci,netdev=mynet0
References: