— Testing Rolling, Anti-Cinnamon Guardrails
This is a 2025 refresh of my Debian + Fluxbox notes, updated specifically for Debian Testing (rolling). The major addition this year is a set of guardrails to prevent Cinnamon from being installed during upgrades or via meta/task packages, plus a pre-flight step that removes Cinnamon if it already snuck in.
What’s new in this 2025 Testing update
- Targets Debian Testing (rolling) rather than a fixed stable snapshot.
- Pre-guardrail cleanup: detect and purge Cinnamon if present.
- Two-layer anti-Cinnamon safety:
- Hard APT pin refuses Cinnamon and its task/meta packages.
- Lean APT defaults disable automatic Recommends/Suggests to prevent surprise DE pulls.
- Audio modernized: media keys now use
wpctl(PipeWire-native), notamixer. - Completes the daily-driver baseline: adds CUPS and a Debian-repo browser.
Assumptions
- Fresh minimal install of Debian Testing.
- You want Xorg + Fluxbox (not a full desktop environment).
- You want NetworkManager to own networking.
- You want a clean, stable lightweight workflow even as Testing evolves.
Install command
Save the script below as debian-fluxbox-setup-testing-2025.sh, then run:
sudo bash debian-fluxbox-setup-testing-2025.sh <username>
One-shot script (2025 Testing rolling)
#!/usr/bin/env bash
###############################################################################
# Debian Testing (rolling) + Fluxbox single-shot setup (2025)
#
# PURPOSE
# Build a lean, predictable Fluxbox desktop on Debian *Testing* while
# preventing Cinnamon from being installed now or later, and while using
# PipeWire-native media keys (wpctl).
#
# BACKGROUND / DESIGN INTENT
# - Testing is great, but sometimes upgrade churn or meta/task packages can
# unexpectedly pull in a full desktop environment. You specifically saw
# Cinnamon being installed and causing issues.
# - This script adds guardrails and also performs a pre-flight cleanup:
# 1) Detect and remove Cinnamon if it already exists.
# 2) Apply permanent blocks against Cinnamon packages.
# 3) Reduce surprise pulls by disabling auto Recommends/Suggests.
#
# WHAT THIS SCRIPT DOES (STEP-BY-STEP)
# 1) Enable strict shell safety options.
# 2) Validate we are root and a target user exists.
# 3) (Optional hint) Warn if /etc/os-release doesn’t say “testing”.
# 4) Pre-guardrail cleanup:
# - Detect Cinnamon packages.
# - Purge task/meta and cinnamon* packages if present.
# - Autoremove orphaned dependencies.
# 5) Create APT guardrails:
# a) Disable automatic Recommends/Suggests.
# b) Pin/ban Cinnamon packages with Pin-Priority -1.
# 6) apt-get update.
# 7) Install a minimal graphical stack:
# - Xorg + xinit + utilities
# - Fluxbox + fonts
# 8) Install day-to-day tools:
# - NetworkManager + nm-applet
# - Thunar + automount helpers
# - arandr, numlockx
# - blueman, cbatticon
# 9) Install audio stack:
# - PipeWire + WirePlumber + pavucontrol + optional pasystray
# 10) Install printing:
# - cups + cups-client (+ optional system-config-printer)
# 11) Install a browser from Debian repos:
# - chromium and/or firefox-esr (whichever is available)
# 12) Enable NetworkManager.
# 13) Rewrite /etc/network/interfaces to loopback-only so NM owns NICs.
# 14) Create user Fluxbox config:
# - menu
# - keys (with wpctl volume keys)
# - startup
# - .xinitrc
# 15) Post-run verification summary.
#
# HOW TO RUN
# sudo bash debian-fluxbox-setup-testing-2025.sh <username>
#
# HOW TO UNDO GUARDRAILS (IF YOU EVER WANT TO)
# sudo rm /etc/apt/apt.conf.d/99lean-desktop
# sudo rm /etc/apt/preferences.d/no-cinnamon.pref
#
###############################################################################
set -euo pipefail
###############################################################################
# Resolve target username.
###############################################################################
USER_NAME="${1:-${SUDO_USER:-}}"
if [[ -z "${USER_NAME}" ]]; then
echo "Usage: sudo bash $0 <username>"
exit 1
fi
###############################################################################
# Root check.
###############################################################################
if [[ "$(id -u)" -ne 0 ]]; then
echo "Please run as root (use sudo)."
exit 1
fi
###############################################################################
# User existence check.
###############################################################################
if ! id "${USER_NAME}" >/dev/null 2>&1; then
echo "User '${USER_NAME}' does not exist."
exit 1
fi
USER_HOME="$(eval echo "~${USER_NAME}")"
###############################################################################
# Non-fatal OS hint.
###############################################################################
if [[ -r /etc/os-release ]]; then
if ! grep -qiE 'testing' /etc/os-release; then
echo "[!] /etc/os-release does not appear to say 'testing'."
echo " Continuing anyway (you may be on a testing-derived snapshot)."
fi
fi
###############################################################################
# Pre-guardrail cleanup: detect and remove Cinnamon if present.
###############################################################################
echo "[*] Checking for existing Cinnamon install..."
CINN_PKGS_INSTALLED="$(
dpkg -l 2>/dev/null | awk '{print $2}' | \
grep -E '^cinnamon($|-)|^task-cinnamon-desktop$|^cinnamon-desktop-environment$' || true
)"
if [[ -n "${CINN_PKGS_INSTALLED}" ]]; then
echo "[!] Cinnamon-related packages detected:"
echo "${CINN_PKGS_INSTALLED}" | sed 's/^/ - /'
echo "[*] Purging Cinnamon-related packages..."
apt-get purge -y \
task-cinnamon-desktop \
cinnamon-desktop-environment \
'cinnamon*' || true
echo "[*] Autoremoving orphaned dependencies..."
apt-get autoremove -y || true
echo "[*] Cinnamon removal complete."
else
echo "[*] No Cinnamon packages detected."
fi
###############################################################################
# APT guardrails to prevent Cinnamon and reduce surprise DE pulls.
###############################################################################
echo "[*] Creating APT guardrails..."
cat > /etc/apt/apt.conf.d/99lean-desktop <<'EOF'
APT::Install-Recommends "false";
APT::Install-Suggests "false";
EOF
cat > /etc/apt/preferences.d/no-cinnamon.pref <<'EOF'
Package: cinnamon
Pin: release *
Pin-Priority: -1
Package: cinnamon-*
Pin: release *
Pin-Priority: -1
Package: task-cinnamon-desktop
Pin: release *
Pin-Priority: -1
Package: cinnamon-desktop-environment
Pin: release *
Pin-Priority: -1
EOF
###############################################################################
# Update package index after guardrails are in place.
###############################################################################
echo "[*] Updating apt..."
apt-get update
###############################################################################
# Install Xorg + Fluxbox core.
###############################################################################
echo "[*] Installing Xorg + Fluxbox core..."
apt-get install -y \
xorg \
xinit \
x11-xserver-utils \
xterm \
fluxbox \
fonts-dejavu-core
apt-get install -y xbacklight || true
###############################################################################
# Networking: NetworkManager + applet.
###############################################################################
echo "[*] Installing NetworkManager..."
apt-get install -y network-manager
echo "[*] Installing NetworkManager GUI applet/tools..."
apt-get install -y network-manager-gnome || true
apt-get install -y nm-tray || true
###############################################################################
# File manager + display + input utilities.
###############################################################################
echo "[*] Installing file manager and desktop utilities..."
apt-get install -y \
thunar \
thunar-volman \
arandr \
numlockx
###############################################################################
# Bluetooth + battery tray.
###############################################################################
echo "[*] Installing Bluetooth and battery trays..."
apt-get install -y \
blueman \
cbatticon
###############################################################################
# Audio: PipeWire + WirePlumber + control UI.
###############################################################################
echo "[*] Installing PipeWire stack..."
apt-get install -y \
pipewire-audio \
wireplumber \
pavucontrol || true
apt-get install -y pasystray || true
###############################################################################
# Printing: CUPS.
###############################################################################
echo "[*] Installing printing stack (CUPS)..."
apt-get install -y \
cups \
cups-client || true
apt-get install -y system-config-printer || true
###############################################################################
# Browser(s) from Debian repos.
###############################################################################
echo "[*] Installing browser(s)..."
apt-get install -y chromium || true
apt-get install -y firefox-esr || true
###############################################################################
# Enable NetworkManager service now and on boot.
###############################################################################
echo "[*] Enabling NetworkManager service..."
systemctl enable --now NetworkManager
###############################################################################
# Make /etc/network/interfaces loopback-only for clean NM ownership.
###############################################################################
echo "[*] Setting /etc/network/interfaces to loopback-only (NM-friendly)..."
if [[ -f /etc/network/interfaces ]]; then
cp -a /etc/network/interfaces "/etc/network/interfaces.bak.$(date +%Y%m%d%H%M%S)"
fi
cat > /etc/network/interfaces <<'EOF'
# NetworkManager-friendly baseline.
# Loopback only.
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
EOF
###############################################################################
# User-level Fluxbox configuration directory.
###############################################################################
echo "[*] Creating Fluxbox config skeleton for ${USER_NAME}..."
install -d -m 0755 "${USER_HOME}/.fluxbox"
chown -R "${USER_NAME}:${USER_NAME}" "${USER_HOME}/.fluxbox"
###############################################################################
# Fluxbox menu.
###############################################################################
if [[ ! -f "${USER_HOME}/.fluxbox/menu" ]]; then
cat > "${USER_HOME}/.fluxbox/menu" <<'EOF'
[begin] (fluxbox)
[exec] (Terminal) {xterm}
[exec] (File Manager) {thunar}
[exec] (Web Browser - Chromium) {chromium}
[exec] (Web Browser - Firefox ESR) {firefox-esr}
[exec] (Network Connections) {nm-connection-editor}
[exec] (Display Settings) {arandr}
[exec] (Audio Control) {pavucontrol}
[exec] (Printers) {system-config-printer}
[submenu] (System)
[exec] (Reconfigure) {fluxbox-remote reconfigure}
[exec] (Restart) {fluxbox-remote restart}
[exec] (Logout) {fluxbox-remote exit}
[end]
[end]
EOF
fi
###############################################################################
# Fluxbox keybindings.
###############################################################################
if [[ ! -f "${USER_HOME}/.fluxbox/keys" ]]; then
cat > "${USER_HOME}/.fluxbox/keys" <<'EOF'
# Basic Fluxbox keybindings
Mod1 Tab :NextWindow (workspace=[current])
Mod1 Shift Tab :PrevWindow (workspace=[current])
Mod1 F4 :Close
Mod1 z :RootMenu
Mod1 Shift z :HideMenus
Mod1 x :ExecCommand xterm
Control Shift n :ExecCommand chromium --incognito
XF86MonBrightnessUp :ExecCommand /usr/bin/xbacklight -inc 5
XF86MonBrightnessDown :ExecCommand /usr/bin/xbacklight -dec 5
XF86AudioLowerVolume :ExecCommand wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
XF86AudioRaiseVolume :ExecCommand wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
XF86AudioMute :ExecCommand wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
EOF
fi
###############################################################################
# Fluxbox startup file.
###############################################################################
cat > "${USER_HOME}/.fluxbox/startup" <<'EOF'
#!/bin/sh
xset -b
command -v numlockx >/dev/null 2>&1 && numlockx on &
command -v nm-applet >/dev/null 2>&1 && nm-applet &
command -v blueman-applet >/dev/null 2>&1 && blueman-applet &
command -v cbatticon >/dev/null 2>&1 && cbatticon &
command -v pasystray >/dev/null 2>&1 && pasystray &
command -v fbsetbg >/dev/null 2>&1 && fbsetbg -l &
xterm -geometry 120x55+0+0 &
exec /usr/bin/fluxbox
EOF
chmod +x "${USER_HOME}/.fluxbox/startup"
###############################################################################
# .xinitrc for startx-based sessions.
###############################################################################
if [[ ! -f "${USER_HOME}/.xinitrc" ]]; then
cat > "${USER_HOME}/.xinitrc" <<'EOF'
#!/bin/sh
exec startfluxbox
EOF
chmod +x "${USER_HOME}/.xinitrc"
fi
chown -R "${USER_NAME}:${USER_NAME}" \
"${USER_HOME}/.fluxbox" \
"${USER_HOME}/.xinitrc"
###############################################################################
# Post-run verification.
###############################################################################
echo
echo "=================================================================="
echo "[*] Post-run verification"
echo "=================================================================="
echo
echo "[1/7] Cinnamon packages installed (should be none):"
if dpkg -l | awk '{print $2}' | grep -qE '^cinnamon($|-)|^task-cinnamon-desktop$|^cinnamon-desktop-environment$'; then
echo " [!] Cinnamon packages still present:"
dpkg -l | awk '{print $2}' | grep -E '^cinnamon($|-)|^task-cinnamon-desktop$|^cinnamon-desktop-environment$'
else
echo " [✓] none"
fi
echo
echo "[2/7] APT policy for cinnamon (expect Pin-Priority -1):"
apt-cache policy cinnamon 2>/dev/null || echo " (package not visible in current cache)"
echo
echo "[3/7] APT guardrail files:"
ls -l /etc/apt/apt.conf.d/99lean-desktop /etc/apt/preferences.d/no-cinnamon.pref
echo
echo "[4/7] CUPS packages:"
dpkg -l | awk '{print $2}' | grep -E '^cups$|^cups-client$' || echo " (cups not installed)"
echo
echo "[5/7] Browser packages:"
dpkg -l | awk '{print $2}' | grep -E '^chromium$|^firefox-esr$' || echo " (no Debian-repo browser installed)"
echo
echo "[6/7] PipeWire control tool (wpctl):"
command -v wpctl >/dev/null 2>&1 && echo " [✓] found at: $(command -v wpctl)" || echo " [!] wpctl not found"
echo
echo "[7/7] wpctl status (may be minimal pre-login):"
if command -v wpctl >/dev/null 2>&1; then
sudo -u "${USER_NAME}" wpctl status 2>/dev/null || echo " (no active user PipeWire session yet)"
else
echo " (skipped)"
fi
echo
echo "[✓] Setup complete."
echo
echo "Next steps:"
echo " - Log in as ${USER_NAME}"
echo " - If not using a display manager, run: startx"
echo " - Use nm-applet to join Wi-Fi"
echo
echo "Guardrails installed:"
echo " - /etc/apt/preferences.d/no-cinnamon.pref"
echo " - /etc/apt/apt.conf.d/99lean-desktop"
echo
echo "To re-enable Recommends/Suggests globally:"
echo " sudo rm /etc/apt/apt.conf.d/99lean-desktop"
echo
echo "To remove the Cinnamon block:"
echo " sudo rm /etc/apt/preferences.d/no-cinnamon.pref"
echo "=================================================================="
Additional software (optional, still fits the Fluxbox ethos)
If you want parity with the older “daily driver” list, these still pair nicely with a lightweight setup:
- Document/PDF:
evince - Media:
vlc - Office:
libreoffice - Locking:
xtrlock - Optical:
xfburn(if you still burn discs) - Scanning:
simple-scan(if you need it) - E-books:
calibre
Why I’m comfortable with these guardrails
- Testing changes quickly. The pin ensures Cinnamon can’t be reintroduced via drift.
- Lean APT defaults reduce surprises. Install “nice-to-haves” explicitly, when you want them.
- You can disable this any time. Removing two small files restores default behavior.
Quick troubleshooting
- Wi-Fi not showing up? Confirm your interfaces aren’t declared in
/etc/network/interfacesbeyond loopback and that NetworkManager is enabled. - wpctl keys not working on first boot? Log into Fluxbox once so your user PipeWire session is active; then test again.
- Printing not detected? Install model-specific drivers if needed and confirm CUPS is running.
No comments:
Post a Comment