An unpatched server is a security risk, but uncontrolled updates can cause an outage. unattended-upgrades lets Ubuntu Server install patches according to policy. Production environments still need restricted package sources, preflight validation, outcome monitoring, and a deliberate reboot process.
This guide builds a practical Ubuntu Server policy: prioritize security updates, avoid automatic reboots, keep customization in a manageable drop-in file, test with --dry-run, and roll out changes in stages.
What does unattended-upgrades do?
unattended-upgrades is the backend for APT periodic updates. On modern Ubuntu systems, systemd schedules the work through apt-daily.timer and apt-daily-upgrade.timer. It installs packages only from origins allowed by policy. It does not perform an Ubuntu release upgrade, which is a separate do-release-upgrade workflow.
Ubuntu has included and enabled automatic security updates by default on Desktop and Server since 18.04 LTS. Still, verify the actual state because cloud images, internal templates, or configuration management may change the defaults.
1. Inspect the current state
lsb_release -a
apt-cache policy unattended-upgrades
systemctl status apt-daily.timer apt-daily-upgrade.timer
systemctl list-timers 'apt-*'
A timer shown as active (waiting) is waiting for its next run. A randomized delay may be added so a fleet does not download updates at the same moment.
apt-config dump | grep -iE 'APT::Periodic|Unattended-Upgrade'
2. Install and enable it
sudo apt update
sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades
The last command creates or enables the periodic configuration. Check /etc/apt/apt.conf.d/20auto-upgrades:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
The value 1 represents a daily interval; systemd timers determine the effective execution time.
3. Use a drop-in instead of editing the packaged file
Ubuntu advises against modifying 50unattended-upgrades directly because package updates can create configuration conflicts. Create a higher-priority file:
sudo nano /etc/apt/apt.conf.d/60local-unattended-upgrades
A conservative production policy:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
Unattended-Upgrade::SyslogEnable "true";
APT expands ${distro_id} and ${distro_codename} for the host. Limiting updates to the -security pocket keeps the scope predictable. Do not automatically allow PPAs or third-party repositories without their own test and rollback process.
4. Should the server reboot automatically?
Kernel, libc, and other foundational updates may require a reboot before the running system uses the fix. An automatic reboot on a single production server, however, can drop requests, interrupt jobs, or break quorum.
The policy above keeps Automatic-Reboot "false". Detect pending reboots with:
test -f /var/run/reboot-required && cat /var/run/reboot-required
cat /var/run/reboot-required.pkgs 2>/dev/null
For a load-balanced service, drain one node, wait for connections to finish, reboot, pass health checks, return it to service, and only then proceed to the next node.
Enable automatic reboot only when the workload tolerates it and a maintenance window exists:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";
Unattended-Upgrade::Automatic-Reboot-Time "03:30";
The reboot time uses the operating system timezone. Verify it with timedatectl, especially on cloud images that default to UTC.
5. Temporarily block sensitive packages
A blacklist should be temporary, owned, and have an expiry date. Deferring a security fix indefinitely can create more risk than a compatibility issue.
Unattended-Upgrade::Package-Blacklist {
// "mysql-server";
// "docker-ce";
};
Entries are interpreted as regular expressions, so inspect the package selection and avoid overly broad patterns.
6. Validate before applying changes
sudo unattended-upgrade --dry-run --debug
sudo apt-get -s upgrade
apt-config dump | less
--dry-run simulates package selection without installing anything. Review origins, held packages, dependencies, and configuration errors. After a clean test, trigger one observed run:
sudo unattended-upgrade --verbose
Do not run it alongside another apt, dpkg, or provisioning process. If a lock error occurs, identify the process holding the lock rather than deleting lock files.
7. Monitor timers, the journal, and logs
systemctl list-timers 'apt-*'
systemctl status apt-daily-upgrade.service
journalctl -u apt-daily-upgrade.service --since today
sudo tail -n 200 /var/log/unattended-upgrades/unattended-upgrades.log
sudo tail -n 200 /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
The main log records package selection and results; the dpkg log records installation details. Alert when the timer has not run within the expected interval, an upgrade fails, overdue security patches remain, or a reboot requirement persists.
8. Design a fleet rollout
Do not deploy a new update policy to every server at once. Use a staged process:
- Canary: select a low-impact host with a representative workload.
- Observe: monitor service health, error rate, latency, and logs.
- Expand in cohorts: proceed through staging, part of production, and then the fleet.
- Rolling reboot: preserve capacity and quorum throughout maintenance.
- Report: record changed package versions, failed hosts, and completion times.
A VM snapshot can support recovery but does not replace a verified backup. For databases, confirm consistency and test restoration before treating a snapshot as a rollback plan.
9. Common configuration mistakes
- Expecting an exact timer: APT may apply a randomized delay.
- Auto-rebooting a single server: a patch becomes an unannounced outage.
- Allowing every repository: third-party packages have different release and support practices.
- Editing 50unattended-upgrades: package upgrades become harder to manage; use a drop-in.
- Ignoring logs: enabled does not mean successfully updated.
- Confusing package and release upgrades: this tool does not move Ubuntu 22.04 to 24.04.
Production checklist
- Backups and the restore process have been tested.
- Package origins are restricted and PPAs are inventoried.
- The dry run succeeds on a representative canary.
- Automatic reboot is disabled by default or has an explicit maintenance window.
- Timers, logs, pending security fixes, and reboot requirements are monitored.
- Multi-node systems update in rolling cohorts while preserving quorum and capacity.
- Every blacklist exception has an owner and removal date.
Conclusion
unattended-upgrades works best as one part of a patch-management process, not a switch to turn on and forget. Restrict origins, use a drop-in, validate on a canary, separate reboot decisions from package installation, and turn logs into owned alerts. This delivers security patches promptly while keeping production controlled.




No comments yet. Be the first to share your thoughts.