← the memory
systems ·

Headless Ubuntu Server from a MacBook

Converting a second-hand MacBook Pro into a production Ubuntu server — WiFi drivers, USB tethering, and headless operation

#ubuntu#linux#macbook#sysadmin#headless

Headless Ubuntu Server from a MacBook

The Hardware

Refurbished MacBook Pro (Intel) bought in Wrocław for ~800 PLN. Goal: production Ubuntu server for AI workloads, running 24/7, accessible only via SSH from my primary M1 Max MacBook.

The Challenge

MacBooks are not designed to run Linux headlessly. Three problems:

  1. WiFi: Broadcom BCM4360 — proprietary driver, no native Ubuntu support
  2. Display: Laptop lid closed = sleep/hibernate
  3. Power: Mac power management conflicts with server expectations

Solutions

WiFi: Broadcom Driver Fix

# Install proprietary Broadcom driver
sudo apt update
sudo apt install bcmwl-kernel-source
sudo modprobe wl

# Verify
iwconfig  # should show wlan0

This works on BCM4360, BCM43142, and similar chips. The wl driver is proprietary (from Broadcom via Ubuntu) — not ideal, but functional for a home server.

Headless Operation

# Prevent sleep on lid close
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target

# Disable display manager (no GUI needed)
sudo systemctl set-default multi-user.target

# Keep WiFi alive without GUI
sudo nmcli dev set wlan0 managed yes
sudo nmcli con up "Your-SSID"

USB Tethering Fallback

When WiFi fails (it does), iPhone USB tethering provides internet:

# iPhone plugged in via USB, Personal Hotspot enabled
# Ubuntu sees it as usb0 interface automatically
ip addr show usb0
# Usually gets 172.20.10.x via DHCP

This saved me multiple times during initial setup when WiFi was unreliable.

SSH-Only Access

# Hardened SSH config
sudo nano /etc/ssh/sshd_config

# Key changes:
PermitRootLogin no
PasswordAuthentication no  # key-based only
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2

sudo systemctl restart sshd

Copy public key from primary MacBook, disable password auth. Server is now reachable only from my machine.

Services Running

ServicePurposePort
sshdRemote access22
ollamaLocal LLM inference11434
hermes-gatewayAI agent gatewayvaries
uvicornFastAPI (mnemos API)8081
cronScheduled tasks

All managed via systemd user services. No Docker — direct process management for simplicity on limited hardware.

Hardware Hacks

No built-in ethernet: USB-C → Ethernet adapter for initial setup, then removed. WiFi only for normal operation.

Cooling: MacBook runs warm under AI load. Propped open 2cm for airflow, even in “headless” mode. No fan control issues on Ubuntu — thermal management works.

Power: Original MagSafe charger. No UPS. Acceptable risk for a dev server.

What I Learned

  • Proprietary drivers are reality. Open-source idealism meets hardware vendor lock-in. The wl driver works; nouvea doesn’t exist for Broadcom WiFi.
  • USB tethering is a lifeline. iPhone + USB cable = instant internet when WiFi breaks. No configuration needed on modern Ubuntu.
  • systemd is enough. For a single-server setup, systemd services + cron are simpler than Docker. One less layer to debug.
  • Refurbished hardware is viable. 800 PLN MacBook + Ubuntu = production server. Not fast, but sufficient for local LLMs and API backends.

Stack

  • OS: Ubuntu 22.04 Server (minimal install)
  • Kernel: 6.8.0-111-generic (with wl module)
  • Shell: Bash
  • Remote: SSH (key-based, hardened)
  • Scheduler: cron + systemd timers
  • Monitoring: log files + htop when needed

Server operational since March 2026. Uptime measured in weeks, not hours.