Setup of persistent docker node on ARM M1 MacBook
By: Callum Smith
Tags: Virtualization, Docker, Mac, Containers, M1

First off: Install Xcode from the App Store. This takes a little while so getting this going first off is a good idea.

You will also need homebrew to be installed. I recommend using the stable homebrew compiled for x86_64 and not the experimental ARM branch.

Next you will want to get a disk image, initrd and kernel file for any linux distribution. In this guide I have used the cloud image for Ubuntu, you can choose anything, but the process of getting it up and running may differ.

Kernel:

https://cloud-images.ubuntu.com/releases/focal/release/unpacked/ubuntu-20.04-server-cloudimg-arm64-vmlinuz-generic

Initrd:

https://cloud-images.ubuntu.com/releases/focal/release/unpacked/ubuntu-20.04-server-cloudimg-arm64-initrd-generic

Disk image:

https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-arm64.tar.gz

Collect these files together in a folder, I chose ~/VM/docker-ubuntu-cloud/

mkdir -p ~/VM/docker-ubuntu-cloud

cd ~/VM/docker-ubuntu-cloud

mv ~/Downloads/ubuntu-20.04-server-cloudimg-arm64-vmlinuz-generic vmlinuz.gz

mv ~/Downloads/ubuntu-20.04-server-cloudimg-arm64-initrd-generic initrd

mv ~/Downloads/ubuntu-20.04-server-cloudimg-arm64.tar.gz diskimg.tar.gz

You will want to unzip your disk image and the kernel file and tidy up the image tarball

gunzip vmlinuz.gz

tar xvzf diskimg.tar.gz

rm diskimg.tar.gz

Accept the license agreement for the xcodebuild tool

sudo xcodebuild -license

Clone the VM command line tool from github and build it using our Xcode install and copy it to our local bin



cd vftool

xcodebuild

cd ../

cp vftool/build/Release/vftool /usr/local/bin/

source ~/.zshrc git clone https://github.com/evansm7/vftool cd vftoolxcodebuildcd ../cp vftool/build/Release/vftool /usr/local/bin/source ~/.zshrc

Start the server using vftool

vftool -k vmlinuz -i initrd -d focal-server-cloudimg-arm64.img -m 4096 -a “console=hvc0”

The ouput will look something like this:

vftool[43462:425638] vftool (v0.1 25/11/2020) starting

vftool[43462:425638] +++ kernel at vmlinuz -- file:///Users/xi0s/VM/ubuntu-cloud-docker/, initrd at initrd -- file:///Users/xi0s/VM/ubuntu-cloud-docker/, cmdline 'console=hvc0', 1 cpus, 4096MB memory

vftool[43462:425638] +++ fd 3 connected to /dev/ttys001

vftool[43462:425638] +++ Waiting for connection to: /dev/ttys001

Connect to your VM using the screen — making note of which tty socket is actually connected to your VM. You will need to do this in a new terminal tab/window from the one running your VM.

screen /dev/ttys001

The cloud image for Ubuntu is configured to be provisioned by cloud-init by default. We will want to manually provision the image and set the root password along with some host keys and networking. Run the following commands inside your VM to get it provisioned for the next step.

mkdir /mnt

mount /dev/vda /mnt

chroot /mnt touch /etc/cloud/cloud-init.disabled echo 'root:root' | chpasswd ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa

ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa

ssh-keygen -f /etc/ssh/ssh_host_ed25519_key -N '' -t ed25519 cat <<EOF > /etc/netplan/01-dhcp.yaml

network:

renderer: networkd

ethernets:

enp0s1:

dhcp4: true

version: 2

EOF exit

umount /dev/vda

Close your VM (Press Ctrl+c inside the terminal window that is running your VM) and expand the disk image to allow other things to be installed and run. You will need to install the qemu package via homebrew for this step

arch -arch x86_64 brew install qemu

qemu-img resize focal-server-cloudimg-arm64.img +5G

Now start the server with the disk attached

vftool -k vmlinuz -i initrd -d focal-server-cloudimg-arm64.img -m 4096 -a “console=hvc0 root=/dev/vda”

Connect again using screen — your tty socket may have changed so just be sure to double check

screen /dev/ttys001

Now login using your new root credentials (username root password root )

Update the disk size inside the VM

resize2fs /dev/vda

Install Docker — below is a list of commands from the docker install guide for Ubuntu on ARM



apt-get install \

apt-transport-https \

ca-certificates \

curl \

gnupg-agent \

software-properties-common

curl -fsSL

add-apt-repository \

"deb [arch=arm64]

$(lsb_release -cs) \

stable"

apt-get update

apt-get install docker-ce docker-ce-cli containerd.io apt-get updateapt-get install \apt-transport-https \ca-certificates \curl \gnupg-agent \software-properties-commoncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -add-apt-repository \"deb [arch=arm64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) \stable"apt-get updateapt-get install docker-ce docker-ce-cli containerd.io

Create a user account to login with and add it to the docker group. Here I use the username docker and ensure the home directory is created with the -m flag.

useradd -g docker -m docker

Login to that user account and test docker is working