Skip to content

Ubuntu on the 2018 Mac mini (i7, T2 chip)

Runbook for converting the 2018 Intel Mac mini (i7-8700B, 6C/12T, 16GB, 512GB) into the fleet’s 10.1.1.15 β€œdev” box (GitHub CI runner + Docker dev stack). The T2 security chip is what makes this different from a stock Ubuntu install β€” the internal SSD and Wi-Fi sit behind it, so the install uses the t2linux community’s patched ISO and kernel instead of mainline Ubuntu.

Hardware rationale: 6C/12T is ~2–2.5Γ— the multithreaded throughput of the 4C/4T i5 boxes elsewhere in the fleet, and containers run natively x86 (matching the Lambda production architecture, no Apple Silicon emulation). RAM is SO-DIMM upgradable to 64GB if the stack + CI ever feel tight.

You’ll need: a 16GB+ USB stick, wired Ethernet (strongly recommended), monitor + keyboard for the install only.

Phase 0 β€” while macOS is still on it (~15 min)

  1. Update macOS fully. T2/bridgeOS firmware only updates through macOS; get current firmware before Linux takes over.

  2. Enable restart-after-power-failure while you still can (stored in SMC; a headless server must come back after an outage):

    Terminal window
    sudo systemsetup -setrestartpowerfailure on
  3. Sign out of iCloud / disable Find My Mac (avoids Activation Lock issues).

Phase 1 β€” relax T2 boot security (~5 min)

  1. Boot to Recovery: hold Cmd-R at power-on.
  2. Utilities menu β†’ Startup Security Utility:
    • Secure Boot β†’ No Security
    • External Boot β†’ Allow booting from external media
  3. Shut down.

Phase 2 β€” build the installer USB (~15 min)

  1. Download the current T2-Ubuntu 24.04 LTS ISO from the t2linux project: start at https://wiki.t2linux.org β†’ Distributions β†’ Ubuntu; ISOs are on the t2linux/T2-Ubuntu GitHub releases page.

  2. Write it to USB with balenaEtcher, or:

    Terminal window
    diskutil list # find the USB, e.g. disk4
    diskutil unmountDisk /dev/disk4
    sudo dd if=~/Downloads/t2-ubuntu-24.04*.iso of=/dev/rdisk4 bs=4m status=progress

Phase 3 β€” install (~30 min)

  1. Plug USB + Ethernet + monitor/keyboard into the mini. Power on holding Option, pick EFI Boot.
  2. Install Ubuntu. Choices that matter:
    • Erase disk is fine β€” but consider leaving a ~60GB macOS partition (t2linux recommends keeping macOS around for future T2 firmware updates; a 512GB drive can afford it). If keeping it, use β€œInstall alongside” / manual partitioning.

    • Avoid the 100GB LVM trap: the Ubuntu installer’s LVM default caps the root LV at 100GB regardless of disk size. Give root the full space, or fix post-install:

      Terminal window
      sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
      sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
    • User larry, hostname dev.

  3. Reboot into Ubuntu (Option-boot again if it doesn’t come up as default; the default boot volume can be set later with efibootmgr).

Phase 4 β€” post-install T2 housekeeping (~15 min)

  1. The T2 ISO ships a patched kernel; add the t2linux apt repo (instructions on the wiki’s Ubuntu page) so kernel updates stay T2-compatible. A stock kernel update can cost you the internal SSD driver at next boot β€” never install a non-t2 mainline kernel.

  2. Wi-Fi/Bluetooth firmware (optional β€” skip for a wired server): the wiki’s get-apple-firmware script pulls it from the macOS partition or Apple’s servers.

  3. Basics:

    Terminal window
    sudo apt update && sudo apt install -y openssh-server
    sudo systemctl set-default multi-user.target # if the ISO installed a desktop
  4. Reserve 10.1.1.15 for its MAC in DHCP (or set a static IP).

  5. Pull the monitor/keyboard; it’s a server now.

Phase 5 β€” fleet provisioning (~20 min)

From here follow the standard dev-box provisioning (same steps as the 2026-09-08 original .15 build):

  1. From the main Mac: ssh-copy-id -i ~/.ssh/nightly-audit.pub [email protected]

  2. Passwordless sudo:

    Terminal window
    echo 'larry ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/larry-nopasswd
    sudo chmod 440 /etc/sudoers.d/larry-nopasswd
  3. Packages: git build-essential curl jq python3 docker.io docker-compose-v2 plus Node 22 via NodeSource (setup_22.x β€” not Node 20; @supabase/realtime-js needs native WebSocket). usermod -aG docker larry.

  4. GitHub runner: delete any stale offline theaccessible-runner-15 entry from the repo’s runner list first, then register a fresh runner with labels theaccessible-ci,theaccessible-test and install it as a service (sudo ./svc.sh install larry && sudo ./svc.sh start).

  5. Generate a machine SSH key, add as a read-only deploy key on the repo, clone to ~/accessible, copy compose secrets (.env, .env.node-server, .env.grafana) from the main Mac, recreate docker-compose.override.yml (LAN port exposure), then build the dev stack staged β€” COMPOSE_PARALLEL_LIMIT=2 β€” a full-parallel 25-image build can starve sshd on small boxes.

Hardware gotchas

  • T2 kernel dependency is permanent β€” keep the t2linux apt repo (step 12).
  • Internal audio and Touch ID don’t work under Linux; irrelevant for a server.
  • Black screen after an update: Option-boot β†’ the USB stick still works; the t2linux wiki has recovery steps.
  • 16GB RAM (2Γ—8GB β€” both slots filled, upgrades replace both sticks) is fine for the runner role and worth keeping. DDR4 SO-DIMM prices spiked as DDR4 production wound down (checked 2026-09: ~$200 for 2Γ—16GB, $400+ for 2Γ—32GB new), so an upgrade no longer pencils out β€” if it ever swaps under real load, shop used laptop pulls on eBay (DDR4-3200 kits also work; they downclock to 2666). The swap itself is a near-full teardown (logic board slide-out, TR6 security Torx), so pair it with any other reason to open the case.