Enabling automatic background updates with unattended-upgrades

Packages release new versions with bugfixes, security patches and improvements all the time. Staying on top of all those changes and keeping your systems updated can be a tedious task, especially when you need to manage multiple servers. To solve this issue, debian-based distros ship with the unattended-upgrades package that automates this task.

Installation & configuration

The package can quickly be installed through apt:

apt install unattended-upgrades

This will create two configuration files under /etc/apt/apt.conf.d/:

  • 20auto-upgrades: contains the configuration of the automatic background process, like the scheduled frequency and what parts to automatically upgrade.
  • 50unattended-upgrades: contains the configuration of the unattended-upgrades program itself, defining how it is supposed to behave, which sources to include and what packages are exempt.

By default, 20auto-upgrades will contains just 2 lines:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

The first defines the number of days between automatic package list updates (apt update), the second the number of days between automatic background upgrades (apt upgrade).

To keep your apt cache clean and enable smooth operations for long-running servers, you add a line to set the AutocleanInterval as well:

APT::Periodic::AutocleanInterval "7";

This will run apt-cache autoclean every 7 days, ensuring the package cache does not grow out of control.

The file 50unattended-upgrades defines the behaviour of the background upgrading process. It contains a lot of options, such as what packages to exclude, enabling automatic reboots, removing unused packages or sending notification mails. The options are well-documented in that file, take some time to read through them and adjust them to your needs.

Testing your configuration

Once you have configured unattended-upgrades, you need to confirm it behaves the way you intended. To do that, you can perform a dry run of a background upgrade:

unattended-upgrade --dry-run --debug

The --dry-run flag ensures we don't actually upgrade packages now, and the --debug flag gives us detailed information about what choices were made during the upgrade process and why.

Getting information about background upgrades

Since unattended-upgrades runs in the background, we don't directly get information about possible issues. For this reason, every background upgrade will write it's output (the same you got from the dry run earlier), to a log file in /var/log/unattended-upgrades/.

To monitor the upgrade process, you could install and configure apt-listchanges to send you mails on errors or set up a cron job to periodically check the log file /var/log/unattended-upgrades/unattended-upgrades.log for errors and forward them some other way, like webhooks or a push service.

Automatic reboots

If you want to have your machine reboot automatically if required after an upgrade, for example because of a kernel upgrade or similar, unattended-upgrades can do that as well. The relevant configuration can be set in /etc/apt/apt.conf.d/50unattended-upgrades:

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
Unattended-Upgrade::Automatic-Reboot-Time "01:00";

This will enable automatic reboots after upgrades (but only if required). The second line instructs it to reboot even if users are currently logged in and the last line specifies that reboots should happen at 1am (if one is needed). If the last line weren't set, the machine would reboot immediately after a background upgrade instead.

More articles

Sharing compiled go code libraries

Ever wondered how to create dll/shared object files in go, like other compiled languages can?

Finding files in linux

Hunting for files an conditional transforming made easy

Write modern javascript for older browsers with babel and browserify

Write modern frontend code even for outdated target browsers

Installing ingress-nginx on K3S

Setting up the default ingress controller

Passing by Reference in PHP

Sharing variables instead of their values

Setting up the Kubernetes Dashboard

Deploying a visual overview of your k8s cluster