-
Debian on the LincStation E1 - Turning an Android NAS into a Linux NAS
So I’ve made a one off project for a piece of hardware that was sent to me. I’ve gotten Debian 13 and OpenMediaVault 8 running on the LincStation E1, and put the installer and documentation on GitHub. The E1 is a Rockchip RK3568-based NAS with 4 GB of RAM and 64 GB of eMMC storage. It ships with Android underneath LincOS, a rather... incomplete OS. What isn’t incomplete is Linux.
Getting there involved Android debugging, gaining root through the bundled aria2 download service, and building boot images the existing bootloader could understand. The bootloader was already unlocked, which helped considerably. Getting the thing to reliably reboot took a device-tree fix. Booting Linux is one thing; having it come back after a restart is a fairly useful feature for a NAS.
What works?
Debian boots from the internal eMMC, with working 2.5 GbE, both SATA bays, fan control, and OpenMediaVault's web interface. You can keep it headless or install an LXDE desktop with HDMI output and VNC. Kernel updates work through
apt, with a hook that rebuilds the boot image. There's also a recovery boot slot.The big caveat: this is experimental. The migration worked on one E1, but the reusable installer hasn't been run end to end on a second stock unit yet. NVMe hasn't been tested, and power-off, Wi-Fi, Bluetooth, and hardware video decoding still need validation. Back up before attempting this; replacing the firmware can brick your NAS.
If you have an E1 and feel like tinkering, start with the full installation guide. It's all on GitHub, including the migration scripts and notes on what has actually been tested.
-
PowerFox is the first genuinely modern web browser for PowerPC Macs
There's been a quiet little movement of new PowerPC software lately, and the headliner is PowerFox — a brand new modern web browser for PowerPC Macs. Originally aimed at OS X 10.5 and PowerMac G5s, it now has a PowerMac G4-capable build and runs on 10.4 Tiger. Unlike previous "modern" PowerPC browsers that were duct tape and dryer lint glued to a Firefox ESR release from 2008, PowerFox is a full-fledged port with dramatically better compatibility. It's made by none other than the talented retro hacker JazzzNY, who long-time viewers (if I have such a thing) will recognize.
I really wanted to put PowerFox through its paces, and a few other new pieces of retro software while I was at it, but my PowerMac G4's PSU kicked the bucket — mid-stream, during development, no less. The PSU was so flakey the computer wouldn't go to sleep and required physically unplugging it after every shut down. Fortunately I'd already bought a replacement that I'd previously tried (and failed) to install. The difference this time is I have a modified GPU in my dual 1.4 GHz G4, the Wind Tunnel. I'm not sure if there's any official bookkeeping on this, but it has to be the loudest Mac Apple ever released. It annoys me to even have it on, but I also really like having a dual G4 — it's my most-used retro machine since it's also my dev box (2 GB of RAM and a SATA SSD).
Resurrecting the Wind Tunnel
If I'm replacing the PSU I figured I'd do something about the noise too, with a pile of fans and a fan controller.
The first time I tried this mod, I had the OEM 9200 Pro installed — the factory GPU. Apple has never been able to do things by the book, and generally that's been to the detriment of their computers. During the AGP era, Apple thought it'd be really cool to invent the Apple Display Connector, ADC for short. Not the worst idea — it shoehorned DVI + USB + power into one cable for Apple Displays — but it only delivered 100W and never adopted DVI-DL, capping it at 1920 x 1200. I swear there was a non-Apple display that used ADC, but I can't find one. I suspected my failed PSU mod last time was due to ADC, so this round I used a 9600 Pro pulled from a G5, modded by disabling pins 3 and 11 and hacking off the hook so it'd fit my G4. (I originally did this to play the very broken PowerPC port of Grand Theft Auto 3, but that's another story.)
The magic that makes the ATX PSU mod possible is a custom harness cable I bought off eBay. Everything else is a sloppy mod, and as my friend Quin said, "These computers were made for shitty mods."
Then it was time to wedge in fans. The Power Mac G4 dates back to the 2-pin fan era, where the computer literally kicks out more voltage to the fan as the CPU temperature gauge climbs. Fans have advanced a lot in the 23 years since this computer was released. My idea was to replace the bulky 120mm case fan with a Noctua. My first attempt used a 2-pin-to-3-pin adapter on Apple's existing fan header. It kinda worked, but it wasn't kicking out enough power to properly cool — the computer crashed at 70°C. I should've known I wasn't going to get away that cheaply, so the second round was a PWM fan controller, an 80mm slim Noctua, and a 60mm Noctua for the upper case. Result: a machine that used to flirt with the high 60s°C now doesn't crack 50°C. I also unplugged the nearly worthless optical bay fan. The biggest source of noise now is the PSU fan, which uses a less-common 15mm-deep fan — that's a project for another day.
It's a novelty now having a Power Mac G4 that properly goes to sleep.
PowerFox vs. AquaFox
For context: the previous "best PowerPC Mac browser" was AquaFox, a fork of TenFourFox, which was itself a fork of the last official Firefox for PowerPC Macs from 2011. The core of AquaFox is 15 years old with new features grafted on. PowerFox is different — it's a fork of Basilisk, which is an independent fork of Firefox that's still being actively developed. To break that into plain speak: Mozilla moved Firefox to the Rust programming language in 2017, and Rust doesn't have compilers for very old systems like PowerPC OS X. Basilisk kept the old C++ codebase going while bolting on modern features, and PowerFox rides on top of that. The guts are much newer than anything else on PowerPC, even if it's still hinging on an esoteric Firefox fork.
Performance is... tolerable. It's less janky than when I used X11 to pipe Firefox from a Raspberry Pi 5, but you're not going to mistake it for a modern machine.
I tried to benchmark this thing and most browser benchmarks straight up failed, likely due to memory and JavaScript requirements. Speedometer 3.1 froze after a few tests. JetStream 3 errored out (it requires WebAssembly, so realistically it was never going to work). Basemark impressively finished and scored a 9 — that's very low, but the fact it can complete the suite at all is remarkable. For reference, my M4 Pro scores 1800.
The more useful but antiquated benchmark for retro browsers is HTML5Test, which maps a browser's capabilities. PowerFox scores 449, AquaFox scores 407 — meaning PowerFox passes more tests and is more likely to render a site correctly. In BrowserAudit (similar in spirit), PowerFox passed nearly every test; AquaFox couldn't even execute the suite. Ironically, PowerFox scored higher in HTML5Test than Helium, a Chromium fork on my modern Mac. Do with that what you will.
Real-world surfing
The modern internet is a bit out of bounds for a computer this old. Just loading a Google search spikes both CPUs to near 100%. uBlock Origin Legacy is almost a requirement to lessen the JavaScript burden. PowerFox is a touch slower than AquaFox, but it can actually load Ars Technica and render it mostly correctly. AquaFox crashed the first time I loaded it and was a mess once it did open — I couldn't click on grid settings, whereas PowerFox handled it.
I was able to load my own blog, but sites like my Hotline Navigator page that lean on WebGL for the background outright don't render — you can still browse the site, you just don't get the eye candy. I did the obligatory watch-my-own-video YouTube test. Amazingly, I got to a video page, but it took two minutes for a video to load and another five before it was actually playing back, slideshow-style. Lowering the quality to 240p didn't help. Don't get me wrong, the fact this works at all is amazing — but you're not going to enjoyably surf the modern web on a PowerMac G4. The web is JavaScript-heavy, and in the era of vibe coding, expect more 5MB PNGs on homepages, leftover testing frameworks shipped to prod, and Claude Code shipping its own source files into the bundle.
The nice thing is PowerFox works well enough to use GitHub, which is huge for retro development.
Other recent PowerPC wins
While I'm here, a few other pieces of new-ish retro software worth checking out:
- Half-Life (Xash3D PPC) — the PowerPC port now has working textures. I made an entire video about Half-Life for the Mac if you want the historical deep dive.
- Noise (Signal Client for OS X) — yes, a working Signal client for OS X. It's a little rough around the edges, but the fact it works at all is wild.
- Lemoniscate — my native Hotline Server for 10.4 and 10.5, written in C with TLS 1.0 + HOPE encryption, certificate generation, and Mnemosyne search support. I covered this and Hotline Navigator's recent updates in earlier posts.
None of this turns a 23-year-old PowerMac into a daily driver, but the fact that we're getting genuinely new PowerPC software in 2026 — not just maintenance forks of forks of forks — is the most exciting thing to happen in this corner of computing in years. PowerFox alone is a bigger jump in browser capability than anything we've seen on PPC in over a decade.
Go grab it: powerfox.jazzzny.me.
-
Apple Finally Killed the Mac Pro
The Mac Pro is officially dead. After 20 years, it went out with a quiet whimper. I'd already eulogized the Mac Pro as I considered it dead but Apple finally made it official. I made a quick video with my thoughts.
-
Hotline Navigator Gets a Home, and MobiusAdmin is Here
Two quick updates on the Hotline front. First, Hotline Navigator now has a proper home at hotlinenavigator.com. Previously, if you wanted to find the client you had to dig through GitHub or my personal website. Now there's a landing page with an about, privacy policy, and a link to the source code, making it easier to find and share.
Hotline Navigator is now at 0.1.8 and includes iOS/iPadOS and Android builds for anyone willing to sideload. The last few versions have included some nice tweaks: Large File support, Inline Image Previews, a proper error modal system, extended icon support, get info, hotline url support, live username updates, TLS support, and ton of UI/UX improvements for all screen sizes. It might be the most feature rich Hotline client on the planet. Markdown support is coming in the next version.

MobiusAdmin: a macOS GUI for Mobius
The bigger news is MobiusAdmin, a native macOS app I built that wraps the Mobius Hotline server in a point-and-click interface. To be clear, I didn't write Mobius itself. Mobius is a modern, cross-platform Hotline server written in Go that's compatible with all the popular Hotline clients. What I did write is a SwiftUI front-end that lets you run and manage the whole thing without ever touching a terminal or hand-editing config files.
If you've ever wanted to spin up a Hotline server on your Mac but didn't want to wrestle with YAML and command-line flags, this is for you. MobiusAdmin includes:
- A setup wizard that walks you through initial configuration.
- One-click start, stop, and restart.
- A visual account editor with toggles for all 35 Hotline permission flags, because nobody wants to memorize access bitmasks.
- A file browser for the server's shared directory.
- News and message board management.
- A live log viewer with real-time user monitoring.
- Ban management.
- Server settings (name, description, banner, tracker registration, port) without needing a restart.
It ships as a universal binary for Apple Silicon and Intel, fully signed and notarized. The whole thing is around 55 MB and uses minimal RAM since you're basically running a Go binary with a thin SwiftUI shell on top.
One caveat: it requires macOS 14 (Sonoma) or later due to some SwiftUI APIs I leaned on. In theory you could back-port it to earlier versions, but I didn't want to maintain compatibility shims for older OS releases.
The source is on GitHub and it's free and open source, same as everything else in this little ecosystem. If you're running a Hotline server or thinking about it, give it a shot. And if you just want to connect to one, hotlinenavigator.com has you covered.
-
Hotline Navigator Updates: v0.1.5 is out
I haven't written about Hotline Navigator since I first announced it, but the project hasn't been sitting idle. Over the past few days I've pushed out four releases, each one chipping away at rough edges and adding features that make the client feel more like a proper application and less like a proof of concept. If you tried v0.1.1 and bounced off it, now's a good time to give it another look.

You can grab the latest release from the releases page. Builds are available for macOS, Windows, and Linux (ARM64) only at the time of writing this as my Linux VM died. Version 0.1.4 has a Linux x86_64 build, which doesn't have the UI polishes.
The big additions
@Mention notifications and watch words landed in v0.1.4. This existed in a earlier version but now has much more robust support. You can now get notified when someone mentions your name in chat, and if you want to track specific topics or mentions, you can add custom watch words in Settings that trigger the same notification. There's also a mute list if someone's being noisy. Pop-up toasts only appear when you're away from the tab, and everything gets logged to a notification history regardless.
News management and broadcast messages came in v0.1.3. If the server grants you the permissions, you can create news categories, folders, and articles directly in the client. Admins also get a broadcast button for server-wide messages. Admin names now show up in red in chat to mimic the original Hotline client.
Mobile-responsive UI and iOS builds were the focus of v0.1.2. The server UI now has a tab bar for Chat, Board, News, and Files on small screens, and there's a user list toggle with a live count badge. I also set up iOS build scripts and a GitHub Actions pipeline for iOS artifacts, it's not working yet but the groundwork is there. Whether that ever ships on the App Store is another question entirely. I'm not sure if it meets Apple's App Store guidelines for iOS apps, but it's there if you want to try it out.
Improvements and fixes
Here's an incomplete list of quality of life improvements:
- Simple animations for modals.
- Prefetching directories has now been removed as it caused more issues than it solved for file browsing. The performance gains came at the cost of unreliable behavior.
- Chat input auto-resizes as you type, and the view only auto-scrolls when you're already at the bottom. No more getting yanked away from something you were reading.
- Private messaging got a proper overhaul: text wraps, the input grows up to three lines, Enter sends, Shift+Enter adds a new line.
- Links in News, Boards, Server Agreement, and Chat are now clickable.
- Server agreements are now a proper modal. Previously you could just click around without agreeing.
- File browser no longer hangs on empty folders, and there's a configurable download directory in Settings.
- You can create folders in the file browser if the server allows it.
- Server banners now fade in after loading, and there's a toggle to hide them entirely.
- The icon picker got expanded with the full icon list, thanks to John over at the Hotline wiki.
- Linux Icon fixes.
Under the hood
I've updated dependencies, either updated oradded ESLint, Vitest, and Rust-side tests with clippy warnings treated as errors. CI now gates on all of these before builds go out, it's completely broken as of writing this but I'll get it working eventually. The backend board parsing also got improvements for mixed UTF-8/Mac Roman content, which helps prevent garbled posts on older servers. Hotline's encoding situation is a perpetual adventure.
What's next
A few things on my radar: user name changes don't propagate without a disconnect/reconnect, which is annoying. Hotline
hotline://link support would be nice. The biggest nut to crack is the is chat persistence. Chat history is the big weak point of the Hotline protocol itself, there's no server-side scrollback, so once it's gone, it's gone. I'm still mulling over what, if anything, I can do about that client-side or contributing to Morbius server-side support for chat persistence without breaking compatibility with the original Hotline protocol. If chat persistence is implemented, it would start to make Hotline a viable Discord alternative for chatting.Apple Media Archive
You can find my personal hotline server at
hotline.semihosted.xyz. It's also listed in the remaining public trackers that I'm aware of. It has the Hotline Navigator client for download and a treasure trove of Apple media. It is only accessible via hotline.If you want to follow along or contribute, the project is on GitHub. And if you're running a Hotline server and want to test, I'd love to hear how it works for you.
-
The Enshittening Part 2: The Enshittificator
Back in 2018, I wrote about the Enshittening, now more accurately called the "Enshittification" of the internet, the observation that we're all surfing on a river of bullshit while each contributing our own tiny tributary of turds. For those uninitiated with the concept, it's a three-stage grift befitting of the underpants gnomes.
- Hook:: The platform lures you in with a good product.
- Lock-in: The platform keeps you in its walled garden through network effects and switching costs.
- Squeeze: The platform extracts every last cent out of you by making the thing you relied on progressively worse, as you're held hostage to the platform's business model.
Most users of the internet are tacitly aware of the Enshittification cycle, even if they've never heard the word. When someone laments the state of the internet, it's enshifficiation. The Norwegian Consumer Council (Forbrukerrådet) just released a brilliant PSA that deserves to be spread far and wide.
The video accompanies the Council's report, Breaking Free: Pathways to a Fair Technological Future, replete with examples of the Enshittification cycle in action. Facebook and Instagram feeds are flooded with scams and fraudulent ads. Meta reportedly rakes in roughly $16 billion annually from fraudulent advertising on its platforms. Google Search is serving up AI-generated slop instead of actual results. Car companies charge you a subscription to heat your own car seats. OEM parts have DRM preventing repairs. Advertisements exist in operating systems. Customer service has been replaced with chatbots designed to deflect rather than help.
In my 2018 post, I wrote about Amazon's counterfeit problem, Facebook's apathy toward its role in political manipulation, and the bot-infested simulacrum of an internet. Seven years later, every single one of those problems is worse. Not just a little worse, industrially worse. Amazon is still a landfill of counterfeits and fake reviews. Facebook (sorry, Meta) still doesn't give two shits about the damage it causes. It also has an AI chatbot shoved into every one of its apps. While I won't pretend that I was able to predict the rise of AI slop, I did write:
Too lazy to make up your own bullshit? Want to build an empire of bullshit? There's an entire bullshit industry you're probably not even familiar with, even if you've heard of low-rent bullshit like Fiver. There are full-on bullshit mills to generate bullshit on your behalf!
I didn't have any answers at the time, just an observation of the problem and a small platform to raise awareness. Now I'm happy to write that there's a growing group of people who are calling out the Enshittification cycle and demanding better regulation.
What makes the Norwegian Consumer Council's effort notable is that this isn't just a funny video. They've coordinated with over 70 consumer groups across Europe and the US, and sent formal letters to policymakers in the EU, UK, and US, demanding action: stronger consumer rights, mandatory interoperability, data portability, the right to repair, and the actual enforcement of existing competition laws. You know, the kind of common-sense regulation that gets endlessly lobbied against by the same companies profiting from the enshittification cycle.
This is the sort of activism I can get behind. Let's try to make the world less shitty.
-
To use Migration Assistant or not to use Migration Assistant
You've got a new Mac. The box is open, the screen is pristine, and you're staring at the setup screen, wondering: Should I use Migration Assistant?
Whether to use Migration Assistant is a constant debate on Mac communities. Before I answer whether you should use it, we need to take a peek under macOS's hood.
The APFS Architecture: Why Your System Stays Safe
Modern Macs use APFS (Apple File System), which creates a container structure with multiple volumes. I highly recommend for an in-depth breakdown , and it has downstream reprocussions for Migration Assistant.
The
/Systemvolume is a read-only sub-partition that's sealed and cryptographically hashed. Your macOS installation files are signed, and the system volume cannot be modified by Migration Assistant, or by anything else, for that matter, outside of Apple-distributed updates. Even if Migration Assistant wanted to alter your OS, System Integrity Protection (SIP) prevents it. Even if SIP is disabled, and system file are modified, updating macOS will replace any modified files with the Apple-hashed versions.The operating system you get on your new Mac stays exactly as Apple installed it. Migration Assistant can't touch it, and that's a feature, not a limitation.
For the nerds out there, in older versions of macOS (Dating back to OS X),to bring more recent versions of OS X/macOS to older hardware or Hackintoshes, people would build scripts. Popular ones in include Pike's Script and DosDUDE1's scripts. However, due to Apple's shifting focus towards a non-modifiable core operating system, scripts became an impediment, as any update would render the computer unbootable by replacing key modified system files with non-modified versions. As this avenue became more precarious, the strategy shifted to bootloaders like Clover and later OpenCore. Prior to booting macOS, the bootloader would launch and perform active memory modifications, load in kernel extensions (Kexts) to bring driver support for unsupported hardware, bypass the Don't steal macOS protection, among other things. This had the benefit of never modifying physical files in macOS, only altering or replacing them in active memory.
In short, it's safe to use Migration Assistant on Macs running OpenCore as none of the modifications are transferrable as they only exist on the EFI partition, something that Migration Assistant is unaware of, and does not exist on Apple Silicon Mcas/
What Migration Assistant Actually Moves
So what does Migration Assistant actually transfer? Here's the complete list:
- User Home folders: Everything in
~/, including documents, desktop, downloads, and all your personal files - ~/Library: User-level settings, preferences, application support files, caches, and all the hidden configuration that makes your Mac feel like your Mac
- /Library: System-wide support files, preferences, and application data (non-system files)
- /Applications: Third-party applications (Apple's system apps are already on the new Mac, so they don't get migrated)
- Documents and user data: All user-created content across your home directories, anything that exists in ~/
- Root-level user-created folders.
Migration Assistant also identifies incompatible files during the process. Intel-only apps on Apple Silicon Macs will be flagged, though they may still run via Rosetta. Apple will likely flag them as incompatible in future macOS versions, but for now, they'll transfer and you'll get a heads-up about potential issues.
What Migration Assistant Doesn't Do: The Housekeeping Problem
Here's where things get interesting: Migration Assistant is not a janitorial service. It's a wholesale transfer tool. Everything moves over, including years of digital clutter, old preferences, cached data, and files you probably forgot existed.
You're still on the hook for cleanup in these areas:
- /Library: System-level caches, old preference files, duplicate support files from applications you've long since deleted
- ~/Library: User caches, old application preferences, obsolete support files, and remnants from apps you uninstalled years ago
- /usr: Third-party binaries and libraries that may no longer be needed or compatible
- Invisible files in ~/: Dotfiles like
.bashrc,.zshrc,.gitconfig, and other hidden configuration files that accumulate over time
The burden of decluttering falls on you. Migration Assistant preserves your data, not your good decisions. Years of accumulated files, old preferences, and cached data come along for the ride, and you'll need to clean house afterward if you want a truly optimized Mac. Tools like Onyx can assist in dumping caches for orphaned utilities.
When Migration Assistant Works Best
Migration Assistant works best under certain conditions:
- Migrating during initial setup: Running Migration Assistant at first boot is ideal, though you can also run it later from
/Applications/Utilities/Migration Assistant.app - Update macOS first: It's recommended to update macOS on the new Mac before migrating, though it's not strictly required to match versions between the two Macs
- Clean source Mac: A source Mac with no disk errors or corrupted files will migrate more reliably. Boot into recovery mode and run the disk utility.
- Reasonable file count: Hundreds of thousands of files to even millions is fine, but many millions may cause the process to struggle. Doing a bit of house cleaning is a wise move.
When to Reconsider Using It
Migration Assistant isn't always the right choice:
- Years of accumulated cruft: If your old Mac has become a digital hoarder's paradise, you might want a fresh start with selective migration instead
- Selective control: When you want to cherry-pick what comes over rather than transferring everything wholesale
- When your new Mac's volume is smaller than the source drive.
One thing that's not a blocker: architecture differences. Intel apps still run via Rosetta on Apple Silicon Macs, and Apple will flag incompatible apps in future versions. Migration Assistant handles this gracefully by flagging potential issues rather than blocking the migration.
Practical Tips for Success
If you decide to use Migration Assistant, here's how to set yourself up for success:
Before Migrating
- Update macOS on the new Mac first and the old Mac (recommended)
- Disable antivirus, firewall, and VPN software temporarily during the transfer
- Ensure both Macs are on the same network and have Wi-Fi enabled
- Have a Time Machine backup as a safety net.
During Migration
- Keep both Macs on the same network
- Close all applications on both Macs
- Be patient, large migrations can take hours
After Migrating
- Plan time for cleanup of
/Library,~/Library,/usr, and hidden files - Check for flagged incompatible files and decide what to do with them
- Test your applications to ensure everything works as expected
Alternatives
Migration Assistant isn't your only option:
- Time Machine restoration: You can use a Time Machine backup as the source for Migration Assistant, which gives you more control over timing.
- Selective manual transfer: Fresh install plus cherry-picking what you need gives you the cleanest start
- Third-party cloning tools: Tools like Carbon Copy Cloner or SuperDuper can create complete duplicates, though they come with the same housekeeping challenges
Wait, you didn't tell me if I should use Migration Assistant!
I'd argue that for most users, most of the time, you should use Migration Assistant. It's a transfer tool, but the rest of the data is your responsibility to manage. It isn't a cleaning tool, thus years of digital baggage will be along for the ride.
For more technical deep-dives on macOS migration, check out The Eclectic Light Company's excellent article on the subject, or Apple's official Migration Assistant guide.
For a tutorial on how to tame your System Data, check out my guide Reclaiming storage/space from 'System Data' in macOS: A tutorial on understanding the System Data usage.
- User Home folders: Everything in
-
Using X11 to run a modern web browser on a PowerPC Mac
The closest thing to a modern browser a PowerMac can run is ancient forks of Firefox from roughly 2014. The forked browsers like TenFourFox, InterWeb PPC, and AquaFox all ship with band-aid fixes to attempt to cobble together more modern features. Modern browsers, these are not. While a PowerPC Mac can't run a modern browser in OS X, it can display one.
This isn't OS X specific even, as X11 exists on multiple Unix-like systems and these instructions should be adaptable to other Unix-like systems as well, like SunOS.
The trick: let another computer do the heavy lifting (Firefox + modern TLS + modern JS), and have the PowerMac act like a dumb terminal that just draws windows and sends keyboard/mouse input. For this example, I'll be using a Raspberry Pi 5 with an NVMe expansion (aka Hat), but any Linux computer will do. If you don't have an always on Linxu box, the Raspberry Pi 5s are fast enough and can be had for about $100~ for the 8 GB version (recommended for this project), consume only about 4 watts idling and NVMe is entirely optional, if you're looking to do this on the cheap, just get a 32+ GB MicroSD card. Plus, you'll be able to do plenty more with a Pi 5 like PiHole for DNS level adblocking, hosting docker etc.
This project uses old-school X11 remote display technology, not VNC which largely streams pixels. The way X11 works is it sends commands like "create a window, draw text here, render this image, handle this click." The results in real-time window updates on the PowerMac, and functionality that feels like an application running (almost) natively on the Mac.
What you need
- Linux computer on the same local network as your Mac
- A PowerPC Mac running OS X (I'm on 10.5 Leopard but this should work in 10.4 Tiger)
- XQuartz installed on the Mac (Leopard's built-in X11 is old and may not behave)
- SSH access to the Pi
Step 1: Install X11 + Firefox on the Raspberry Pi
On the Pi:
sudo apt update sudo apt install -y firefox-esr x11-apps x11-utilsx11-appsgives you quick sanity-test tools likexclock.x11-utilsas well asxdpyinfoso you can confirm you're actually communicating with the Mac's X server.
Step 2: Install XQuartz on the PowerPC Mac
Leopard shipped with X11, but it's old. When I tried to use it, it didn't play nice with the Pi. Install XQuartz's X11 instead.
Grab XQuartz 2.6.1 (this appears to be the last release for Leopard):
https://www.xquartz.org/releases/XQuartz-2.6.1.html
If on Tiger, you'll probably need to experiment with older XQuartz versions; See the archive
Install it, then launch X11. You'll get an xterm window (this is NOT the same as the Mac Terminal). If it doesn't launch with a terminal open, from the menu select New Xterm window.
Step 3: Allow network clients
We'll have to make some security concessions during setup to eliminate any possible complications due to network restrictions.
In the OS X preferences, open System Preferences > Security & Privacy > Firewall, then click the lock to make changes. Click Firewall Options... and disable it.
In X11:
- Open X11 Preferences
- Go to the Security tab
- Check Allow connections from network clients
Then restart X11 (quit and re-open it). This setting often doesn't fully take effect until you relaunch.
Next, in the X11 xterm, run:
xhost +That basically says "anyone on my LAN can open windows on my X server." You can be more strict, but for a retro Mac on a home LAN, this shouldn't be too much of an issue. Once you've set up X11 you can always return to the security settings and tighten things back up.
Step 4: Confirm what X11 port you're listening on
X11 uses port 6000 + display number.
:0= port6000:1= port6001- etc.
From the X11 xterm on the Mac:
netstat -an | egrep '\.600[0-9] ' | egrep 'LISTEN|listen'If you see
6000, you're on display:0. If you see6001, that's display:1.If you see a higher than 6001, often this will create issues; reboot the Mac and try again.
Step 5: From the Pi, confirm you can reach the Mac's X11 port
On the Pi, test the port (replace with your Mac's IP and the port you saw above):
nc -vz 192.168.50.134 6001If it connects (doesn't time out), you're almost done.
Now confirm X11 is really responding:
DISPLAY=192.168.50.134:1 xdpyinfo | headYou should get output that looks similar to:
name of display: 192.168.50.134:1 version number: 11.0 vendor string: The X.Org Foundation ...
Step 6: Test a simple X app (the victory lap)
On the Pi:
DISPLAY=192.168.50.134:1 xclockIf a little clock window pops up on the PowerMac, congrats — you've got remote X working.
Step 7: Launch Firefox ESR on the Pi, display it on the Mac
On the Pi:
DISPLAY=192.168.50.134:0 \ GDK_BACKEND=x11 \ MOZ_DISABLE_WAYLAND=1 \ MOZ_DBUS_REMOTE=0 \ firefox-esr --new-instance --no-remoteA quick breakdown of the flags:
DISPLAY=...tells the Pi where to draw the GUI (your Mac's XQuartz display), the:0specifies the display number, which we confirmed earlier. 0 = port 6000, 1 = port 6001, etc.GDK_BACKEND=x11forces GTK onto X11MOZ_DISABLE_WAYLAND=1avoids Wayland paths on the PiMOZ_DBUS_REMOTE=0+--new-instance --no-remoteprevents Firefox from trying to "reuse" an existing local GUI instance
If you do not see anything, try flipping between
:0and:1based on what your Mac is actually listening on (remember::0=> 6000,:1=> 6001).Troubleshooting
While AI is a bit of scourge, the recent models of Claude and Chat GPT are excellent at debugging terminal scripts. Even as an advanced technical user, I used it quickly debug my issues when working on this project as I'm new to X11, as I was able to display xclock but not Firefox ESR.
OS X is a bit janky, I'd highly recommend 10.5 as it's supported by xQuartz officially, but I've heard that it can be hacked to work on Tiger. Ports can get "occupied" and cause issues, so a reboot can sometimes help.
Bonus: Launching Firefoxwith X11 from the PowerMac with a script
To make life more convenient, it's pretty easy to make a script to launch FireFox X11 from your PowerPC Mac. One gotcha: Leopard's built-in SSH can be too old to communicate to modern OpenSSH a modern system. You can lower your security settings on said system but the smarter move is to update SSH to a newer version. I'm using a homebrew OpenSSH binary. To install OpenSSH, install TigerBrew onto your 10.4/10.5 Mac.
#!/bin/sh # Assumes XQuartz is already running on the Mac. # Allows the Pi to open X11 windows, then SSH into the Pi and launch firefox-esr. set -eu PI_HOST="192.168.50.224" PI_USER="me" detect_mac_ip() { ip="$(ipconfig getifaddr en0 2>/dev/null || true)" [ -n "${ip:-}" ] && { echo "$ip"; return; } ip="$(ipconfig getifaddr en1 2>/dev/null || true)" [ -n "${ip:-}" ] && { echo "$ip"; return; } echo "" } MAC_X11_HOST_IP="$(detect_mac_ip)" if [ -z "${MAC_X11_HOST_IP:-}" ]; then echo "ERROR: Could not detect this Mac's LAN IP." exit 1 fi BREW_PREFIX="$(brew --prefix)" SSH_BIN="${BREW_PREFIX}/opt/openssh/bin/ssh" if [ ! -x "$SSH_BIN" ]; then echo "ERROR: Expected brewed ssh at: $SSH_BIN" exit 1 fi # Wide open version (matches the blog post steps): # DISPLAY=:0 xhost + # # Slightly less wild: allow only the Pi: DISPLAY=:0 xhost +"$PI_HOST" >/dev/null 2>&1 "$SSH_BIN" -t "${PI_USER}@${PI_HOST}" " export DISPLAY='${MAC_X11_HOST_IP}:0' export GDK_BACKEND='x11' export MOZ_DISABLE_WAYLAND=1 export MOZ_DBUS_REMOTE=0 exec firefox-esr --new-instance --no-remote "Then run it:
chmod +x launch-x11-firefox.sh ./launch-x11-firefox.sh
You can take this even further by enabling AFP on your Raspberry Pi and serving up the downloads as a network volume for your Mac.
That's it
Your 2003 PowerMac is now "running" a modern browser… in the same way a monitor is "running" Photoshop. It's stupid, it's fun, it's absolutely not efficient, and it works way better than it has any right to.
Updates
2026-01-03: Cleaned up language and syntax highlighting, added troubleshooting tips and added links to retro browsers.
-
The easiest way to install Windows 11 on an Unsupported Mac (Bypassing TPM 2.0)
What You'll Need
- A Mac or PC Windows 10 already installed via Boot Camp or other means
- Windows 11 ISO from Microsoft
- A USB thumb drive
Credit Where It's Due
These instructions are based on a post by Darall on Reddit, so credit to them for figuring this out.
The Process
You'll need to be already booted into Windows 10 for this to work. Here's the step-by-step:
- Go to microsoft.com and download the Windows 11 ISO.
- Copy the ISO onto your USB drive.
- Disconnect from the internet. For me, that meant unplugging Ethernet and disconnecting from Wi-Fi.
- Double-click the ISO you copied onto your USB drive to mount it. Make note of the drive letter it mounts as. For me, it mounted as I. Yours will probably be different.
- Open Run from the Start menu (or press Windows + R).
The Command That Makes It Work
In Run, enter:
X:\sources\setupprep.exe /product serverReplace
Xwith your ISO's drive letter.setupprep.exeis a Windows setup helper used to start an in-place upgrade from inside an existing Windows session. When you run it against a Windows 11 ISO, it still installs Windows 11 — but this mode is commonly used because it bypasses (or relaxes) some of Windows 11's hardware checks, like TPM, Secure Boot, and CPU checks. Those checks are what normally block installs on unsupported hardware.Installing
This will launch the installer. It'll take a bit. Then click Install and let it do its thing. It'll reboot a few times, and that's basically it.
Important Notes
As always, if you have important data, back it up before you start.
This doesn't just apply to Macs, it'll work on any unsupported computer. But I'm a Mac guy, so that's what I went with.
-
Hosting a Hotline server with a VPS and WireGuard to a Raspberry Pi
Time for a massive info dump.
Hotline is dated, and that complicates things as servers are very public. It was designed in a very different era of the internet. Hosting a server means exposing an IP. This isn't a huge deal, but I wanted to be able to host my files on my NAS without exposing said NAS to the internet. This is where a VPS comes in. The Mobius binary is happy on a small VPS, but storage costs money, and besides, I already have a Raspberry Pi 4 on a VLAN with my NAS as my data warehouse. The issue is I need to connect my VPS to my Raspberry Pi, which has limited access to NAS.
The trick: WireGuard stitches the two together, SSHFS mounts the Pi storage onto the VPS, and Mobius thinks everything is local. Trackers see the VPS IP, my LAN stays closed, and if the VPS dies, I can swap in a new one without touching the files, as the configuration lives on my home network. It's incredible how useful AI is when it comes to a project like this, as AI pretty much stepped me through setting up Wireguard and SSHFS.
My original plan was to use Cloudflare tunnels, as you get all the benefits of Cloudflare, and I could have skipped the VPS and hosted the server on my Raspberry Pi, but Hotline requires multiple TCP ports, which makes the tunneling more or less impossible unless you throw a lot of money at the problem. I'm not paying $10k a year to host a hotline server. But I am willing to pay $10 a year. That's where the VPS comes into play.
What this setup does
Time for the bullet points:
- Public address like
hotline.example.com:5500/5501. - All Mobius config, users, and files live on a Raspberry Pi at home.
- VPS is only the front door; it reaches the Pi over WireGuard.
- Mobius on the VPS reads/writes through an SSHFS mount.
Result: clients and trackers only see the VPS IP, while the Pi keeps the actual data tucked away on its own VLAN. For the remainder of these instructions, I'm going to skip the VLAN setup details as it's noise that doesn't matter for this guide. You can always add your own VLAN if you want. Also, to avoid over-complicating something that's already complicated, I'm writing the instructions as if you have an external HDD connected to your Pi.
1. High-level architecture
VPS: Ubuntu (I used 24.04) running Mobius, I found that CloudServer.net charged all of $10 a year for a tiny VPS (1 Core, a few gigs of RAM, 10 GB of storage)
Domain Name: I use Cloudflare to manage my DNS, but it doesn't matter who you use, though. You can find my server at Hotline.semihosted.xyz, it points to my VPS.
File Server: This is really up to you. I use a Raspberry Pi 4 with Raspberry Pi OS and have mounted my Synology NAS. My Raspberry Pi is on a VLAN, thus safer to expose it than my NAS itself.2. WireGuard: connect VPS ↔ Pi
First, we need to set up WireGuard so the VPS and Pi can see each other on a private subnet. You'll need to SSH into both machines.
2.1 Install WireGuard
On the VPS:
sudo apt-get update sudo apt-get install -y wireguardOn the Pi:
sudo apt-get update sudo apt-get install -y wireguard2.2 Generate keys
We need a public/private key pair for both the VPS and the Pi to make Wireguard work.
On the VPS:
sudo umask 077 sudo wg genkey | sudo tee /etc/wireguard/server.key | sudo wg pubkey > /etc/wireguard/server.pub echo "SERVER PRIVATE:" sudo cat /etc/wireguard/server.key echo "SERVER PUBLIC:" sudo cat /etc/wireguard/server.pubOn the Pi:
sudo umask 077 sudo wg genkey | sudo tee /etc/wireguard/pi.key | sudo wg pubkey > /etc/wireguard/pi.pub echo "PI PRIVATE:" sudo cat /etc/wireguard/pi.key echo "PI PUBLIC:" sudo cat /etc/wireguard/pi.pubKeep these four values handy:
SERVER_PRIVATE,SERVER_PUBLIC,PI_PRIVATE,PI_PUBLIC.2.3 Configure VPS
Now it's time to configure WireGuard on our VPS.
Create
/etc/wireguard/wg0.conf:[Interface] Address = 10.44.0.1/24 ListenPort = 51820 PrivateKey = SERVER_PRIVATE # NAT traffic from the tunnel out via VPS NIC PostUp = iptables -t nat -A POSTROUTING -s 10.44.0.0/24 -o eth0 -j MASQUERADE PostDown = iptables -t nat -D POSTROUTING -s 10.44.0.0/24 -o eth0 -j MASQUERADE [Peer] PublicKey = PI_PUBLIC AllowedIPs = 10.44.0.2/32, 192.168.1.0/24Swap in your keys and LAN subnet. Then allow forwarding:
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-ip-forward.conf sudo sysctl --system2.4 Configure Wirguard on the Pi
Create
/etc/wireguard/wg0.conf:[Interface] Address = 10.44.0.2/24 PrivateKey = PI_PRIVATE ListenPort = 45519 [Peer] PublicKey = SERVER_PUBLIC Endpoint = VPS_PUBLIC_IP:51820 AllowedIPs = 10.44.0.0/24 PersistentKeepalive = 25Replace the keys and VPS IP. Optional but handy if you ever route more:
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-ip-forward.conf sudo sysctl --system2.5 Bring the tunnel up
Time to stich the two together by turning the tunnel on.
On the VPS:
sudo systemctl enable --now wg-quick@wg0 sudo wg showOn the Pi:
sudo systemctl enable --now wg-quick@wg0 sudo wg showFrom VPS, confirm both the tunnel and LAN reach the Pi:
ping -c 3 10.44.0.2 ping -c 3 PI_LAN_IP # e.g. 192.168.1.503. Prepare Mobius config on the Pi
3.1 Pick a storage spot
On the Pi, pick a spot for Mobius config and files. For this example, I'm using an external drive
/mnt/storage/mobius-config. This could be entirely hosted on the Pi's intenral drive or an external NAS.sudo mkdir -p /mnt/storage/mobius-config sudo chown -R $USER:$USER /mnt/storage # or sudo chown -R piuser:piuser /mnt/storage3.2 Download and init Mobius (ARM)
We are not going to run Mobius on the Pi, just use it for storage. However, we want all the configuration files that come with Mobius. You can copy between the two machines but I was lazy and found this to be easier.
mkdir -p ~/mobius cd ~/mobius curl -L https://github.com/jhalter/mobius/releases/download/v0.20.1/mobius_server_Linux_arm64.tar.gz -o mobius_server_Linux_arm64.tar.gz tar xzf mobius_server_Linux_arm64.tar.gz chmod +x mobius-hotline-server # adjust if the binary name differs ./mobius-hotline-server -init -config /mnt/storage/mobius-configYou should now see
Agreement.txt,config.yaml,Users/,Files/, etc. on the Pi’s storage. This is your Mobius configuration and data directory, aka where your files live.4. SSH key auth from VPS → Pi
To make SSHFS work without a password prompt, we need to set up SSH key authentication from the VPS to the Pi. This is necessary so we can automatically connect to our Mobius storage on the Pi.
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "vps-to-pi" ssh-copy-id -i ~/.ssh/id_ed25519.pub piuser@10.44.0.2 ssh piuser@10.44.0.2Replace
piuserwith your actual user. If login works without a password, you are set for sshfs.5. Mount the Pi's Mobius config on the VPS via SSHFS
Now the moment of truth: mount the Mobius config directory from the Pi onto the VPS using SSHFS.
sudo apt-get update sudo apt-get install -y sshfs sudo mkdir -p /mnt/mobius-config sudo sshfs -o IdentityFile=/root/.ssh/id_ed25519,StrictHostKeyChecking=accept-new \ piuser@10.44.0.2:/mnt/storage/mobius-config /mnt/mobius-config ls -la /mnt/mobius-configIf you see
config.yamland friends, the mount worked. You can formalize this with systemd or/etc/fstablater.6. Install Mobius on the VPS
Finally, we install Mobius on the VPS itself. This is where the server will run.
cd /opt sudo mkdir -p /opt/mobius sudo chown root:root /opt/mobius cd /opt/mobius curl -L https://github.com/jhalter/mobius/releases/download/v0.20.1/mobius_server_Linux_x86_64.tar.gz -o mobius_server_Linux_x86_64.tar.gz tar xzf mobius_server_Linux_x86_64.tar.gz chmod +x mobius-hotline-server # adjust binary name if needed ./mobius-hotline-server --help7. systemd unit on the VPS
Almost done, now we need to create a systemd unit to run Mobius as a service on the VPS. Systemd will manage starting, stopping, and restarting Mobius as needed.
Create
/etc/systemd/system/mobius.service:[Unit] Description=Mobius Hotline Server (VPS using Pi storage via SSHFS) After=network.target After=wg-quick@wg0.service [Service] Type=simple WorkingDirectory=/opt/mobius ExecStart=/opt/mobius/mobius-hotline-server -config /mnt/mobius-config Restart=on-failure [Install] WantedBy=multi-user.targetReload and start:
sudo systemctl daemon-reload sudo systemctl enable mobius sudo systemctl start mobius sudo systemctl status mobius --no-pager -n 208. Verify Hotline ports
sudo ss -tlnp | grep 550You should see listeners on 5500 and 5501. From outside, test:
nc -vz -w 3 hotline.example.com 5500 nc -vz -w 3 hotline.example.com 5501Watch logs as clients connect:
sudo journalctl -u mobius --no-pager -n 509. Configure trackers and metadata
Edit
/mnt/storage/mobius-config/config.yaml(from the Pi or via the VPS mount):server: name: "The Apple Media Archive by DMG" description: "A Hotline server filled with Apple events and commercials from the 80s to today." banner: "banner.jpg" messageBoard: "MessageBoard.txt" tracker: enabled: true servers: - "hltracker.com:5499" - "tracker.preterhuman.net:5499" - "saddle.dyndns.org:5499" - "hotline.kicks-ass.net:5499"Restart to apply changes:
sudo systemctl restart mobius10. Optional: helper script for pushing new Mobius builds to the Pi
If you ever run Mobius directly on the Pi, a quick-update script helps:
#!/usr/bin/env bash set -euo pipefail MOBIUS_SRC="/home/piuser/Desktop/mobius-server-linux-arm64" MOBIUS_DST="/opt/mobius/mobius-hotline-server" echo "Stopping Mobius..." sudo systemctl stop mobius || true echo "Updating binary..." sudo cp "$MOBIUS_SRC" "$MOBIUS_DST" sudo chmod 755 "$MOBIUS_DST" echo "Starting Mobius..." sudo systemctl start mobius sudo systemctl status mobius --no-pager -n 10Make it executable:
chmod +x ~/update-mobius.sh. Run it when you drop in a new build.Wrap-up
I know that was quite a bit, but that's how you can host Mobius (Hotline server) on a VPS and have it SSH tunnel back to your home network for file storage and not expose your home network to the internet.
- WireGuard links the VPS and Pi on a private subnet.
- The Pi holds config and files on roomy storage.
- SSHFS makes that storage feel local on the VPS.
- Mobius runs on the VPS, shows the VPS IP to the world, and keeps your home network dark.
If the VPS gets nuked, you can rebuild it, remount the Pi, and be back on the Hotline trackers in minutes.
- Public address like