System Updates on Linux Servers: Safe Updates with apt, dnf, and zypper

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 tmux or screen to 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:

  1. Take a snapshot before updates (often automated via Snapper).
  2. Run zypper update or zypper patch.
  3. 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)

  1. Take a snapshot on your hypervisor (or create LVM/Btrfs snapshot).
  2. Start a tmux session over SSH.
  3. Check disk space (ensure enough free space for packages and logs):
df -h 
  1. Update and review packages:
sudo apt update 
sudo apt list --upgradable 
  1. Apply updates:
sudo apt upgrade 
  1. Check if a reboot is required; if yes, schedule or perform it in the maintenance window:
[ -f /var/run/reboot-required ] && sudo reboot 
  1. Verify services after reboot: web server, database, monitoring agents, etc.

Example 2: Weekly security patching on a RHEL/Rocky server

  1. Create a script for security updates (as shown earlier with dnf --security).
  2. Schedule it via cron to run every Sunday at 02:00.
  3. On Monday morning, check:
    • The log file created by the script.
    • Your monitoring dashboard for any alerts after patching.
  4. 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

  1. Ensure the root filesystem is Btrfs and Snapper is configured for pre/post snapshots.
  2. Run:
sudo zypper refresh 
sudo zypper patch 
  1. Verify the system:
    • Check your applications.
    • Run sanity checks or smoke tests.
  2. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.