Before getting into the details
Docker is not natively compatible with macOS, so Hyperkit is used to run an alpine virtual image. The workflow described in this guide is similar goals to Docker Desktop on Mac (note that several features such as bridge network, volume wouldn't work with this way.)
Install docker client binary
Launch Ubuntu Linux (ARM64) VM and Dockerd
First of all, I assume you are working on ~/Downloads
directory and have the following files downloaded:
- 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
- qemu-img (prebuilt): https://drive.google.com/file/d/1vGsANcOV123TOQQKFwzSwqyDelDy0pRG/view?usp=sharing
Then run the following commands in terminal:
-- Terminal 1
$ mv ubuntu-20.04-server-cloudimg-arm64-vmlinuz-generic vmlinux.gz
$ gunzip vmlinux.gz
$ rm vmlinux.gz
$ mv ubuntu-20.04-server-cloudimg-arm64-initrd-generic initrd
$ tar zxvf ubuntu-20.04-server-cloudimg-arm64.tar.gz
$ mv focal-server-cloudimg-arm64.img disk.img
$ git clone https://github.com/evansm7/vftool.git
$ cd vftool && xcodebuild
$ cp ./build/Release/vftool vftoolcli
# Expand the disk image size because its default size is 2GB.
$ DYLD_LIBRARY_PATH=~/Downloads/qemu-img-x86_64 ~/Downloads/qemu-img-x86_64/qemu-img resize disk.img +60G
$ ./vftoolcli -k vmlinuz -i initrd -d disk.iso -m 4096 -a "console=hvc0"
...
# You can see /dev/ttysXXX here.
-- Terminal 2
$ screen /dev/ttysXXX
So you can see initramfs prompt in Terminal 2, and then:
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
Now press CTRL + C to terminate the VM, and run the following command to start it again with the disk mounted to /dev/vda
:
$ ./vftoolcli -k vmlinuz -i initrd -d focal-desktop-arm64.iso -m 4096 -a "console=hvc0 root=/dev/vda"
After that get into TTY using screen
command:
Ubuntu 20.04.1 LTS ubuntu hvc0
ubuntu login: root
Password: root
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-54-generic aarch64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Mon Nov 30 08:59:18 UTC 2020
System load: 0.08 Processes: 100
Usage of /: 95.8% of 1.23GB Users logged in: 0
Memory usage: 4% IPv4 address for enp0s1: 192.168.64.7
Swap usage: 0%
=> / is using 95.8% of 1.23GB
0 updates can be installed immediately.
0 of these updates are security updates.
Last login: Wed Apr 1 17:24:06 UTC 2020 on hvc0
$ resize2fs /dev/vda
$ passwd
$ apt update
$ apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y
$ curl -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 update
$ apt-get install docker-ce docker-ce-cli containerd.io -y
$ sh -c "cat <<EOF > /etc/docker/daemon.json
{
\"hosts\": [\"tcp://0.0.0.0:2375\", \"unix:///var/run/docker.sock\"],
\"storage-driver\": \"vfs\"
}
EOF"
$ sed -i 's/ -H fd:\/\///g' /lib/systemd/system/docker.service
$ systemctl daemon-reload
$ systemctl restart docker
$ docker run hello-world
# Check if docker works.
$ apt install openssh-server net-tools -y
$ ip a | grep 192.168
inet 192.168.64.2/24 brd 192.168.64.255 scope global dynamic noprefixroute enp0s1
# Check the IP address here.
Now you can execute docker on your mac by:
$ DOCKER_HOST=192.168.64.xxx docker run hello-world
If this works well, you can use docker after registering the environment variable using export DOCKER_HOST=192.168.64.xx
(note that you have to run vftool and check ip address again after rebooting your Mac.)