
Reviewed and updated 28 July 2026.
If you want to learn Linux system administration, build a small environment that can fail safely. The strongest beginner projects are not one-click installations: they make you configure a service, prove it works, break it deliberately, recover it and document what you learned.
This guide contains 12 Linux system administrator projects that fit together as one home lab. They cover the practical areas in the current Red Hat Certified System Administrator objectives, including users, storage, networking, services, logs, SSH, firewalls and shell scripting. It then adds backups, monitoring, Ansible and containers.
The examples use Ubuntu Server 26.04 LTS unless a command is labelled for a RHEL-family system. Ubuntu 26.04 LTS receives standard security updates until April 2031, according to its official release notes. Commands and package names differ between distributions, so check your distribution’s documentation before using them elsewhere.
Safety first: use disposable virtual machines, take snapshots and keep a console available. Never practise storage, firewall or SSH changes on a production server. A cloud VM can generate charges and become exposed to the internet, so a local lab is the safer default for beginners.
Linux system administrator projects at a glance
| Project | Level | Typical time | Portfolio evidence |
|---|---|---|---|
| 1. Two-server home lab | Beginner | 1–2 hours | Network diagram and inventory |
| 2. Users and permissions | Beginner | 1–2 hours | Access-control matrix |
| 3. LVM storage | Intermediate | 2–3 hours | Storage map and mount tests |
| 4. Networking and firewall | Intermediate | 2–3 hours | Connectivity test record |
| 5. SSH hardening | Intermediate | 1–2 hours | Sanitised configuration |
| 6. systemd service and timer | Intermediate | 1–2 hours | Unit files and journal output |
| 7. Nginx web service | Intermediate | 2–4 hours | Architecture and validation |
| 8. Tested backups | Intermediate | 2–3 hours | Restore-test report |
| 9. Monitoring and alerts | Intermediate | 3–5 hours | Dashboard and alert evidence |
| 10. Ansible automation | Intermediate | 3–5 hours | Inventory and playbook |
| 11. Rootless containers | Intermediate | 2–3 hours | Container runbook |
| 12. Incident recovery | Advanced | 3–6 hours | Incident report |
Times are rough estimates, not deadlines. Troubleshooting is part of the project.
Prepare a safe Linux home lab
Create two local virtual machines named lab-web and lab-ops. A useful starting allocation is two virtual CPUs, 2–4 GB of RAM and 20 GB of storage per machine, but adjust it to your computer. Give both machines NAT access for updates plus a private or host-only network for lab traffic. Do not bridge them directly to an untrusted network.
Ubuntu Server 26.04 LTS is a straightforward starting point. For RHEL-style administration, use a supported RHEL release or CentOS Stream 10. Do not install the old CentOS Linux releases: CentOS Linux 7 reached end of life in 2024 and CentOS Linux 8 in 2021, as shown in the CentOS lifecycle. Kali Linux is also the wrong default for this lab; Kali’s developers say it is designed for professional penetration testing and is not recommended as a general-purpose distribution for people unfamiliar with Linux.
Update only your disposable lab machines:
# Ubuntu
sudo apt update && sudo apt upgrade
# RHEL family
sudo dnf upgrade --refreshRecord the OS version, virtual hardware, IP addresses and snapshot name in a README. Never publish real passwords, private keys, tokens or public IP addresses.
1. Build a two-server Linux home lab
Your first project is the lab itself. Set the hostnames, confirm both network interfaces and make the machines resolve each other. For a private lab, simple entries in /etc/hosts are enough; DNS can come later.
hostnamectl
ip address
ip route
resolvectl status
ping -c 3 lab-opsCreate an inventory containing hostname, role, distribution, IP address, CPU, memory and disk. Draw a small diagram showing the host computer, NAT network and private network. The project is complete when each VM can reach package repositories and communicate with the other VM over the private network.
Portfolio proof: publish the diagram and a sanitised inventory, not screenshots containing addresses or credentials.
2. Manage users, groups, permissions and sudo
Create an analyst account and a webops group on lab-web. Build a shared directory where members can collaborate without making it world-writable.
sudo adduser analyst
sudo groupadd webops
sudo usermod -aG webops analyst
sudo install -d -o root -g webops -m 2770 /srv/team
id analyst
ls -ld /srv/teamThe leading 2 in mode 2770 sets the set-group-ID bit, so new files inherit the directory’s group. Test access as the new user and confirm an unrelated user is denied.
For a least-privilege exercise, use sudo visudo -f /etc/sudoers.d/webops to allow a group only the command it needs. Validate the result with sudo visudo -cf /etc/sudoers.d/webops. Never edit /etc/sudoers with an ordinary editor; a syntax error can remove administrative access.
Portfolio proof: include an access matrix showing which user can read, write or administer each resource.
3. Configure a filesystem with LVM
Add a new, empty virtual disk to one VM. This exercise can destroy data if you select the wrong device, so confirm the target in the hypervisor and with lsblk -f. The name below, /dev/sdb, is only an example.
sudo apt install lvm2
lsblk -f
sudo pvcreate /dev/sdb
sudo vgcreate vg_lab /dev/sdb
sudo lvcreate -L 4G -n lv_data vg_lab
sudo mkfs.ext4 /dev/vg_lab/lv_data
sudo mkdir -p /srv/data
sudo blkid /dev/vg_lab/lv_dataAdd the filesystem UUID—not the changeable device name—to /etc/fstab using sudoedit. Then test before rebooting:
sudo mount -a
findmnt /srv/data
df -h /srv/dataTake another snapshot, extend the logical volume and filesystem, and document the difference between a physical volume, volume group, logical volume and filesystem.
Definition of done: the filesystem mounts by UUID after a reboot and existing test data remains readable.
4. Configure networking and a host firewall
Learn the tools before changing the network. Use ip for addresses and routes, ss for listening sockets, dig for DNS and curl for application tests.
ip address
ip route
ss -lntup
dig example.com
curl -I https://example.comOn Ubuntu, allow SSH before enabling UFW, especially when connected remotely:
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status verboseOn a RHEL-family lab, use firewalld:
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-allUse sudo nft list ruleset to inspect the underlying rules, but do not mix several firewall managers until you understand how they interact. Red Hat deprecates the iptables framework for new RHEL 9 deployments and recommends nftables for new firewall scripts.
Definition of done: document which ports are permitted, prove an allowed connection succeeds and prove a deliberately blocked test port fails.
5. Harden remote access with SSH keys
Generate an Ed25519 key on your client, protect the private key with a passphrase and copy only the public key to the server:
ssh-keygen -t ed25519
ssh-copy-id admin1@lab-web
ssh admin1@lab-webUbuntu’s OpenSSH documentation recommends validating configuration before restarting the service. In a lab, create a configuration snippet in /etc/ssh/sshd_config.d/ containing:
PermitRootLogin no
PasswordAuthentication noDo not disable password authentication until key login works in a second terminal and you have hypervisor-console access. Then validate and reload:
sudo sshd -t
sudo systemctl reload sshKeep the original session open while testing a new one. Changing the SSH port may reduce log noise, but it is not a replacement for key authentication, updates, least privilege and firewall controls.
6. Create a systemd service and timer
Create /usr/local/sbin/lab-health.sh with sudoedit:
#!/bin/sh
date --iso-8601=seconds
df -h /
uptimeMake it executable with sudo chmod 750 /usr/local/sbin/lab-health.sh. Next create /etc/systemd/system/lab-health.service:
[Unit]
Description=Write a basic lab health report
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/lab-health.shCreate /etc/systemd/system/lab-health.timer:
[Unit]
Description=Run the lab health report hourly
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.targetsudo systemctl daemon-reload
sudo systemctl enable --now lab-health.timer
systemctl list-timers lab-health.timer
journalctl -u lab-health.service --no-pagerDefinition of done: the timer survives reboot, the service exits successfully and its output is visible in the journal.
7. Deploy and validate an Nginx web service
Install Nginx on lab-web, replace the default page with a small status page, and validate every configuration change before reload:
sudo apt install nginx
sudo systemctl enable --now nginx
sudoedit /var/www/html/index.html
sudo nginx -t
sudo systemctl reload nginx
curl -I http://127.0.0.1Open only the port the lab requires. On Ubuntu, sudo ufw allow 'Nginx HTTP' permits HTTP. Do not expose a practice server to the public internet merely to obtain a certificate.
For an internet-facing extension, use a registered domain, restrictive firewall rules and a trusted TLS certificate. Ubuntu documents separate approaches for Let’s Encrypt on public servers and an internal certificate authority for private networks. Self-signed certificates are useful for learning but should not be presented as a normal production solution.
If you extend the project to WordPress, check its current PHP, MariaDB/MySQL and HTTPS requirements. WordPress does not specifically require Apache or a classic LAMP stack; Nginx is also supported.
8. Build a backup that you can actually restore
Use restic to create an encrypted lab backup. Install it with sudo apt install restic. Create a password file under ~/.config/restic/, give it mode 600, and never commit it to Git.
export RESTIC_REPOSITORY="$HOME/restic-repo"
export RESTIC_PASSWORD_FILE="$HOME/.config/restic/password"
restic init
restic backup "$HOME/lab-data"
restic snapshots
restic check --read-data
restic restore latest --target /tmp/restore-testCompare the restored files with the originals and record the time required. A repository on the same VM is acceptable only for learning the commands; it does not protect against loss of that VM. A real design needs an independent destination, protected credentials, retention rules and recurring restore tests.
Portfolio proof: publish a restore-test report and sanitised script, not the repository password or storage credentials.
9. Monitor Linux with Prometheus and Grafana
Install Prometheus and Node Exporter on the monitoring VM:
sudo apt install prometheus prometheus-node-exporter
sudo systemctl enable --now prometheus prometheus-node-exporter
curl http://127.0.0.1:9100/metrics | headAdd lab-web:9100 as a target in /etc/prometheus/prometheus.yml, validate it with promtool check config /etc/prometheus/prometheus.yml, then restart Prometheus. The official Node Exporter guide explains the host metrics exposed on port 9100.
Add Grafana using its current official installation instructions, create panels for CPU, available filesystem space and memory, and configure one useful alert. The Grafana dashboard guide provides the current workflow.
Keep ports 9090, 9100 and 3000 on the private lab network. Do not make monitoring interfaces public without authentication, TLS and network restrictions.
10. Automate configuration with Ansible
Install Ansible in a Python virtual environment on lab-ops:
sudo apt install python3-venv
python3 -m venv "$HOME/venvs/ansible"
source "$HOME/venvs/ansible/bin/activate"
python -m pip install --upgrade pip
python -m pip install ansible
ansible --versionCreate inventory.ini:
[web]
lab-web ansible_user=admin1Create web.yml:
---
- name: Configure the lab web server
hosts: web
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: Enable and start nginx
ansible.builtin.service:
name: nginx
state: started
enabled: trueansible all -i inventory.ini -m ping
ansible-playbook -i inventory.ini web.yml --check
ansible-playbook -i inventory.ini web.ymlRun the playbook again and examine whether it reports unnecessary changes. Ansible describes this desired-state behaviour as idempotence in its official introduction. Use SSH keys, keep secrets out of inventory and use Ansible Vault or another secret manager when a project genuinely needs secrets.
11. Run a service in a rootless Podman container
Install Podman and run a web container as your ordinary user on an unprivileged port:
sudo apt install podman
podman run --name lab-site -d -p 8080:80 docker.io/library/nginx:alpine
podman ps
curl http://127.0.0.1:8080
podman logs lab-site
podman inspect lab-sitePodman’s rootless mode uses a user namespace so the container does not need to run under the host’s root account. For a second iteration, mount a read-only directory of site files and make the service persistent across reboot using the current Podman Quadlet documentation.
Do not mount the host root filesystem or a container-engine socket into an untrusted container. Review image provenance, scan images where practical and pin a tested image digest for reproducible production deployments; a floating tag is acceptable only for this disposable exercise.
12. Diagnose and recover from a controlled incident
A system administrator needs to investigate, not merely install. Take a snapshot, record a healthy baseline and introduce one safe fault in the disposable lab: an invalid Nginx directive, a blocked test port or a stopped service. Do not fill the VM’s root filesystem or attack any system you do not own.
Work through the problem in a repeatable order:
systemctl --failed
systemctl status nginx --no-pager
journalctl -u nginx -b --no-pager
ss -ltnp
curl -v http://127.0.0.1
sudo nginx -tWrite an incident report with the symptoms, impact, timeline, evidence, root cause, recovery steps and one prevention measure. Restore the service, confirm monitoring returns to normal and compare the result with your original baseline.
Portfolio proof: a clear incident report demonstrates troubleshooting judgment better than a screenshot of a successful installation.
A 30-day Linux sysadmin project roadmap
- Week 1: build the lab, manage users and configure the LVM filesystem.
- Week 2: configure networking, firewall rules, SSH and the systemd timer.
- Week 3: deploy Nginx, perform a restore test and build a monitoring dashboard.
- Week 4: automate with Ansible, run the rootless container and complete the incident exercise.
It is better to finish and document four connected projects than to claim 12 incomplete installations. If you want broader ideas, see these system administration projects and network administrator projects. The guide to getting your first IT job explains how projects fit into a wider job search, while these free information-security training resources can extend the security exercises.
How to document Linux projects for a portfolio
Create one repository with a directory for each project. Every README should include:
- the problem and intended outcome;
- a simple architecture diagram;
- the OS versions and assumptions;
- sanitised configuration files or scripts;
- validation commands and expected results;
- a failure you encountered and how you diagnosed it;
- security and cost decisions;
- cleanup or rollback steps.
Do not upload private keys, passwords, cloud credentials, raw environment files or employer information. Before publishing a screenshot or log, check hostnames, usernames, addresses and tokens. Lachie’s systems engineering background is relevant context for this guide, but your own portfolio should make only claims you can explain and reproduce.
Frequently asked questions
Which Linux system administrator project is best for a beginner?
Start with two virtual machines, user permissions and SSH. That combination teaches installation, networking, identity and remote access without requiring paid hardware. Add a small Nginx service only after you can recover the VMs from a snapshot.
Can I build a Linux home lab on one laptop?
Yes. Two small server VMs are enough for most projects in this guide. If your computer has limited memory, run one VM at a time or begin with one server and add the automation node later. A local lab also avoids surprise cloud charges.
Should I learn Ubuntu or a RHEL-family distribution?
Either can teach core Linux administration. Ubuntu Server is approachable and well documented; RHEL-family systems add experience with tools such as DNF, SELinux and firewalld. Learning one deeply first is more useful than copying commands across several distributions without understanding the differences.
Is CentOS still suitable for a Linux lab in 2026?
CentOS Stream 10 is current, but the old CentOS Linux releases are end-of-life and should not be recommended. If you want a RHEL-oriented lab, use a supported RHEL release or a current compatible option and verify its lifecycle before installing it.
What should a Linux sysadmin portfolio include?
Show the objective, architecture, configurations, tests, troubleshooting and recovery—not just the finished screen. A good reviewer should be able to understand what you built, why you made each decision and how you proved the result without needing any secret values.
Do I need Docker or Kubernetes for a beginner Linux portfolio?
No. Users, storage, networking, services, logs, SSH, firewalls and backups are more fundamental. A rootless Podman or Docker project is a useful later addition. Kubernetes makes more sense after you can operate and troubleshoot the Linux hosts underneath it.
Conclusion
These Linux system administrator projects form a progression: build two machines, secure access, manage storage and services, verify backups, observe the systems, automate repeatable work and recover from failure. Keep the environment disposable, use supported software and document evidence rather than exaggerating experience. The result is both a practical learning path and a portfolio you can confidently discuss.