My personal tips for working from home
Remote working and working from home are completely two different concepts. Remote working is working from home, but also coworking spaces…
Read My personal tips for working from homeRepurposing an unsupported iMac into a headless Debian kiosk with automation and hardening.
At the office, we had an older iMac 5K that had reached the end of its practical life as a macOS machine. Apple no longer supports the latest macOS releases on this model, which meant modern Xcode versions were unavailable and CI workloads that depended on recent SDKs became increasingly fragile. As a macOS device, it was effectively end of life.
From a hardware perspective, the story was very different.
This iMac still had a capable Intel CPU, plenty of RAM, fast SSD storage, and an excellent 5K display. Throwing that away felt wasteful. Instead, we decided to repurpose it as a secure, headless Debian-based status display: permanently on, fully automated, and controlled as infrastructure rather than a workstation.
This article is a practical how-to guide. It documents the full setup, the problems we ran into, and the troubleshooting steps we needed to make an iMac 5K behave like a reliable Linux appliance. It also highlights the security choices we made, because even a status screen deserves defensive thinking.
Back in 2019 we upgraded a Mac Mini to run Jenkins (full write-up here). This iMac eventually took over until Apple ended macOS support for the model. We now run macOS builds in Apple’s Xcode Cloud, and keep Jenkins on this iMac on Debian with current OS updates.
Note: this write-up is based on an iMac 5K 27-inch (Late 2014) with an AMD GPU. Other Intel-based iMac generations are similar, but the 5K panel behavior can differ slightly.
The system used in this setup:
While macOS support stagnated, these specifications remain more than sufficient for Linux. In practice, this machine performs comfortably as an always-on dashboard system.
Practical note: the 5K panel is a special case. On some Linux setups it appears as two logical outputs. That can influence kiosk layout choices later in this guide.
Before installing anything, we defined a few non-negotiables:
This mindset drove almost every technical decision that followed.
We downloaded the Debian netinstaller, flashed it onto a thumb drive, and booted the iMac from it to perform a clean, non-graphical base install with proper disk formatting and swap.
Debian Trixie gives a modern base for a headless kiosk, with long-term security updates and predictable package behavior.
Key installation choices:
After installation, we explicitly verified EFI boot entries. Apple firmware sometimes makes surprising choices about boot order. Verifying this early prevents confusing boot failures later.
efibootmgr -vIf you are installing Debian 13 or newer, ensure your APT sources include non-free firmware. On Debian this is done by adding the component "non-free-firmware" to your repository lines.
deb http://deb.debian.org/debian trixie main contrib non-free-firmware
Although a display is attached, we intentionally avoided all desktop assumptions:
We considered disabling getty on the primary console. In practice, keeping tty1 available can be useful for recovery. If you do disable it, ensure you have reliable SSH access and a fallback plan.
systemctl disable getty@tty1.serviceInstead of relying on interactive console access, we created a dedicated kiosk user and used systemd services and timers for automation.
The iMac 5K uses an AMD GPU paired with a very high DPI internal panel. We explicitly installed the required firmware. Without this, display behavior was inconsistent and sometimes unusable.
apt install firmware-amd-graphicsTo verify the kernel driver is bound correctly:
lspci -nnk | grep -A3 -E 'VGA|3D'If you hit a black screen after reboot, this is the first place to look. Firmware and output detection are usually the culprits.
We initially tested Google Chrome, but switched to Chromium for the final setup. Chromium integrates cleanly with Debian package management, avoids an external vendor repository, and fits better with a minimal, security-conscious, always-on system.
apt install chromiumWe launch Chromium in kiosk mode with a curated set of flags to remove distractions and reduce accidental exit paths.
chromium \
--kiosk \
--noerrdialogs \
--disable-infobars \
--no-first-run \
--disable-session-crashed-bubble \
--disable-features=TranslateUI \
--disable-pinch \
--overscroll-history-navigation=0 \
https://status.semonto.com/#display-mode
One of the most time-consuming problems was how the 5K panel presents itself to Linux. Internally, it may appear as multiple display outputs. Chromium then behaves as if two screens exist, which leads to incorrect spanning, off-center rendering, and broken full-screen behavior.
We solved this by running a minimal window manager (Openbox) and being explicit about the display layout. On this iMac, running Chromium directly under X without a WM could result in only half the panel being used.
If you prefer to solve it via xrandr, you can inspect the outputs and experiment with enabling a single combined mode. Auto-detection was unreliable on this hardware, so we treated display layout as a configuration problem, not a guess.
DISPLAY=:0 XAUTHORITY=/home/display/.Xauthority xrandrIf the dashboard appears split or misaligned, revisit the xrandr configuration. The internal 5K panel often reports multiple logical outputs.
Chromium is treated as unreliable by design. It is launched via a systemd service that starts on boot, automatically restarts on crash, and can be restarted remotely.
This is critical. The system must recover without human intervention. At this point, the iMac already behaved more like a digital signage appliance than a computer.
If Chromium does not start, check the systemd service logs and confirm the display environment variables are set correctly.
One subtle failure mode we hit is a race condition at boot: X may start before the 5K panel outputs are reported as connected. This can lead to X errors and a black screen.
A pragmatic fix is to delay X startup until the DRM connector reports a connected output (without relying on dmesg permissions):
# wait up to ~15s for any DRM output to become connected
for i in {1..15}; do
grep -q "connected" /sys/class/drm/*/status 2>/dev/null && break
sleep 1
done
Even without a physical mouse attached, X will still display a cursor by default. On a wall-mounted dashboard, a visible cursor is distracting and makes the system look unfinished.
We installed unclutter to automatically hide the mouse cursor when it is not in use. This works reliably at the X level and survives Chromium restarts.
apt install unclutterunclutter is started alongside the display session and ensures the cursor disappears after a short idle period. Once enabled, the dashboard remains visually clean and kiosk-like.
We use an immediate hide to keep the display clean:
unclutter -idle 0 &Because this system is always on, we wanted visibility into hardware health.
apt install lm-sensors
sensors-detectThis provides insight into CPU temperature, thermal stability, and fan behavior over time.
Apple hardware does not always expose fan control in a Linux-friendly way by default. On this iMac, fan speeds were too low under load, and the system ran warmer than expected.
We installed macfanctld to actively control fan speed based on temperature sensors.
apt install macfanctldOnce enabled, thermal behavior became predictable and long-term stability improved significantly.
If the system runs hot, verify macfanctld is running and reading the sensors correctly.
Debian defaults are optimized for desktops. For a wall-mounted kiosk we want the exact opposite: never suspend and never blank the display.
We disabled power management at multiple layers: systemd sleep targets, logind idle handling, and X-level screen blanking / DPMS.
First, we prevented suspend/hibernate at the OS level by masking the relevant systemd targets:
systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.targetSecond, we ensured systemd-logind does not trigger any idle actions or react to suspend keys. In /etc/systemd/logind.conf we set:
[Login]
HandleSuspendKey=ignore
HandleHibernateKey=ignore
HandleLidSwitch=ignore
IdleAction=ignoreThen we restarted logind to apply the changes:
systemctl restart systemd-logindFinally, we disabled X screen blanking and DPMS (display power management). These commands are executed when the kiosk display session starts:
xset s off
xset -dpms
xset s noblankIn practice, we discovered a fourth layer: Xorg and the GPU driver may re-enable DPMS timers even if you run xset. Symptoms include the display turning off after 10 minutes even though the system is still running.
To make DPMS behavior deterministic, we disabled blanking at the Xorg configuration level:
# /etc/X11/xorg.conf.d/10-dpms-off.conf
Section "ServerFlags"
Option "BlankTime" "0"
Option "StandbyTime" "0"
Option "SuspendTime" "0"
Option "OffTime" "0"
EndSection
Section "Monitor"
Identifier "iMacPanel"
Option "DPMS" "false"
EndSection
With these layers in place, the iMac stays awake and the 5K panel keeps showing the status page indefinitely.
To make the dashboard manageable without SSH access, we exposed a small local control API. This allows the system to be controlled and recovered remotely without granting shell access.
The API is implemented using Apache and a small set of PHP scripts. It is intentionally minimal, only accessible on the internal network, and protected with lightweight authorization.
The API exposes a limited and explicit set of actions. These include restarting Chromium, refreshing the currently displayed page, switching between predefined dashboard URLs, and turning the display on or off.
Display power control allows the screen to be switched off outside office hours and re-enabled automatically when needed. This avoids unnecessary screen wear while keeping the system itself running.
This control layer turns the iMac from a passive screen into a remotely recoverable and automatable appliance, without exposing system-level access.
If the API is not reachable, verify Apache binding and firewall rules on the internal network.
Homey is our office automation hub. We already use it for everything from the Christmas tree (yes, already) to lighting, radio controls, and other routines.
Now Homey also controls the iMac display state and which status page is rendered. The local API makes the dashboard part of the broader Homey flows and automations.
Homey interacts with the dashboard exclusively through this API. This enables automations such as showing a different dashboard during incidents, refreshing the screen on a schedule, or powering the display based on office presence.
Even though this is just a screen, security still matters.
We also recommend verifying Fail2ban is active and monitoring SSH:
fail2ban-client status
fail2ban-client status sshdWe run some weekly automation via /etc/cron.d. One failure mode surprised us: cron ignores files that are group-writable or world-writable and logs 'INSECURE MODE'.
If your job never runs, check permissions first:
ls -l /etc/cron.d/your-job
chmod 600 /etc/cron.d/your-job
chown root:root /etc/cron.d/your-jobThis is a security feature. It prevents privilege escalation through writable cron definitions.
We only discovered the issue because Semonto Cron Job monitoring flagged a missed run. That feedback loop was worth it. Semonto Cron Job monitoring
Running Linux on Apple hardware works well, but there are a few non-obvious quirks worth calling out.
None of these are blockers, but they require explicit handling. Once addressed, the system behaves predictably.
This iMac now runs internal services like a VPN server, a Jenkins server, and a business insights tool. We also want to do some more fun things with the speakers, camera, microphone, AI projects, and more, which will be a topic of one of the next office hackathons. Stay tuned! (All within GDPR, of course.)
This setup is a reminder that macOS end of life does not mean hardware end of life. By replacing the operating system and narrowing the purpose, we extended the useful life of an expensive device by years.
It is a practical example of sustainable hardware reuse in a modern office.
Keep reading
Recent posts that share topics with this article.
Remote working and working from home are completely two different concepts. Remote working is working from home, but also coworking spaces…
Read My personal tips for working from home
After moving all my photos from Adobe Lightroom, with Dropbox as cloud storage to sync and backup, to Apple’s iCloud and Photos, there was…
Read How to downgrade or cancel your Dropbox account
2FA on a secondary Apple Developer Account — not primary account. Simple steps to get it working again
Read Enabling 2FA on your (not primary) Apple Developer Account
Getting the SSD in our Mac Mini 2011, fixing Jenkins after upgrading to High Sierra that deleted our Jenkins user
Read Installing SSD on Mac Mini for dual drive and installing Jenkins on macOS