From MacBook Pro to Linux Workstation: Why I Chose the HP ZBook Ultra G1a with CachyOS
The macOS Docker Struggle
For years, my daily driver was a MacBook Pro with the M1 Max. It was a great machine. Fast, silent, beautiful display and excellent battery life. But there was one thing that kept frustrating me: macOS has no native Docker support.
For my work as a freelance developer, I need a local Kubernetes cluster with port forwards. I'm working with Spring Boot microservices, running local deployments, spinning up databases, message brokers, and various services. All in containers. On macOS, Docker always runs inside a Linux VM, and that indirection causes all sorts of headaches.
My Docker journey on macOS went something like this:
- Docker Desktop: worked fine initially, until the licensing changes made it less appealing.
- Colima: a nice CLI-driven alternative, but still a VM under the hood.
- OrbStack: genuinely impressive, the closest macOS has come to a native-feeling Docker experience.
- Rancher Desktop: another solid option, but same fundamental limitation. And port forwards would randomly stop working.
- Podman Desktop + k3d: where I eventually landed. Podman Desktop was probably the best overall experience, combined with k3d for a lightweight local Kubernetes cluster.
But no matter which tool I used, the underlying problem remained: everything runs through a VM. Port forwarding quirks, filesystem performance issues with bind mounts, networking edge cases. It never feels as seamless as just running containers on actual Linux. I was done fighting it.
Finding the Right Hardware
So I started looking for a Linux laptop. My requirements were clear: I wanted specs comparable to the latest MacBook Pro models, but without Apple's pricing. The MacBook Pro configuration I was eyeing, M4 Max with 128 GB RAM and just 1 TB SSD (because Apple's storage upgrades are absurdly expensive), came out to over €6,000 including VAT. That's a lot of money for a machine where I'd still be fighting Docker.
After a lot of research, I landed on the HP ZBook Ultra G1a 14. Here's what sold me:
- 128 GB of unified LPDDR5x RAM: just like Apple's unified memory architecture, the Strix Halo APU shares its memory pool between CPU and GPU. You can allocate up to 96 GB as VRAM for the integrated GPU.
- AMD Ryzen AI Max+ PRO 395: 16 Zen 5 cores, 32 threads, up to 5.0 GHz. Desktop-class performance in a laptop.
- Radeon 8060S iGPU: 40 RDNA 3.5 compute units, roughly on par with an RTX 4060/4070 laptop GPU. And with up to 96 GB of allocatable VRAM, it's perfect for running large LLMs locally.
- 50 TOPS NPU: dedicated AI accelerator (more on that in a later post).
- 14" OLED display: 2880×1800, 120 Hz, touch, 100% DCI-P3. Gorgeous.
- Aluminum chassis, 1.57 kg: genuinely portable for a workstation.
- HP has Ubuntu certification for this laptop, so Linux support should be solid.
The price? Just over €4,000 including VAT with the top-end APU, 128 GB RAM, 2 TB NVMe, and the OLED display. That's significantly cheaper than the comparable MacBook Pro and I get native Linux with actual Docker support.
I also came across Wendell's excellent Arch + Secure Boot guide for this exact laptop on the Level1Techs forum, which gave me confidence that the Linux experience on this machine would be solid.
Buying in Belgium
I found a good deal at zstore.be, a Belgian webshop. The service was excellent, but they did warn me that the 128 GB RAM version would take some time to deliver, presumably due to the ongoing memory shortage. So I waited, tried not to think about it too much, and then one day I got an email saying it had arrived a week early. I was thrilled. I couldn't wait to install CachyOS and start testing everything.
I also picked up the HP Thunderbolt 4 Ultra 180 W G6 to go with it. One Thunderbolt cable and I have power delivery, dual external displays, ethernet, and all my peripherals connected. Plug in, and you're at your desk. Unplug, and you're mobile. Simple.
The Specs
- APU: AMD Ryzen AI Max+ PRO 395 (Strix Halo) - 16 cores, 32 threads, up to 5.0 GHz (Zen 5)
- iGPU: AMD Radeon 8060S - 40 CUs, RDNA 3.5 (up to 96 GB VRAM from unified memory)
- NPU: XDNA 2 - 50 TOPS
- RAM: 128 GB LPDDR5x-8533 (unified, soldered)
- Storage: 2 TB NVMe Gen4, M.2 2280 (user-replaceable, one of the few upgradeable components)
- Display: 14" OLED, 2880×1800, 120 Hz, touch, 400 nits, 100% DCI-P3
- Wi-Fi: MediaTek MT7925 (Wi-Fi 7 + Bluetooth 5.4)
- Battery: 74.5 Wh
- Weight: ~1.57 kg
- Ports: 2× USB4/Thunderbolt, USB-C 3.2 Gen 2, USB-A 3.2 Gen 2, HDMI 2.1, 3.5 mm audio, Nano Kensington
The 128 GB unified memory is the killer feature for my use case. Running a local Kubernetes cluster with multiple Spring Boot microservices, a few databases, and other services can easily eat 32-64 GB of RAM. Having 128 GB means I can run all of that and have a local LLM loaded at the same time.
Why CachyOS?
I'd actually been running CachyOS on my gaming desktop at home for a few months before buying the ZBook. I had switched from Windows 11 to Bazzite first, and while Bazzite was a great introduction to Linux gaming, the immutable/atomic desktop approach felt too restrictive. Want to install something outside of Flatpak or layer an RPM? Good luck. CachyOS gave me the freedom of Arch with sensible defaults, and it felt noticeably snappier.
The gaming experience was surprisingly good too. Almost every game I play works perfectly on CachyOS, including most online games. The only holdouts are titles with Windows-only anti-cheat systems (like certain Battlefield titles), which still require a Windows boot. But the switch from Windows has been a breath of fresh air. No more forced updates, no more telemetry, no more bloat.
For the ZBook specifically, CachyOS makes even more sense:
Rolling release for new silicon. Strix Halo is bleeding-edge hardware. Driver improvements, NPU support, and firmware fixes land in the kernel constantly. On a fixed-release distro, you'd wait months for critical patches. On CachyOS, they're days away from upstream.
Performance-optimized kernels. CachyOS ships its own patched kernel (linux-cachyos) with the BORE scheduler (although recently they switched the default to EEVDF due to performance regressions with BORE), optimized compiler flags, and tweaks that make a real difference on AMD hardware.
Arch base with access to the AUR. The AUR is a massive community-driven repository with packages for practically anything you can think of: ROCm tooling, niche drivers, bleeding-edge AI frameworks, you name it. You get the power of Arch without the three-day setup marathon.
Installation
I kept the CachyOS installation straightforward. I used the standard CachyOS installer with its default partition layout (LUKS2 encryption on Btrfs with the standard subvolume setup) and limine as bootloader. Nothing fancy here; the installer handles it all nicely.
TPM-Enrolled LUKS Key
One thing I did set up after installation was enrolling the LUKS encryption key in the TPM. This means the system decrypts automatically on boot without needing to type a passphrase every time, as long as the boot chain hasn't been tampered with (Secure Boot integrity). It's the same convenience you get on a BitLocker-encrypted Windows machine, but on Linux.
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/nvme0n1pX
Adding Swap for Hibernation
After the initial install, I added a 132 GB swap partition for hibernation support. The idea was to enable suspend-then-hibernate for better battery life when I close the lid. In practice, hibernation still has issues: closing the lid and hibernating works, but when resuming from hibernation, I get a black screen. Running systemctl hibernate manually from the terminal does work correctly, so it's likely a lid-close/resume interaction issue rather than a fundamental hibernation problem.
For now, I just use regular sleep (s2idle), and honestly it's been great. With a few BIOS tweaks, disabling legacy port charging and some other settings, I only lose about 4–5% battery overnight. That's good enough that I rarely feel the need for true hibernation.
Secure Boot with sbctl
Setting up Secure Boot went smoothly. I followed the CachyOS Secure Boot guide, enrolled my own keys with sbctl, and it worked on the first try.
Keeping Everything Up to Date with Topgrade
One tool I want to highlight is Topgrade. Instead of running pacman -Syu, then updating AUR packages, then Flatpaks, then firmware, and whatever else, Topgrade does it all in a single topgrade command. It detects which package managers and tools you have installed and runs all of them in sequence. Pacman, AUR (via paru/yay), Flatpak, pip, npm, cargo, firmware updates via fwupd, everything gets updated in one go. It's one of those tools that once you start using, you wonder how you ever lived without.
GPU and VRAM Configuration
The Radeon 8060S is detected and runs with the amdgpu driver out of the box. Vulkan works immediately, no extra packages needed. In the BIOS, I set the dedicated VRAM to 4 GB, though this grows automatically beyond that as needed. To give the TTM memory manager more headroom for large VRAM allocations (important when running local LLMs), I added the following kernel parameters:
ttm.pages_limit=24576000 ttm.page_pool_size=24576000What Needed Tweaking
Wi-Fi: ASPM Issues with the MT7925
The MediaTek MT7925 Wi-Fi 7 adapter works, but ASPM (Active State Power Management) causes instability. When ASPM is enabled, the Wi-Fi connection becomes unreliable: random disconnects, slow reconnections, and general flakiness.
My solution: I wrote a systemd service that dynamically toggles ASPM based on the active power profile. On the balanced and performance profiles, ASPM is disabled for a stable connection. On the power-saver profile, it's re-enabled to save battery (with the understanding that Wi-Fi might be slightly less reliable).
The service monitors power profile changes via D-Bus and uses setpci to toggle ASPM in real-time:
- performance: ASPM off, L1 substates off
- balanced: ASPM off, L1 substates off
- power-saver: ASPM on (L1), L1 substates on (PCI-PM L1.1/L1.2 + ASPM L1.1/L1.2)
This has been working well in daily use. A proper kernel-level fix would be nicer, but this does the job. Here's the systemd service and monitor script if you want to use it:
/etc/systemd/system/wifi-aspm-monitor.service:
[Unit]
Description=WiFi ASPM monitor based on power profile
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/wifi-aspm-monitor.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target
/usr/local/bin/wifi-aspm-monitor.sh:
#!/bin/bash
# WiFi ASPM toggle based on power profile
# Adapter: MediaTek MT7925 at PCI address c1:00.0
PCI_ADDR="c1:00.0"
CAP_EXP_LNKCTL="CAP_EXP+10"
L1SUBCTL1_OFFSET="0x118"
set_aspm() {
local profile="$1"
case "$profile" in
power-saver)
# Enable ASPM L1 + all L1 substates
setpci -s "$PCI_ADDR" "$CAP_EXP_LNKCTL.W=0x0142"
setpci -s "$PCI_ADDR" "$L1SUBCTL1_OFFSET.L=0x4068000f"
echo "ASPM enabled (power-saver)"
;;
*)
# Disable ASPM + all L1 substates
setpci -s "$PCI_ADDR" "$CAP_EXP_LNKCTL.W=0x0040"
setpci -s "$PCI_ADDR" "$L1SUBCTL1_OFFSET.L=0x40680000"
echo "ASPM disabled ($profile)"
;;
esac
}
# Set initial state
CURRENT_PROFILE=$(powerprofilesctl get)
set_aspm "$CURRENT_PROFILE"
# Monitor profile changes via D-Bus
dbus-monitor --system "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='/net/hadess/PowerProfiles'" |
while read -r line; do
if echo "$line" | grep -q "ActiveProfile"; then
read -r _ # skip type line
read -r profile_line
PROFILE=$(echo "$profile_line" | grep -oP 'string "\K[^"]+')
if [ -n "$PROFILE" ]; then
set_aspm "$PROFILE"
fi
fi
done
Note: Replace the PCI address (c1:00.0) with your own. Find it withlspci | grep MT7925.
Current Kernel Status
The standard linux-cachyos kernel (6.19 at time of writing) works well for daily use. I'm currently running 7.0-rc2 to get NPU support working. The XDNA 2 NPU requires kernel 7.0 because the latest BIOS update ships NPU firmware major version 7, which isn't supported by older kernels. Getting 7.0-rc2 to boot did require fixing a regression in the AMD ISP4 (camera) driver, but more on that in a later post.
First Impressions
After a few weeks of daily driving CachyOS on the ZBook Ultra G1a, I'm genuinely excited about this machine. Podman runs natively. My local Kubernetes cluster (k3d) starts in seconds and doesn't fight the OS. The 128 GB of RAM means I can run a full microservices stack, multiple databases, and a local LLM simultaneously without breaking a sweat. Everything feels smooth, no hiccups, no lag. As a daily driver, it's been perfect.
Coming from the MacBook Pro, the things I don't miss are the Docker workarounds, the VM overhead, and paying the Apple tax. The things I do miss? Mainly the tight integration with my iPhone: iMessage, auto-filling 2FA codes from Messages or email, AirDrop. That said, KDE Connect does a good job filling part of that gap. As for the trackpad: Apple's is still the gold standard, but the ZBook's trackpad holds its own. It's not a haptic touchpad, but it's responsive and precise, and I got used to it within a few days. The keyboard I actually prefer over the MacBook, it just types better.
I keep discovering new things I like about this laptop, and I'm excited to see what future Linux kernel releases will bring for this platform. Strix Halo support is improving with every release, and it's a great time to be running Linux on this hardware.
The OLED display is gorgeous, and despite being a workstation, the ZBook is genuinely portable at 1.57 kg. On CachyOS, you're always close to the latest fixes, and both the CachyOS and Strix Halo Linux communities are incredibly active.
Have questions or running the ZBook Ultra G1a on Linux yourself? I'd love to hear about your experience.