Running apt upgrade updates every installed package on your system. That is fine for routine maintenance, but in production you often need to upgrade just one package – apply a security patch to OpenSSL without touching your database server, or update Nginx while keeping PHP pinned to a tested version. Targeted upgrades reduce risk and keep your change window small.
This guide covers every apt technique for managing individual package versions on Ubuntu and Debian systems – checking installed and available versions, upgrading a single package, pinning versions, downgrading, and simulating changes before applying them.
Prerequisites
- A server or workstation running Ubuntu 24.04 / 22.04 or Debian 13 / 12
- Root or sudo access
- Package index updated – run
sudo apt updatebefore starting
Step 1: Check the Installed Version of a Package
Before upgrading, confirm which version is currently installed. The apt list command shows installed packages filtered by name.
apt list --installed 2>/dev/null | grep nginx
The output shows the package name, version, architecture, and install status:
nginx/noble-updates,now 1.24.0-2ubuntu7.3 amd64 [installed]
For more detail including package size and description, use dpkg -l instead:
dpkg -l nginx
This displays the package status, installed version, and a short description:
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-====================-============-=================================
ii nginx 1.24.0-2ubuntu7.3 amd64 small, powerful, scalable web/proxy server
Step 2: Check the Available Version in Repositories
The apt policy command shows the installed version alongside all available versions from configured repositories. This tells you whether an upgrade is available and which repository provides it.
apt policy nginx
The output lists the installed version, the candidate (version apt would install), and all available versions with their repository sources:
nginx:
Installed: 1.24.0-2ubuntu7.3
Candidate: 1.24.0-2ubuntu7.4
Version table:
1.24.0-2ubuntu7.4 500
500 http://archive.ubuntu.com/ubuntu noble-security/main amd64 Packages
*** 1.24.0-2ubuntu7.3 100
100 /var/lib/dpkg/status
If Installed and Candidate show different versions, an upgrade is available. If they match, the package is already at the latest version in your repositories.
Step 3: Upgrade a Single Package with apt
Use the --only-upgrade flag with apt install to upgrade a single package without installing it if it is not already present. This is the safest approach for targeted upgrades.
sudo apt install --only-upgrade nginx
apt resolves dependencies and shows exactly what will change before asking for confirmation:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be upgraded:
nginx
1 upgraded, 0 newly installed, 0 to remove and 42 not upgraded.
Need to get 614 kB of archives.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n]
The key detail is “1 upgraded, 0 newly installed” – confirming only your target package gets upgraded. If the package is not installed, --only-upgrade does nothing and exits cleanly.
To upgrade multiple specific packages in one command, list them separated by spaces:
sudo apt install --only-upgrade nginx openssl curl
After the upgrade completes, verify the new version is active:
apt policy nginx
Step 4: Upgrade a Package to a Specific Version
Sometimes you need a specific version rather than the latest available. This is common when testing a known-good release or matching a version across multiple servers. Specify the exact version with an equals sign.
sudo apt install nginx=1.24.0-2ubuntu7.4
First list all available versions to get the exact version string:
apt list -a nginx 2>/dev/null
This shows every version available from all configured repositories:
Listing...
nginx/noble-security 1.24.0-2ubuntu7.4 amd64 [upgradable from: 1.24.0-2ubuntu7.3]
nginx/noble,now 1.24.0-2ubuntu7.3 amd64 [installed,upgradable to: 1.24.0-2ubuntu7.4]
Copy the full version string exactly as shown – including the distribution suffix. A typo means apt cannot find the version and the command fails.
Step 5: Hold a Package to Prevent Upgrades
After upgrading to a tested version, you may want to lock it in place so future apt upgrade runs do not change it. The apt-mark hold command prevents a package from being upgraded, removed, or modified. This is useful for managing package repositories where you have added third-party sources and need to control which versions get installed.
sudo apt-mark hold nginx
The confirmation message shows the package is now held:
nginx set on hold.
To verify which packages are currently held:
apt-mark showhold
When you are ready to allow upgrades again, release the hold:
sudo apt-mark unhold nginx
The unhold confirmation reads:
Canceled hold on nginx.
Held packages show as “kept back” during apt upgrade so you always know they were skipped intentionally.
Step 6: Downgrade a Package to a Previous Version
If an upgrade causes problems, you can roll back to a previous version. The syntax is the same as installing a specific version – just specify the older version number.
sudo apt install nginx=1.24.0-2ubuntu7.3
apt warns you about the downgrade and asks for confirmation:
WARNING: The following packages cannot be authenticated!
nginx
Install these packages without verification? [y/N]
After downgrading, hold the package immediately to prevent apt from upgrading it back on the next run:
sudo apt-mark hold nginx
If the older version is no longer available in your repositories, you can download the .deb file from Ubuntu’s package archive or Debian’s snapshot service and install it directly with dpkg:
sudo dpkg -i nginx_1.24.0-2ubuntu7.3_amd64.deb
Step 7: Upgrade from a Specific Repository
When you have multiple repositories providing the same package – for example the default Ubuntu archive and a third-party PPA or vendor repo – you can tell apt to pull specifically from one release. Use the -t flag followed by the release name.
sudo apt install -t noble-security nginx
This forces apt to prefer the version from the noble-security pocket regardless of version priority. It is particularly useful when you want to grab a security fix before it lands in the regular updates channel.
On Debian systems, the release names follow the same pattern:
sudo apt install -t bookworm-backports nginx
Check which releases are configured on your system with:
apt policy | grep -E "release|http"
Step 8: Simulate an Upgrade with Dry Run
Before applying changes to a production system, simulate the upgrade to see exactly what apt would do without actually modifying anything. The --dry-run flag (also available as -s or --simulate) shows the full plan.
sudo apt install --only-upgrade --dry-run nginx
The output looks identical to a real upgrade but prefixes actions with “Inst” and “Conf” instead of actually performing them:
NOTE: This is only a simulation!
apt needs root privileges for real execution.
Inst nginx [1.24.0-2ubuntu7.3] (1.24.0-2ubuntu7.4 Ubuntu:24.04/noble-security [amd64])
Conf nginx (1.24.0-2ubuntu7.4 Ubuntu:24.04/noble-security [amd64])
This reveals dependency changes, removals, and version transitions before you commit. Use it every time on production servers.
To simulate a full system upgrade and see everything that would change:
apt list --upgradable 2>/dev/null
Step 9: Auto-remove Unused Dependencies
When packages are upgraded or removed, their dependencies sometimes become orphaned – installed but no longer required by any package. These waste disk space and increase your attack surface. Clean them up with autoremove.
sudo apt autoremove
apt lists orphaned packages and their total disk usage before asking for confirmation:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
linux-headers-6.8.0-38 linux-headers-6.8.0-38-generic linux-image-6.8.0-38-generic
linux-modules-6.8.0-38-generic linux-modules-extra-6.8.0-38-generic
0 upgraded, 0 newly installed, 5 to remove and 0 not upgraded.
After this operation, 423 MB disk space will be freed.
Do you want to continue? [Y/n]
Old kernel packages are the most common orphans. Running autoremove after kernel upgrades keeps /boot from filling up, which is a common issue on systems with a small boot partition. If you manage a local Ubuntu mirror, unused dependencies also waste mirror disk space.
To also remove cached package files that are no longer available in repositories:
sudo apt autoclean
apt Version Management Commands Reference
This table summarizes all the commands covered in this guide for quick reference when managing package versions on Ubuntu and Debian systems.
| Command | Description |
|---|---|
apt list --installed 2>/dev/null | grep pkg | Check installed version of a package |
dpkg -l pkg | Show detailed package info and status |
apt policy pkg | Show installed and all available versions |
apt list -a pkg | List all available versions from repositories |
sudo apt install --only-upgrade pkg | Upgrade a single package only if installed |
sudo apt install pkg=version | Install or upgrade to a specific version |
sudo apt-mark hold pkg | Prevent package from being upgraded |
sudo apt-mark unhold pkg | Release a held package for upgrades |
apt-mark showhold | List all held packages |
sudo apt install -t release pkg | Install from a specific repository release |
sudo apt install --only-upgrade --dry-run pkg | Simulate upgrade without making changes |
sudo apt autoremove | Remove orphaned dependencies |
sudo apt autoclean | Remove obsolete cached packages |
Conclusion
You now have full control over individual package upgrades on Ubuntu and Debian. The --only-upgrade flag handles targeted updates, apt-mark hold locks packages at a known-good version, and --dry-run lets you preview every change before committing. On production systems, always simulate first, upgrade one package at a time, and hold critical packages after verifying your repository keys are current and your package sources are trusted.