People have been using computers for decades. Information technology advances by leaps and bounds. As a result, yesterday’s new, powerful machines quickly become today’s obsolete hardware, gathering dust on shelves and in closets.
However, these old computers can still be useful for low-resource tasks, such as working with documents, surfing the web, and watching videos. In general, the obsolete hardware is supported by very old software — operating systems and applications — which is vulnerable and unsafe to use. New software cannot be installed or runs too slowly due to a slow CPU and a lack of memory and disk space.
I personally have two examples of such obsolete computers: an Acer Extensa 5220 laptop and an 18-year-old iMac. The iMac has a large display, and it is a shame that I cannot use it safely since its hardware is supported by the very old MacOS Lion. I tried to install several lightweight Linux distributions on it but failed because of:
- It was not easy to get the Wi-Fi card to work properly.
- The software was not responsive.
That is why I decided to experiment with NixOS on my old computers, since I know that NixOS allows fine-tuning of the operating system and other software.
Goals
- Get the old computer working.
- Use modern and secure software with available security and feature updates.
- Ensure a pleasant and responsive user experience.
Breathing new life into the old iMac
Generally, the following steps are suitable for any low-spec computer. However, we will focus more on the iMac, as it is a bit more challenging and requires more effort.
We have an iMac made in 2007:
- CPU: Core2 Duo 2.4Ghz
- RAM: 2GB
- SSD: 120GB (upgraded some time ago from HDD)
- Wi-Fi, Bluetooth
Problems we have to solve:
-
First of all, we need to remove the thick layer of dust that has collected on it.
-
The computer’s hardware is very limited, so we cannot use the graphical installer.
Furthermore, Apple computers have a Broadcom Wi-Fi card that requires a proprietary driver, which is not included in the default NixOS installation image. Of course, it’s possible to connect to the network using an Ethernet cable or tethering, but I don’t have a suitable cable and don’t want to use my mobile data.
That is why we are going to create a custom minimal ISO image with Broadcom Wi-Fi support to be able to install NixOS conveniently.
- We are going to create a NixOS configuration that is sufficient to meet the requirements of Goal 3.
Creating custom minimal installation image
Note: This step is required only for Apple computers and should be skiped for all other hardware. Simply download the minimal installation image from the NixOS website.
Prerequisites: Nix should be installed on the computer which you are going to use for creating the installation image.
Create a working directory, say custom-nixos-iso
.
Creating image with nix flakes
Create flake.nix
file with the following content:
{
description = "Custom NixOS ISO with Broadcom";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
in {
nixosConfigurations.install-iso = nixpkgs.lib.nixosSystem {
inherit system;
modules = [
({ config, pkgs, ... }: {
imports = [
"${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix"
];
hardware.enableRedistributableFirmware = true;
# boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
boot.kernelModules = [ "b43" ];
boot.blacklistedKernelModules = [ "wl" ];
networking.enableB43Firmware = true;
})
];
};
};
}
After that run in the working directory the following command:
nix build .#nixosConfigurations.install-iso.config.system.build.isoImage
The image will be placed in the result
directory.
Creating image without flakes
If you don’t want to use flake you can create installation image with ordinary nix. Create iso.nix
file with the following content:
{ config, pkgs, ... }:
{
imports = [
<nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix>
<nixpkgs/nixos/modules/installer/cd-dvd/channel.nix>
];
hardware.enableRedistributableFirmware = true;
boot.kernelModules = [ "b43" ];
networking.enableB43Firmware = true;
# boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
boot.blacklistedKernelModules = [ "wl" ];
}
Run in the working directory:
nix-build '<nixpkgs/nixos>' -A config.system.build.isoImage -I nixpkgs=channel:nixos-25.05 -I nixos-config=iso.nix
Notes on selecting Wi-Fi drivers
Actually, there are only two options:
-
The original proprietary driver,
broadcom_sta
, which provides the kernel modulewl
. -
The free driver
b43
, which requires redistributable proprietary firmware.
The best driver is the one that works for you. My experience shows that both can get the Wi-Fi card working. However, broadcom_sta
is vulnerable and, in my case, it does not work correctly and creates an incorrect ARP configuration. This means that although the Wi-Fi card obtains an IP address, it does not have access to the gateway. That is why I have enabled b43
in my Nix configurations.
If you want to try broadcom_sta
, you need to:
- Uncomment the line that enables this driver
- Activate the kernel module wl.
- Disable the B43Firmware option.
- Blacklist the b43 kernel module.
Write the image to a USB stick
You can use any suitable software for this. However, note that Ventoy should not be used for installing NixOS on Apple computers.
Booting from the USB stick
When booting your old computer, you must select the USB stick as the boot device. On Apple computers, this is done by pressing the Option key immediately after powering it on.
Setting up the Internet connection
Before you start installation you should make sure that you have working Internet connection.
First, run command
ip link
and check if you can see your Wi-Fi card in the output. In my case, it’s the wlan0
interface. If you don’t see a Wi-Fi card, it means the driver does not support your hardware. Make sure the driver is loaded (lsmod
) and try setting up an alternative driver when creating the installation image.
If Wi-Fi driver works and recognizes your hardware, configure and run your Wi-Fi connection.
wpa_passphrase YOUR_SSID > wpa.conf
sudo wpa_supplicant -B -i wlan0 -c wpa.conf
Please adjust values for your Wi-Fi network SSID
and network interface name to match your setup.
Normally, the dhcpcd
daemon is running after boot, so you should get a working Internet connection shortly. If not, make sure you have entered correct values for the SSID
and password. To check your connection run the following commands:
ip addr # check that you got an IP address
ping 8.8.8.8 # check if the Internet is accessible
Installing NixOS
Create and mount disk partitions
Notes:
- This guide assumes your disk has no existing partitions. If it does, ensure you have backed up any important data and remove all partitions before proceeding.
- In all following commands, replace
sdX
with your actual device name (e.g.,sda
,nvme0n1
). You can use thelsblk
command to list all available block devices. - You are free to partition the disk according to your needs. However, the layout below is a rather optimal setup for an older computer with limited disk space.
- The size of the swap partition should correspond to the amount of RAM in your system. In this guide, we will create a swap partition equal to system’s memory size.
To remove existing partitions use the following commands:
sudo parted /dev/sdX -- print # prints existing partitions
sudo parted /dev/sdX -- rm n # remove partition with number n
Create new partitions:
# Create partition table GPT
sudo parted /dev/sdX -- mklabel gpt
# Create boot partition
sudo parted /dev/sdX -- mkpart ESP fat32 1Mib 512Mib
sudo parted /dev/sdX -- set 1 esp on
# Create swap partition (size 2048 MiB)
sudo parted /dev/sdX -- mkpart primary linux-swap 512MiB 2560MiB
# Create root partition
sudo parted /dev/sdX -- mkpart primary ext4 2560MiB 100%
Format new partitions:
sudo mkfs.fat -F 32 -n boot /dev/sdX1
sudo mkswap -L swap /dev/sdX2
sudo mkfs.ext4 -L nixos /dev/sdX3
Mount partitions:
sudo mount /dev/disk/by-label/nixos /mnt
sudo mkdir -p /mnt/boot
sudo mount /dev/disk/by-label/boot /mnt/boot
sudo swapon /dev/disk/by-label/swap
Create NixOS configuration
sudo nixos-generate-config --root /mnt
After that open /mnt/etc/nixos/hardware-configuration.nix
sudo -e /mnt/etc/nixos/hardware-configuration.nix
If you use b43
Wi-Fi driver then make sure that broadcom_sta
is not set up.
Add noatime
option to root file system configuration.
Replace the entire contents of /mnt/etc/nixos/configuration.nix
with the following configuration. Adjust it according to your needs.
# This configuration.nix file is optimized for an old (2007) iMac.
# It can be adapted for any old computer with weak hardware.
# To do this, you just need to configure it for your specific hardware:
# Wi-Fi card, video driver, printer, etc. Along with that, you may
# choose your preferences for locale, basic system software, themes, etc.
{ config, lib, pkgs, ... }:
{
imports = [ ./hardware-configuration.nix ];
hardware = {
# Wi-Fi card and Bluetooth on iMac require redistributable firmware
enableRedistributableFirmware = true;
# Enable harware graphics support
graphics = {
enable = true;
enable32Bit = true;
};
# Enable Bluetooth support
bluetooth = {
enable = true;
powerOnBoot = true;
package = pkgs.bluez;
settings = {
General = {
Experimental = true;
ControllerMode = "dual";
FastConnectable = true;
};
};
};
};
boot = {
# Use EFI bootloader
loader = {
systemd-boot = {
enable = true;
configurationLimit = 5;
};
efi.canTouchEfiVariables = true;
};
};
# Enable compressed RAM swap. Useful for low RAM systems
zramSwap = {
enable = true;
# Allow utilizing 60% of RAM for compressed swap
memoryPercent = 60;
};
# Configure networking
networking = {
# Use network manager
networkmanager.enable = true;
# Set desired host name
hostName = "nixos";
# Enable firmware to make Wi-Fi card working (in my case BCM4321)
enableB43Firmware = true;
};
# Setup time zone and locale
time.timeZone = "Europe/Moscow";
i18n.defaultLocale = "ru_RU.UTF-8";
# Configure services
services = {
# GUI
xserver = {
# Enable X server
enable = true;
# Setup video driver. Old iMac has Radeon graphics card
videoDrivers = [ "radeon" ];
# Configure lightweight display manager
displayManager = {
lightdm = {
enable = true;
greeters.gtk.enable = true;
};
# The following commands are to configure a good-looking default GUI
# theme. The script does not change the user settings made manually.
sessionCommands = ''
set_default() {
local ch="$1" key="$2" val="$3" type="$4"
if ! xfconf-query -c "$ch" -p "$key" >/dev/null 2>&1; then
xfconf-query -c "$ch" -p "$key" -s "$val" --create -t "$type"
fi
}
set_default xsettings /Net/ThemeName "Arc-Dark" string
set_default xsettings /Net/IconThemeName "Papirus-Dark" string
set_default xsettings /Gtk/CursorThemeName "Bibata-Modern-Classic" string
set_default xsettings /Gtk/CursorThemeSize "24" int
set_default xfwm4 /general/theme "Arc-Dark" string
set_default xsettings /Gtk/FontName "Inter 10" string
'';
};
# Setting XFCE as a desktop manager. It is rather lightweight but
# feature-reach
desktopManager.xfce.enable = true;
# Configure multi language support. This section could be omitted because
# XFCE supports configuring keyboard layout switching.
xkb = {
layout = "us,ru";
# Swithch keyboard layouts with CMD+Space like by default on Mac
options = "grp:win_space_toggle";
};
};
# Configure autologin for your user. Weak computers usually do not intended
# to be used by several users. So this configuration can be useful. If you
# want more than one user just omit this section.
displayManager = {
autoLogin = {
enable = true;
user = "your-user-name";
};
};
# Configure multimedia support
pipewire = {
enable = true;
# Enable alsa comatibility
alsa.enable = true;
# Enable pulse audio comatibility
pulse.enable = true;
wireplumber = {
enable = true;
# Configure audio support via Bluetooth
extraConfig = {
"50-bluez" = {
monitor.bluez.properties = {
bluez5 = {
enable-msbc = true;
enable-sbc-xq = true;
enable-hw-volume = true;
roles = [ "a2dp_sink" "a2dp_source" "hsp_hs" "hfp_hf" ];
};
};
};
};
};
};
# Enable power management
tlp.enable = true;
# Enable daemon for temperature monitoring
thermald.enable = true;
# Enable SSH.
openssh.enable = true;
# Configure printing
printing = {
enable = true;
# Setup correct drivers. The following driver is for most Epson printers.
drivers = [ pkgs.epson-escpr ];
};
avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
# Enable Bluetooth manager
blueman.enable = true;
};
# Configure fonts
fonts = {
# Install most useful and popular fonts
packages = with pkgs; [
dejavu_fonts
liberation_ttf
noto-fonts noto-fonts-cjk-sans noto-fonts-emoji
inter
roboto roboto-mono
jetbrains-mono
fira-code
font-awesome
corefonts
];
# Font settings
fontconfig = {
antialias = true;
hinting.enable = true;
hinting.style = "slight";
subpixel.rgba = "rgb";
subpixel.lcdfilter = "default";
defaultFonts = {
serif = [ "Noto Serif" "DejaVu Serif" "Liberation Serif" ];
sansSerif = [ "Inter" "Noto Sans" "DejaVu Sans" "Liberation Sans" ];
monospace = [ "JetBains Mono" "Fira Code" "DejaVu Sans Mono" "Roboto Mono" ];
emoji = [ "Noto Color Emoji" ];
};
};
};
# By default XFCE installs thunar (file manager), but does not install
# thunar-archive-plugin. Here we explicitly install thunar with plugins.
# Having thunar-archive-plugin allows us cpmpress/decompress files from the
# context menu.
programs.thunar = {
enable = true;
plugins = with pkgs.xfce; [
thunar-archive-plugin
thunar-volman
];
};
# At the moment of creating this configuration file there is an issue with
# thunar-archive-plugin: it does not work with xarchiver. The following hack
# resolves the issue.
nixpkgs.overlays = [
(final: prev: {
xfce= prev.xfce.overrideScope (_self: super: {
thunar-archive-plugin = super.thunar-archive-plugin.overrideAttrs (old: {
postInstall = lib.concatStringsSep "\n" [
(old.postInstall or "")
''
mkdir -p $out/libexec/thunar-archive-plugin
cp -r ${prev.xarchiver}/libexec/thunar-archive-plugin/* \
$out/libexec/thunar-archive-plugin/ 2>/dev/null || true
''
];
});
});
})
];
# Install system-wide packages
environment = {
# Do not install any package by default. We want full control of packages
# configuration
defaultPackages = [];
# We install only the following minimum of packages. Other packages user can
# install in their profile.
systemPackages = with pkgs; [
htop ncdu iotop lm_sensors pciutils usbutils # System utilities
xfce.xfce4-terminal # Graphical terminal
xfce.xfce4-xkb-plugin # plugin to display keyboard layout variant in status bar
rofi # An utility for applications quick start and other useful features
system-config-printer # GUI utility for printer settings
arc-theme papirus-icon-theme bibata-cursors # Themes for XFCE
zathura # Document viewer
mpv # Media player
feh # Image viewer
micro # Tiny simple text editor used as default editor
neovim # Text editor for advanced users
xarchiver zip unzip p7zip xz zstd bzip2 gzip unrar # Archiver utilities
firefox # Web browser
];
# Set some environment variables
variables = {
# Default editor
EDITOR = "micro";
# Hope QT applications will look better in XFCE
QT_QPA_PLATFORMTHEME = "gtk3";
};
};
# Nix configuration
nix = {
# Configure garbage collection
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d";
};
# Additional useful settings
settings = {
auto-optimise-store = true;
experimental-features = [ "nix-command" "flakes" ];
};
};
# Allow proprietary software
nixpkgs.config.allowUnfree = true;
# Users configuration
users.users.your-user-name = {
isNormalUser = true;
extraGroups = [
"wheel" # Enables sudo for user
"networkmanager" # Enable Wi-Fi connections for user
];
};
# Enable sudo
security.sudo.enable = true;
system.stateVersion = "25.05";
}
Install the system
sudo nixos-install
After the installation process finishes, reboot the system and enjoy. Of course, you can fine-tune the system now as you like.