How to Set Up Automatic Updates on Ubuntu (unattended-upgrades)

Overview

Ubuntu’s unattended-upgrades package handles automatic security updates without requiring you to SSH in and run apt upgrade manually. If you’re running a VPS or dedicated server and you’re not using this, your server is likely sitting unpatched between visits — and that’s how most opportunistic compromises happen.

This isn’t about enabling full unattended upgrades for every package blindly. It’s about understanding what the tool does, configuring it sensibly for a production environment, and making sure it notifies you when something needs attention. There’s a meaningful difference between “security patches only” and “upgrade everything automatically” — and that distinction matters a lot on a live server.

This guide applies to Ubuntu 20.04 LTS, 22.04 LTS, and 24.04 LTS. The package and config structure is the same across all three. If you’re on an older release, I’d strongly recommend upgrading — Ubuntu 18.04 reached end-of-life in April 2023.

Prerequisites

  • Root or sudo access to your Ubuntu server
  • Ubuntu 20.04, 22.04, or 24.04 (this guide is tested on all three)
  • A working internet connection from the server (to reach Ubuntu’s package mirrors)
  • Basic comfort with the Linux command line — you’ll be editing a config file and running apt commands
  • If you want email notifications, a working mail transfer agent (MTA) such as postfix or an external SMTP relay configured on the server

Step 1: Install unattended-upgrades

On most Ubuntu installations, unattended-upgrades is already installed. Check first before installing:

dpkg -l unattended-upgrades

If the output shows ii at the start of the line, it’s installed. If not, install it along with apt-listchanges (which summarises what changed in each update):

sudo apt update
sudo apt install unattended-upgrades apt-listchanges -y

Step 2: Enable automatic updates via dpkg-reconfigure

The quickest way to enable the service is through the interactive configuration wizard:

sudo dpkg-reconfigure -plow unattended-upgrades

This prompts you with a yes/no dialog. Select Yes. It writes the enable file at /etc/apt/apt.conf.d/20auto-upgrades with sensible defaults.

To verify what was written:

cat /etc/apt/apt.conf.d/20auto-upgrades

You should see:

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

The "1" means these tasks run every 1 day. You can set "7" for weekly, but I’d leave it at daily for security patches.

Step 3: Configure which updates are applied automatically

The main configuration file is /etc/apt/apt.conf.d/50unattended-upgrades. Open it in your preferred editor:

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

The most important section is the Allowed-Origins block near the top. By default it looks like this (on Ubuntu 22.04):

Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}";
    "${distro_id}:${distro_codename}-security";
    // "${distro_id}:${distro_codename}-updates";
    // "${distro_id}:${distro_codename}-proposed";
    // "${distro_id}:${distro_codename}-backports";
};

The lines starting with // are commented out. For most production servers, leaving only -security enabled is the right call. Security patches are vetted more carefully and are less likely to cause breakage than general -updates packages.

If you also want bug-fix updates (not just security), uncomment the -updates line by removing the //. I’d avoid enabling -proposed or -backports on any server you care about.

Enable email notifications

Find and edit the Mail line in the same file:

Unattended-Upgrade::Mail "you@yourdomain.com";
Unattended-Upgrade::MailReport "on-change";

on-change sends email only when updates were actually applied. Other options are always and only-on-error. On a busy server, always gets noisy fast.

Enable automatic reboots (optional — read the warning first)

Some kernel updates require a reboot to take effect. You can automate this:

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

⚠ Warning: Enabling automatic reboots on a production server can cause unexpected downtime if a reboot takes longer than expected or if a service doesn’t restart cleanly. On a managed Host & Tech VPS SSD Hosting plan, your server is monitored and will restart services automatically — but you should still know a reboot is scheduled. If you enable this, set the time to a low-traffic window and make sure your critical services have proper systemd restart policies.

Step 4: Test the configuration without applying updates

Before relying on the automation, do a dry run. This simulates what would happen without actually installing anything:

sudo unattended-upgrade --dry-run --debug

You’ll see verbose output showing which packages would be upgraded and whether the configuration is valid. If it throws errors here, fix them before leaving the daemon running unattended.

Step 5: Run an immediate upgrade to verify it works

If the dry run looked clean, run it for real once to confirm end-to-end functionality:

sudo unattended-upgrade -v

The -v flag gives verbose output. You’ll see packages being fetched and installed (or a message that nothing needed updating). Check the log afterward:

cat /var/log/unattended-upgrades/unattended-upgrades.log

Step 6: Verify the systemd timer is active

On Ubuntu 20.04 and later, unattended-upgrades runs via apt-daily.timer and apt-daily-upgrade.timer — not a traditional cron job. Check their status:

systemctl status apt-daily.timer
systemctl status apt-daily-upgrade.timer

Both should show active (waiting). If either is inactive, enable it:

sudo systemctl enable --now apt-daily.timer
sudo systemctl enable --now apt-daily-upgrade.timer

📝 Note: apt-daily.timer handles updating the package lists. apt-daily-upgrade.timer is what actually installs the updates. Both need to be active. A common gotcha is that only one of them is running and users wonder why updates aren’t being applied.

Common Issues & Troubleshooting

Updates aren’t being applied even though unattended-upgrades is enabled

First, check the log at /var/log/unattended-upgrades/unattended-upgrades.log for errors. Then verify both systemd timers are active (see Step 6). A frequently missed issue: if /var/run/reboot-required exists from a previous kernel update, some configurations pause further upgrades until the reboot is completed. Check with cat /var/run/reboot-required and reboot if needed.

“E: Could not get lock /var/lib/dpkg/lock-frontend” errors in the log

This means another apt process was running at the same time — usually a manually triggered apt upgrade or another script. unattended-upgrades will retry, but if this happens frequently, check for overlapping cron jobs or admin processes competing with the timer. Don’t delete the lock file manually unless you’ve confirmed no apt process is actually running.

Email notifications aren’t arriving

This almost always means the MTA isn’t configured, not a problem with unattended-upgrades itself. Test it directly:

echo "Test" | mail -s "Test from server" you@yourdomain.com

If that doesn’t arrive, fix your mail setup first. A common solution on VPS environments is to configure a relay through an external SMTP provider (Mailgun, Postmark, etc.) since many cloud providers block outbound port 25.

A bad update broke something — how do I roll back?

unattended-upgrades doesn’t have a built-in rollback. You can downgrade a specific package using:

sudo apt install packagename=version

To find the previous version: apt-cache showpkg packagename. For kernel rollbacks, you can select an older kernel from the GRUB boot menu on next reboot. This is one reason I’d recommend keeping automatic reboots disabled on production servers and reviewing kernel updates manually.

unattended-upgrades is running but the log shows “No packages found that can be upgraded unattended”

This usually means your Allowed-Origins entries don’t match the actual repository labels. Run apt-cache policy and compare the origin strings against what’s in your config. The variable substitution (${distro_id}, ${distro_codename}) should handle this automatically, but on custom or minimal installs the lsb-release package might be missing, causing the variables to resolve to empty strings. Fix: sudo apt install lsb-release.

FAQ

Frequently Asked Questions

Will unattended-upgrades automatically upgrade my Ubuntu version (e.g. 22.04 to 24.04)?

No. unattended-upgrades only handles package-level updates within your current Ubuntu release. Major version upgrades (like 22.04 to 24.04) require running `do-release-upgrade` manually. These are intentionally kept separate because major upgrades carry much more risk and should always be done with a backup and a maintenance window.

Is it safe to enable automatic updates on a production server?

For security-only updates, yes — in my experience the risk of not patching outweighs the risk of a security patch causing breakage. For general updates or kernel updates with auto-reboot, it depends on your tolerance for unplanned downtime. I’d recommend enabling security updates automatically and reviewing everything else manually.

How do I check which packages were automatically updated?

Check the log at /var/log/unattended-upgrades/unattended-upgrades.log. It records every package installed, the date, and any errors. For a quick summary of recent changes across all apt activity (not just unattended-upgrades), you can also check /var/log/dpkg.log.

Can I exclude specific packages from being automatically updated?

Yes. In /etc/apt/apt.conf.d/50unattended-upgrades, find the Package-Blacklist section and add package names there. For example, to prevent MySQL from being auto-updated: add “mysql-server”; inside the block. This is useful for packages where you want to control the upgrade timing yourself.

Does unattended-upgrades work on Ubuntu minimal or server installs?

Yes, but you may need to install it manually — it’s not always included in minimal cloud images. Run sudo apt install unattended-upgrades to get it. Also double-check that lsb-release is installed, since the config file uses distro name variables that depend on it.

SHARE THIS ARTICLE

Need help with your hosting?

Host & Tech provides 24/7 support for all VPS, dedicated, and shared hosting customers.

Scroll to Top