Skip to content

Instantly share code, notes, and snippets.

@cfstras
Last active January 30, 2024 17:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cfstras/e17407f482562fe31367beed8d2dfa4f to your computer and use it in GitHub Desktop.
Save cfstras/e17407f482562fe31367beed8d2dfa4f to your computer and use it in GitHub Desktop.
Lima M1

Note (2024): I've used this for a while to get a reasonably workable Docker installation on my M1 MacBook. For simplicity I use colima nowadays. The setup below should still work though.


  1. Install lima

    brew install lima
  2. Create VM using this docker.yaml

    curl -fsSL -o docker.yaml https://gist.githubusercontent.com/cfstras/d83194ba7a8e9599eaf13978fd1a3c36/raw/49f84e56dde5e43a597c8d00ffefe11c7e12d0f7/lima-docker.yaml
    limactl start ./docker.yaml # (not sure? don't remember the exact command)
  3. Configure gcloud login. You only need to do this within the lima VM if you intend to use the wrapper below.
    If you want to use the mounted socket via a docker context (next step), you will only need to run gcloud auth login and gcloud auth configure-docker on your host.

    LIMA_INSTANCE=docker lima
    # in the shell that opens
    
    gcloud auth login
    # Follow the prompts to log in to gcloud
    
    gcloud auth configure-docker
    # Enter "Y", then Enter to confirm
    
    exit
  4. configure docker context

    docker context create lima --docker "host=unix://$HOME/.lima/docker/sock/docker.sock" && docker context use lima
  5. Fallback for things that don't know what docker context is

    sudo ln -s /Users/claus/.lima/docker/sock/docker.sock /var/run/docker.sock
  6. Add wrapper (optional, if not using context)

    • Copy the docker file from this gist to ~/bin\
    • this assumes that ~/bin is in your path, and is before /usr/local/bin, where docker desktop installs their binary

Now, to run something with regular docker:

your-script.sh

To run it with lima:

LIMA=true your-script.sh
#!/bin/bash
LIMA="${LIMA:-false}"
if [[ "$LIMA" == "true" ]]; then
lima nerdctl "${@}"
elif [[ "$LIMA" == "docker" ]]; then
LIMA_INSTANCE=docker lima docker "${@}"
elif [[ "$LIMA" == "podman" ]]; then
LIMA_INSTANCE=podman lima podman "${@}"
elif [[ "$PODMAN" == "true" ]]; then
podman "${@}"
else
/opt/homebrew/bin/docker "${@}"
fi
# Example to use Docker instead of containerd & nerdctl
# $ limactl start ./docker.yaml
# $ limactl shell docker docker run -it -v $HOME:$HOME --rm alpine
# To run `docker` on the host (assumes docker-cli is installed):
# $ export DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock')
# $ docker ...
# This example requires Lima v0.8.0 or later
images:
# Use the latest ubuntu 22.04 image
# Hint: run `limactl prune` to invalidate the cache
- location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img"
arch: "x86_64"
- location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-arm64.img"
arch: "aarch64"
mounts:
- location: "~"
writable: true
- location: "/tmp/lima"
writable: true
- location: "/var/folders"
writable: true
- location: "/private/var/tmp"
writable: true
# containerd is managed by Docker, not by Lima, so the values are set to false here.
containerd:
system: false
user: false
provision:
- mode: system
# This script defines the host.docker.internal hostname when hostResolver is disabled.
# It is also needed for lima 0.8.2 and earlier, which does not support hostResolver.hosts.
# Names defined in /etc/hosts inside the VM are not resolved inside containers when
# using the hostResolver; use hostResolver.hosts instead (requires lima 0.8.3 or later).
script: |
#!/bin/sh
sed -i 's/host.lima.internal.*/host.lima.internal host.docker.internal/' /etc/hosts
- mode: system
script: |
#!/bin/bash
set -eux -o pipefail
command -v docker >/dev/null 2>&1 && exit 0
export DEBIAN_FRONTEND=noninteractive
curl -fsSL https://get.docker.com | sh
# NOTE: you may remove the lines below, if you prefer to use rootful docker, not rootless
systemctl disable --now docker
apt-get install -y uidmap dbus-user-session
- mode: user
script: |
#!/bin/bash
set -eux -o pipefail
systemctl --user start dbus
dockerd-rootless-setuptool.sh install
docker context use rootless
# Install qemu for amd64 support on M1 & google cloud SDK for docker login
- mode: user
script: |
#!/bin/bash
set -euxo pipefail
sudo apt update && sudo apt install -y qemu-user-static binfmt-support apt-transport-https ca-certificates gnupg
if [[ ! -f /etc/apt/sources.list.d/google-cloud-sdk.list ]]; then
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
fi
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
sudo apt-get update && sudo apt-get -y install google-cloud-sdk
probes:
- script: |
#!/bin/bash
set -eux -o pipefail
if ! timeout 30s bash -c "until command -v docker >/dev/null 2>&1; do sleep 3; done"; then
echo >&2 "docker is not installed yet"
exit 1
fi
if ! timeout 30s bash -c "until pgrep rootlesskit; do sleep 3; done"; then
echo >&2 "rootlesskit (used by rootless docker) is not running"
exit 1
fi
hint: See "/var/log/cloud-init-output.log". in the guest
hostResolver:
# hostResolver.hosts requires lima 0.8.3 or later. Names defined here will also
# resolve inside containers, and not just inside the VM itself.
hosts:
host.docker.internal: host.lima.internal
portForwards:
- guestSocket: "/run/user/{{.UID}}/docker.sock"
hostSocket: "{{.Dir}}/sock/docker.sock"
message: |
To run `docker` on the host (assumes docker-cli is installed), run the following commands:
------
docker context create lima --docker "host=unix://{{.Dir}}/sock/docker.sock"
docker context use lima
docker run hello-world
------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment