How To Setup A Linux Server

How To Setup A Linux Server

Reading time1 min
#Linux#Servers#Tech#LinuxServerSetup#Minimalism#SysAdmin

Mastering Minimalism: Setting Up a Linux Server with Only Essential Packages

Bloat is more than an aesthetic problem in server deployments—it’s a direct invitation for security breaches, wasted CPU cycles, and unpredictable maintenance windows. Minimalist Linux installations reduce exposure, simplify post-deployment auditing, and still yield robust, production-ready environments.


Baseline: Why Minimal?

Default Linux images are rarely optimized for server roles. A fresh full-stack Ubuntu install (22.04 LTS, for reference) can top 2 GB on disk, running 40+ background services (output from systemctl list-units --type=service, if you check). Each extraneous daemon—avahi-daemon, cups, even a GUI stack—expands your attack surface and complicates incident response.

Critical tradeoff: The leaner the base, the more precise your control over dependencies—but expect more bootstrapping work.


1. Distribution Selection

Match distribution to operational needs. For controlled minimalism:

  • Debian 12 Bookworm Netinst: Stable, predictable package sets. Reliable for headless deployments.
    Download: https://www.debian.org/distrib/netinst
  • Ubuntu Server 22.04 LTS Minimal: Rapid hardware support. Decent documentation.
  • AlmaLinux 9 / Rocky Linux 9 (Minimal): RHEL ecosystem, no subscription tension.
  • Arch Linux: Extreme granularity; recommended where complete environment curation is mandatory.

Note: Examples below use Debian 12. Substitute commands for RPM-based distros if needed (e.g., replace apt with dnf or yum).


2. Install — Avoid the Defaults

Boot from your minimal ISO. In the Debian installer, when prompted:

  • Deselect everything except standard system utilities.
  • Decline desktop, print, mail, or web server meta-packages.
  • On network selection, configure only SSH if you need remote access.

Example screen, package selection:

[ ] Debian desktop
[ ] GNOME
[ ] Print server
[X] standard system utilities
[ ] SSH server

(The SSH daemon can also be installed post-boot for tighter control.)


3. System Update/patch

Log in (preferably via console/KVM first). Immediately:

sudo apt update && sudo apt full-upgrade -y

Why not partial upgrade? Kernel and critical libraries (openssl, libc) may require coordinated updates.


4. Essential Packages Only

Install down to the bone. Use --no-install-recommends to avoid cascade installs.

SSH (if missed during install):

sudo apt install --no-install-recommends openssh-server

Review /etc/ssh/sshd_config before exposing to the network. Disable root login (PermitRootLogin no) and consider key-only authentication.

Firewall:

sudo apt install --no-install-recommends ufw
sudo ufw allow OpenSSH
sudo ufw enable

Remember: ufw allow 22/tcp if you change the SSH port.

Utility Tools:

sudo apt install --no-install-recommends vim less curl socat htop

Pick editors/utilities as per staff preference.

Gotcha: Avoid build-essential unless you plan to compile software; it pulls in compilers and headers most servers never need.


5. Service Hardening

Scan enabled services:

systemctl list-unit-files --state=enabled

Expect ssh, maybe cron. Disable the rest:

sudo systemctl disable --now avahi-daemon.service
sudo systemctl disable --now cups.service

Not sure about a service?
Check for open ports with:

ss -tulpn

Tolerate only what you’ve explicitly configured.


6. Disk Usage, Orphaned Dependencies

Quick audit:

dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -nr | head -10

If you spot 300MB+ packages, double-check necessity.

Clean orphaned libraries:

sudo apt autoremove --purge -y

This step's often skipped—over time, libX11, font packages, and other cruft accumulate.


7. Role-specific Components

Do not accept metapackages or blanket stacks:

sudo apt install --no-install-recommends apache2
sudo apt install --no-install-recommends mariadb-server  # If DB layer required
sudo apt install --no-install-recommends php libapache2-mod-php

Omit optional modules for tightest footprint (a2dismod [mod] to disable Apache modules).

Monitor process sprawl:

ps aux --sort=-rss | head -7

Non-obvious: Some web servers start auto-enabling modules based on package presence. Always review /etc/apache2/mods-enabled/ or similar config directories.


8. Routine Audit Script

A quick script to detect unnecessary daemons during maintenance:

#!/bin/bash
wanted="cron sshd"
for srv in $(systemctl list-units --type=service --state=running | awk '/\.service/ {print $1}' | sed 's/\.service//'); do
  [[ "$wanted" == *"$srv"* ]] || echo "Review running: $srv"
done

Pipe that into a Slack alert or web dashboard.


Reference Checklist

StepCommand(s)Output
Updateapt update && apt full-upgrade -yUp-to-date OS, security patches applied
List servicessystemctl list-unit-files --state=enabledDetect bloat
Audit portsss -tulpnPublic/exposed services identified
Clean depsapt autoremove --purge -yDisk reclaimed

Final Considerations

Minimal Linux servers—when properly curated—bring measurable improvements in uptime, mean-time-to-patch, and incident response. The tradeoff: more up-front configuration and ongoing auditing. But uncontaminated baselines are easier to automate and reimagine, especially under CI/CD or Infrastructure as Code.

A note: not all vendor agents or backup systems are available in minimal repositories. Sometimes you’ll have to break minimalism to meet compliance or monitoring requirements. Document such exceptions ruthlessly.


Minimal isn’t about dogma; it’s about having a controlled, reliable platform that doesn’t resist you at every turn.