Created
March 23, 2026 22:20
-
-
Save jranil/2d3f217fbf544872b53cf9f324d7fc04 to your computer and use it in GitHub Desktop.
"reset" a ubuntu server to a minimal state without doing a full reinstall
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -e | |
| echo "=== Step 1: Preserve critical configs ===" | |
| # Backup SSH and network configs | |
| cp -r /etc/ssh /root/ssh_backup | |
| cp -r /etc/netplan /root/netplan_backup 2>/dev/null || true | |
| cp /etc/network/interfaces /root/interfaces_backup 2>/dev/null || true | |
| echo "=== Step 2: Stop and disable non-essential services ===" | |
| KEEP_SERVICES="ssh networking systemd-networkd systemd-resolved ufw cron rsyslog" | |
| for service in $(systemctl list-units --type=service --state=running --no-legend | awk '{print $1}'); do | |
| svc_name=$(echo "$service" | sed 's/.service//') | |
| if ! echo "$KEEP_SERVICES" | grep -qw "$svc_name"; then | |
| echo "Disabling: $svc_name" | |
| systemctl stop "$service" 2>/dev/null || true | |
| systemctl disable "$service" 2>/dev/null || true | |
| fi | |
| done | |
| echo "=== Step 3: Mark only essential packages ===" | |
| # Define essential packages to keep | |
| ESSENTIAL="ubuntu-minimal openssh-server openssh-client netplan.io \ | |
| systemd udev apt dpkg bash coreutils util-linux \ | |
| iproute2 iputils-ping net-tools sudo" | |
| # Mark everything as auto-installed first | |
| apt-mark auto $(apt-mark showmanual) 2>/dev/null || true | |
| # Mark essentials as manually installed (protected) | |
| apt-mark manual $ESSENTIAL | |
| echo "=== Step 4: Remove unnecessary packages ===" | |
| apt-get autoremove --purge -y | |
| echo "=== Step 5: Clean up package cache ===" | |
| apt-get clean | |
| apt-get autoclean | |
| echo "=== Step 6: Remove snap packages (optional) ===" | |
| for snap in $(snap list 2>/dev/null | awk 'NR>1 {print $1}' | grep -v snapd); do | |
| snap remove --purge "$snap" 2>/dev/null || true | |
| done | |
| echo "=== Step 7: Clear logs ===" | |
| journalctl --rotate | |
| journalctl --vacuum-time=1s | |
| find /var/log -type f -name "*.log" -exec truncate -s 0 {} \; | |
| find /var/log -type f -name "*.gz" -delete | |
| echo "=== Step 8: Clear temp files ===" | |
| rm -rf /tmp/* /var/tmp/* | |
| echo "=== Step 9: Restore SSH config (safety net) ===" | |
| cp -r /root/ssh_backup/* /etc/ssh/ | |
| systemctl restart ssh | |
| echo "=== Step 10: Reset hostname and hosts file (optional) ===" | |
| # Uncomment below if you want to reset hostname | |
| # hostnamectl set-hostname ubuntu-server | |
| echo "=== Done! Rebooting in 10 seconds... ===" | |
| echo "Press Ctrl+C to cancel reboot" | |
| sleep 10 | |
| reboot |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
chmod +x reset_to_minimal.sh
sudo bash reset_to_minimal.sh
Check SSH is running
systemctl status ssh
Check network is up
ip addr show
Check what packages remain
dpkg --get-selections | grep -v deinstall | wc -l