Keeping your Linux servers updated is one of the simplest and most effective ways to stay secure and stable. But on a production server, you can’t just run apt upgrade or dnf upgrade and hope for the best. You need a repeatable, safe update process.
In this guide, we’ll look at how to update servers safely on three major Linux families:
- Debian / Ubuntu – using
apt - RHEL / AlmaLinux / Rocky / Fedora – using
dnf - SUSE / openSUSE / SLES – using
zypper
We’ll focus on practical examples and habits that help you patch servers without surprises.
General principles for safe server updates
Before we touch any package manager, there are a few universal rules that apply on every Linux server:
1. Always know what you’re updating
Never update “blindly” on a production system. Always review the list of packages that will be changed.
- Use “check mode” / “download only” / “dry run” where possible.
- Scan for critical components: kernel, web server, database, PHP, mail stack, etc.
2. Have a rollback plan
If an update breaks something, how do you recover?
- Snapshots (VM / LVM / Btrfs / ZFS) before major patching.
- Database backups before updating DB-related packages.
- Configuration backups (e.g.
/etc, application configs).
3. Use a maintenance window
Even “non-disruptive” updates can occasionally restart services or require a reboot. Plan updates during a maintenance window:
- Inform users (or at least your team).
- Check monitoring (Zabbix, Prometheus, etc.) before and after.
- Have someone on call if this is a critical system.
4. Be careful with SSH
Updates can restart network services, firewall rules or SSH itself. To reduce the risk of locking yourself out:
- Use
tmuxorscreento keep your session alive. - On critical systems, consider using out-of-band access (IPMI, iDRAC, etc.) for major changes.
# Example: start tmux before updating
tmux new -s updates
Safe updates on Debian / Ubuntu with apt
The apt tool is the standard package manager on Debian and Ubuntu-based servers.
Step 1: Update package lists
First, always refresh the package index. This does not install anything yet:
sudo apt update
Review the summary at the end. It shows how many upgradable packages are available.
sudo apt list --upgradable
Step 2: Apply security updates only (example)
On production servers, you may want to start with security updates only (especially on Ubuntu where security updates come from *-security repositories):
# Basic approach: upgrade all packages, but you can filter by origin with tools like unattended-upgrades
sudo apt upgrade
If you want more control over security-only updates, you can use unattended-upgrades with a configuration that targets only security repos. For manual server administration, many admins still prefer to review all pending packages and then run a regular apt upgrade.
Step 3: Safe upgrade vs full upgrade
There are two common commands for upgrades:
apt upgrade– upgrades packages but does not remove existing packages or install new dependencies that change relationships heavily.apt full-upgrade– may install or remove packages to complete the upgrade (e.g. kernel transitions, major changes).
On servers, a typical pattern is:
sudo apt update
sudo apt upgrade
Use full-upgrade when you are prepared for more impactful changes, such as a kernel or big library transitions. For example, during a planned maintenance window:
sudo apt update
sudo apt full-upgrade
Step 4: Reboot management
Some updates require a reboot, typically kernel and low-level libraries. On Debian/Ubuntu you can check:
# Check if a reboot is required
if [ -f /var/run/reboot-required ]; then cat /var/run/reboot-required fi
If a reboot is required, perform it during your maintenance window:
sudo reboot
Step 5: Updating specific packages safely
Sometimes you only want to update a single service, e.g. Nginx or OpenSSH.
# Update only nginx
sudo apt update
sudo apt install --only-upgrade nginx
This keeps the rest of the system as-is, which is useful for emergency security fixes.
Step 6: Example: automated but controlled updates
A common pattern is to schedule updates via cron or a configuration management tool (Ansible, Puppet, etc.), but still keep reboots manual.
# Example cron job (run once a week at 03:00)
0 3 * * 0 root apt update && apt -y upgrade
With this approach, you still check for /var/run/reboot-required and decide when to reboot.
Safe updates on RHEL / Rocky / Alma / Fedora with dnf
On modern RHEL-based systems, dnf is the default package manager (replacing yum on older systems). The logic is similar, but there are a few nice features that help with safe updates.
Step 1: Check for updates
sudo dnf check-update
This shows a list of packages that could be updated, but doesn’t install anything.
Step 2: Apply updates
sudo dnf upgrade
On servers, you usually want to review the list that dnf shows before confirming. If you’re automating with Ansible or scripts, you can use -y to auto-confirm:
sudo dnf -y upgrade
Step 3: Security updates only
RHEL/Fedora-style systems can filter updates by type, including security advisories:
# Only apply security updates
sudo dnf upgrade --security
# Show which security updates are available
sudo dnf updateinfo list security
This is very useful when your update policy differentiates between security fixes and feature updates.
Step 4: Using dnf history for rollback
One of the powerful features of dnf is transaction history. You can review what you’ve done and even attempt to undo it.
# Show recent transactions
sudo dnf history
# Get details of a specific transaction
sudo dnf history info <ID>
If a recent update broke something and you have no snapshot, you can try:
# Attempt to undo transaction 25 (example)
sudo dnf history undo 25
This isn’t a perfect rollback mechanism, but it can help in some scenarios. For critical systems, VM or filesystem snapshots are still the preferred rollback method.
Step 5: Excluding sensitive packages
Sometimes you do not want certain packages to ever be updated automatically (e.g. a specific kernel or a vendor-supplied database).
You can set exclusions in /etc/dnf/dnf.conf:
sudo nano /etc/dnf/dnf.conf
Add a line like:
exclude=kernel* mysql*
Now dnf upgrade will skip these packages unless you explicitly request them.
Step 6: Example: weekly security updates
A simple example of scripted security updates once per week:
#!/bin/bash #
/usr/local/sbin/weekly-security-updates.sh
LOGFILE=/var/log/weekly-security-updates.log
{ echo "=== $(date) ===" dnf check-update --security dnf -y upgrade --security } >> "$LOGFILE" 2>&1
Then you can schedule it via cron and review the log file after each run.
Safe updates on SUSE / openSUSE / SLES with zypper
On SUSE-based systems, zypper is the primary CLI package manager. It is powerful and script-friendly.
Step 1: Refresh repositories
sudo zypper refresh
This updates repository metadata but doesn’t install anything yet.
Step 2: List available updates
sudo zypper list-updates
You can also filter for patches, patterns, etc., but list-updates is usually enough to see what will change.
Step 3: Apply standard updates
sudo zypper update
zypper update will upgrade installed packages to the latest suitable versions from enabled repositories.
Step 4: Security patches only
SUSE systems have the concept of patches with categories, including security patches.
# Show security patches
sudo zypper lp -g security
# Install security patches only
sudo zypper patch --category security
This allows you to implement a “security first” update strategy on production servers.
Step 5: Using zypper with Snapper (Btrfs snapshots)
On some SUSE systems (e.g. SLES with Btrfs root), you can integrate updates with filesystem snapshots. This is extremely powerful for safe updates.
Typical workflow:
- Take a snapshot before updates (often automated via Snapper).
- Run
zypper updateorzypper patch. - If something breaks, boot into the previous snapshot or roll back with Snapper.
Example commands (if Snapper is configured):
# View snapshots
sudo snapper list
# Roll back to a previous snapshot (example)
sudo snapper rollback <ID>
This snapshot-based approach is one of the safest ways to update a server OS.
Step 6: Non-interactive updates
For automation, zypper supports a non-interactive mode:
sudo zypper --non-interactive update
Combine this with logging and monitoring to build a controlled patching process.
Practical examples: safe update workflows
Example 1: Manual, fully controlled update on a critical web server (Debian/Ubuntu)
- Take a snapshot on your hypervisor (or create LVM/Btrfs snapshot).
- Start a
tmuxsession over SSH. - Check disk space (ensure enough free space for packages and logs):
df -h
- Update and review packages:
sudo apt update
sudo apt list --upgradable
- Apply updates:
sudo apt upgrade
- Check if a reboot is required; if yes, schedule or perform it in the maintenance window:
[ -f /var/run/reboot-required ] && sudo reboot
- Verify services after reboot: web server, database, monitoring agents, etc.
Example 2: Weekly security patching on a RHEL/Rocky server
- Create a script for security updates (as shown earlier with
dnf --security). - Schedule it via
cronto run every Sunday at 02:00. - On Monday morning, check:
- The log file created by the script.
- Your monitoring dashboard for any alerts after patching.
- If kernel or critical components were updated, plan a reboot during the next agreed maintenance slot.
Example 3: Safe snapshot-based updates on SUSE/SLES
- Ensure the root filesystem is Btrfs and Snapper is configured for pre/post snapshots.
- Run:
sudo zypper refresh
sudo zypper patch
- Verify the system:
- Check your applications.
- Run sanity checks or smoke tests.
- If something is broken and cannot be fixed easily, roll back to the pre-update snapshot with Snapper.
Best practices for safe server patching
- Use staging: Test updates on a staging server that mirrors production before patching the real thing.
- Document your process: Keep a simple runbook for “how we patch servers” so others can follow the same steps.
- Monitor after updates: Have alerts for CPU, RAM, disk, HTTP response codes, and key application metrics.
- Patch regularly: Smaller, frequent updates are easier to debug than one huge quarterly patch.
- Know your critical services: For web/database/mail servers, check their status explicitly after every update.
Conclusion
System updates don’t have to be scary—even on critical servers. With a few simple habits and the right use of apt, dnf, and zypper, you can keep your Linux infrastructure secure and stable:
- Review updates before applying them.
- Use security-only updates when needed.
- Leverage snapshots and history to roll back if something goes wrong.
- Automate carefully, and always monitor the results.
If you standardize this process across your Debian/Ubuntu, RHEL/Rocky/Alma and SUSE servers, patching becomes a repeatable routine instead of a risky adventure.