Debian’s release model is one of the most predictable in the Linux world. A new stable release arrives every two years, gets three years of regular security support and another two via LTS, and produces a steady cadence of point releases that bundle accumulated fixes. The package manager (apt) is the same one Ubuntu inherited, with the same workflow. The hard part isn’t applying updates — it’s confirming that every Debian host across your fleet has actually applied them.
This page covers the core apt commands, how unattended-upgrades behaves on Debian specifically, the differences between stable, testing, unstable, and LTS, and where a fleet-aware tool like SysWard fits on top.
Core Debian Patching Commands
The patching workflow on Debian is the same shape as on Ubuntu, with subtly different defaults:
# Refresh the package index
sudo apt update
# Apply all available upgrades
sudo apt upgrade -y
# Apply only security updates via unattended-upgrades policy
sudo unattended-upgrade -d
# Full upgrade — allows package removals to satisfy dependencies
sudo apt full-upgrade -y
# Reboot if a kernel or glibc upgrade requires it
test -e /var/run/reboot-required && sudo reboot
The same apt upgrade vs apt full-upgrade distinction applies. apt upgrade won’t add or remove packages to satisfy new dependencies; apt full-upgrade will. For routine patching, upgrade is the safer default. For major-version upgrades (Debian 11 → 12), full-upgrade is required because the new release inevitably renames or drops packages.
apt list --upgradable shows what apt upgrade would change without applying anything. apt install --only-upgrade <package> upgrades a single package and its dependencies.
Security Updates and the Security Pocket
Debian ships security advisories through security.debian.org. A typical /etc/apt/sources.list includes a line like:
deb http://deb.debian.org/debian-security bookworm-security main contrib non-free-firmware
That’s the pocket unattended-upgrades watches by default. To apply security-only updates manually with the right pocket filtering:
sudo apt-get -y \
-o Dir::Etc::SourceList=/etc/apt/sources.list \
-o Dir::Etc::SourceParts=/etc/apt/sources.list.d \
upgrade
Or just install unattended-upgrades and let it run on its systemd timer. For the broader strategy around automating this across a fleet — staged rollouts, verification gates, and rollback — see our guide to automating Linux server patching.
Automating with unattended-upgrades
unattended-upgrades is the per-host automation primitive on Debian, identical in shape to the Ubuntu version (Ubuntu inherited it from Debian). Install and enable:
sudo apt install unattended-upgrades apt-listchanges
sudo dpkg-reconfigure unattended-upgrades
The behavior lives in /etc/apt/apt.conf.d/50unattended-upgrades. The knobs that matter:
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename},label=Debian-Security";
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
};
Unattended-Upgrade::Package-Blacklist {
"linux-image-*";
};
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
The Origins-Pattern syntax is more verbose than Ubuntu’s ${distro_id}:${distro_codename}-security shorthand because Debian’s archive metadata is structured slightly differently. The default config that ships with the package is correct for most installations — the most common customization is enabling automatic reboots.
The timer that triggers it is apt-daily-upgrade.timer:
systemctl status apt-daily-upgrade.timer
systemctl list-timers apt-daily-upgrade.timer
journalctl -u apt-daily-upgrade.service --since "24 hours ago"
Logs land in /var/log/unattended-upgrades/. Check this file when investigating why a host did or didn’t pick up a CVE patch.
Stable, Testing, Unstable, and LTS
Debian has four release tracks running at any given time. They behave differently from a patch management perspective:
- Stable (currently bookworm / Debian 12) — production-grade. Receives security updates from
security.debian.orgfor about three years after release. - Old-stable (bullseye / 11) — the previous stable, still receiving security updates via the standard channel for a period after the new stable ships, then via LTS afterward.
- Testing (trixie at time of writing) — the staging area for the next stable. Receives security fixes but with less SLA — the security team prioritizes stable.
- Unstable / sid — rolling, no security pocket. Fixes come through the regular archive.
For production fleets, stable is the only sensible default. Testing and unstable are appropriate for development machines, package maintainers, or where you specifically need a newer package version that hasn’t backported to stable.
Debian LTS extends the security update window by two years past the standard end-of-life. After old-stable’s regular support ends, LTS picks up coverage from deb.freexian.com for selected architectures and packages. Adding LTS to a host:
echo "deb http://deb.debian.org/debian-security bullseye-security main" | sudo tee /etc/apt/sources.list.d/bullseye-lts.list
sudo apt update
sudo apt upgrade -y
The exact sources line varies per release — check the Debian LTS wiki for the current incantation when you need it.
Patching Cadence and Maintenance Windows
A workable Debian patching cadence has three tracks:
- Security advisories within days for critical CVEs, within weeks for the rest.
unattended-upgradeshandles per-host application; fleet inventory confirms it actually ran. - Routine package upgrades on a weekly or monthly cadence, batched into a change window outside business hours.
- Kernel and glibc upgrades on a reboot window, ideally monthly.
/var/run/reboot-requiredflags hosts pending a reboot.
Major version upgrades (11 → 12) are their own change event — schedule them deliberately, pilot on a non-critical host first, and use apt full-upgrade after editing sources.list to point at the new release.
Common Pitfalls
- Stale apt indexes:
apt upgradeworks against whatever the lastapt updateproduced. In scripts, always pair them. - Apt holds:
apt-mark hold <package>prevents upgrades. Easy to set, easy to forget, and a frequent cause of fleet drift. - Pinning:
/etc/apt/preferences.d/pins versions. Same problem as holds — review these regularly across the fleet. - Reboot debt: hosts that don’t reboot accumulate uninstalled kernel updates. A monthly reboot window prevents the surprise outage.
- Per-host unattended-upgrades drift: hosts where it’s misconfigured or disabled stay vulnerable while the rest of the fleet patches. Central inventory is the only reliable way to know.
How SysWard Fits
SysWard sits on top of apt. The agent reports installed packages on a recurring cadence, SysWard matches them against live CVE feeds, and the dashboard shows what’s exploitable across the fleet. Patches roll out via the local apt, but with group scheduling, hold windows, and audit logging that per-host tools don’t provide.
For Debian fleets specifically:
- Cross-version view: Debian 10 LTS, 11, 12, and any testing-track development hosts in one inventory.
- CVE matching against installed packages, not raw advisory feeds. A CVE in
nginxdoesn’t appear on hosts where nginx isn’t installed. - Group rollouts for staging → production, region-by-region, or role-by-role patching.
- Reboot tracking as a fleet view, not a per-host check.
- Audit trail for every patch event — host, package, before/after versions, actor, timestamp.
Ready to automate this?
SysWard manages Debian patching alongside Ubuntu, RHEL, CentOS, Rocky, and SUSE from one dashboard — start free for 2 servers, no card required. See also Ubuntu patch management for the closely-related Ubuntu workflow, or Linux patch management for cross-distro fundamentals.