← Back to blog

How to turn an end-of-life iMac 5K into a Debian dashboard system

Repurposing an unsupported iMac into a headless Debian kiosk with automation and hardening.

Jelle De Laender

iMac 5K running a Debian headless kiosk status dashboard in the office.

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.

Hardware overview

The system used in this setup:

  • iMac 5K 27-inch
  • Intel CPU: i7, 8 cores
  • 32 GB RAM
  • AMD GPU
  • SSD storage
  • Integrated 5K Retina display
  • Wired Ethernet

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.

Design goals and mindset

Before installing anything, we defined a few non-negotiables:

  • Use Debian, not a desktop-oriented distribution
  • No keyboard or mouse required after installation
  • Chromium running full-screen in kiosk mode
  • Treat it like infrastructure (not a personal workstation)
  • No manual logins required
  • Recover automatically on crashes
  • Be controllable remotely
  • Minimal attack surface
  • Sustainable hardware reuse

This mindset drove almost every technical decision that followed.

Step 1: Installing Debian, minimal and explicit

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:

  • EFI boot mode
  • Non-free firmware enabled
  • Minimal system utilities only
  • No desktop environment
  • No display manager

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 -v

If 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
btop on the iMac.
btop results on our iMac 5K during an internet speed test

Step 2: Making the system truly headless

Although a display is attached, we intentionally avoided all desktop assumptions:

  • No graphical login
  • No local user interaction
  • Everything started via systemd

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.service

Instead of relying on interactive console access, we created a dedicated kiosk user and used systemd services and timers for automation.

Step 3: GPU firmware and the 5K display

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-graphics

To 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.

Step 4: Installing Chromium for kiosk usage

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 chromium

We 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

Step 5: Solving the double-screen issue

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 xrandr

If the dashboard appears split or misaligned, revisit the xrandr configuration. The internal 5K panel often reports multiple logical outputs.

Step 6: Supervising Chromium and handling crashes

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
Debian kiosk boot showing a kernel X server I/O error.
X-Server error at boot on the iMac

Step 7: Hiding the mouse cursor

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 unclutter

unclutter 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 &

Step 8: Sensors and hardware monitoring

Because this system is always on, we wanted visibility into hardware health.

apt install lm-sensors
sensors-detect

This provides insight into CPU temperature, thermal stability, and fan behavior over time.

Step 9: Fan control on iMac hardware

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 macfanctld

Once 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.

Step 10: Disabling sleep and power management

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.target

Second, 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=ignore

Then we restarted logind to apply the changes:

systemctl restart systemd-logind

Finally, 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 noblank

In 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.

Step 11: Local control API

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.

Step 12: Integration with Homey

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.

Homey running in the office automation setup.
Homey Pro at our office

Step 13: Security hardening choices

Even though this is just a screen, security still matters.

  • SSH access limited to the internal network
  • Strong SSH configuration
  • No root SSH login and no password logins
  • Minimal installed packages
  • Apache bound only to local interfaces
  • Fail2ban monitoring the logs
  • Regular unattended security updates

We also recommend verifying Fail2ban is active and monitoring SSH:

fail2ban-client status
fail2ban-client status sshd

Automation gotcha: cron permissions

We 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-job

This 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

Apple hardware quirks under Linux

Running Linux on Apple hardware works well, but there are a few non-obvious quirks worth calling out.

  • Fan control is not handled correctly without macfanctld
  • High-DPI internal panels may expose multiple logical outputs
  • EFI boot order can change unexpectedly after firmware events
  • Power management defaults assume a laptop or desktop, not an appliance

None of these are blockers, but they require explicit handling. Once addressed, the system behaves predictably.

Final behavior

  • Power on
  • Debian boots unattended
  • Chromium launches full screen
  • Dashboard fills the entire 5K display
  • Automatic recovery on crashes
  • Remote control via Homey
  • No keyboard or mouse required
Status dashboard on the Debian kiosk display showing an error state.
Status page on the iMac during an incident

Next steps

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.)

Sustainability and hardware reuse

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.