Skip to content

Instantly share code, notes, and snippets.

@hank
Created July 16, 2026 21:16
Show Gist options
  • Select an option

  • Save hank/7de9ffb34e26c4e2006c29ba9614810e to your computer and use it in GitHub Desktop.

Select an option

Save hank/7de9ffb34e26c4e2006c29ba9614810e to your computer and use it in GitHub Desktop.
arch4kids
#!/usr/bin/env bash
#
# post-install.sh — Pangolin 11 kids' machine
# Run ONCE after first boot of the lean Arch base install, as root:
# sudo bash post-install.sh
#
# Assumes: base + linux-lts installed per the guide, NetworkManager running,
# and you're logged in as your admin (wheel) user using sudo.
set -euo pipefail
if [[ $EUID -ne 0 ]]; then
echo "Run with sudo." >&2
exit 1
fi
ADMIN_USER="${SUDO_USER:-}"
if [[ -z "$ADMIN_USER" || "$ADMIN_USER" == "root" ]]; then
read -rp "Your admin username: " ADMIN_USER
fi
echo "==> Full system update"
pacman -Syu --noconfirm
echo "==> Installing lean GNOME + audio + tools"
pacman -S --noconfirm --needed \
gdm gnome-shell gnome-control-center gnome-console nautilus loupe \
gnome-software malcontent flatpak xdg-desktop-portal-gnome \
xdg-user-dirs gnome-keyring gvfs \
power-profiles-daemon bluez bluez-utils \
pipewire wireplumber pipewire-pulse pipewire-alsa \
fwupd zram-generator
echo "==> Configuring zram swap (half of RAM, capped at 8G)"
cat > /etc/systemd/zram-generator.conf <<'EOF'
[zram0]
zram-size = min(ram / 2, 8192)
compression-algorithm = zstd
EOF
echo "==> Enabling services"
systemctl enable gdm.service
systemctl enable bluetooth.service
systemctl enable power-profiles-daemon.service
systemctl enable fstrim.timer
echo "==> Setting up Flathub"
flatpak remote-add --if-not-exists flathub \
https://dl.flathub.org/repo/flathub.flatpakrepo
echo "==> Installing kid-facing apps (Flatpak, system-wide)"
FLATPAKS=(
net._86box._86Box # Win98-era PC emulator (ROMs come as add-on)
org.libretro.RetroArch # console emulation
com.usebottles.bottles # Wine prefixes for the games that don't need 86Box
org.scummvm.ScummVM # Humongous Entertainment etc., if acquired later
# net.lutris.Lutris # uncomment if you prefer Lutris to Bottles
)
for app in "${FLATPAKS[@]}"; do
flatpak install -y --noninteractive flathub "$app"
done
echo "==> Creating kid accounts (standard users, no sudo)"
while true; do
read -rp "Add a kid account? username (blank to finish): " KID
[[ -z "$KID" ]] && break
if id "$KID" &>/dev/null; then
echo " $KID already exists, skipping."
continue
fi
useradd -m -s /bin/bash "$KID"
echo " Created '$KID'. Set their password now (or Ctrl-C to leave it locked):"
passwd "$KID" || true
done
echo "==> Hardening odds and ends"
# No autologin: GDM default already requires login; just make sure no one
# added one. Also hide reboot-into-firmware temptations from kids by policy,
# not tech -- the firmware password from Part 0 is the real control.
mkdir -p /etc/gdm
if [[ ! -f /etc/gdm/custom.conf ]]; then
printf '[daemon]\n' > /etc/gdm/custom.conf
fi
# Kids are standard users: no wheel, no sudoers entry -- nothing to do,
# just verify:
echo " wheel group members: $(getent group wheel | cut -d: -f4)"
echo
echo "=============================================================="
echo " Done. Reboot into GDM: sudo reboot"
echo
echo " Then as $ADMIN_USER, open Settings -> Parental Controls and"
echo " lock down each kid account (app allowlist, block installs,"
echo " content rating). See Part 3 of the guide."
echo "=============================================================="
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment