Introduction / Why This Is Needed
Most Debian/Ubuntu users are familiar with basic commands like apt install, apt update, and apt upgrade. However, for server administration, maintaining workstation stability, or fine-tuning an environment, these capabilities are often insufficient.
This guide is dedicated to advanced APT package management. You will learn how to:
- Control updates for individual packages without affecting the entire system.
- Configure repository priorities to install specific software versions.
- Deeply analyze package dependencies and available versions.
- Safely clean the system of unnecessary files and free up space.
After completing this guide, you will have full control over the package lifecycle on your system.
Requirements / Preparation
Before you begin, ensure that:
- You have access to an account with sudo privileges.
- Your system is based on Debian, Ubuntu, or their derivatives (Linux Mint, Pop!_OS).
- Your package list is up-to-date:
sudo apt update. - You are familiar with basic command-line syntax and the concept of a "package" in the context of APT.
Step 1: Package State Management (Hold/Unhold)
It is often necessary to temporarily "freeze" a critical package (e.g., a kernel or library) to prevent it from being updated automatically during apt upgrade.
How to set hold (block):
sudo apt-mark hold <package_name>
For example, to hold the nginx package:
sudo apt-mark hold nginx
How to remove hold (unblock):
sudo apt-mark unhold <package_name>
How to check package states:
apt-mark showhold
This command will list all packages currently in a hold state.
⚠️ Important: Hold does not protect a package from removal via
apt remove. It only blocks upgrade/install operations.
Step 2: Fine-Tuning Priorities (Pinning)
Pinning is a mechanism that allows assigning packages from specific repositories a higher priority than others. This is useful if you want to install a specific package version from, for example, testing or backports without switching the entire system.
- Create a preferences file:
sudo nano /etc/apt/preferences.d/99custom-pin - Add the configuration. Example: assign the
redispackage from thebuster-backportsrepository a priority of 990 (higher than the default 500) to always select the version from there.Package: redis Pin: release a=buster-backports Pin-Priority: 990Pin-Priority: 1001— forces installation of this version, even if it is older.Pin-Priority: 990— installs this version if there is no newer one in other repositories with priority >= 1000.Pin-Priority: 500— the default priority for installation.
- Update the cache and install/upgrade the package:
sudo apt update sudo apt install redis
APT will select the version frombuster-backportsaccording to the pinning rule.
💡 Tip: Use
apt-cache policy <package_name>to view all available versions of a package and their repositories.
Step 3: Managing Package Sources (sources.list)
Modern systems use not a single /etc/apt/sources.list file, but the /etc/apt/sources.list.d/ directory, where each file is a separate source (e.g., from Docker, NodeSource). This is convenient for management.
- View current sources:
ls -la /etc/apt/sources.list* cat /etc/apt/sources.list ls /etc/apt/sources.list.d/ - Add a new repository (example for Docker):
Note thecurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullsigned-byparameter — this is a modern, more secure method for specifying a key than the deprecatedapt-key. - Remove an unnecessary source: simply delete the corresponding file from
/etc/apt/sources.list.d/:sudo rm /etc/apt/sources.list.d/старый-репозиторий.list - Don't forget to update the cache:
sudo apt update
Step 4: Efficient System Cleanup
Over time, the system accumulates old package versions, configuration files from removed packages, and cache. This can take up hundreds of megabytes.
sudo apt autoremove— removes packages that were installed as dependencies but are no longer needed by any installed package.sudo apt clean— completely clears the local cache (/var/cache/apt/archives/). Package files (.deb) will be re-downloaded on the next install/upgrade.sudo apt autoclean— a milder version of clean. Removes only package files from the cache that are no longer available in the repositories (obsolete versions).- Combined command for full cleanup (use with caution!):
Thesudo apt autoremove --purge sudo apt clean--purgeflag also removes the configuration files of packages being removed byautoremove. Use this only if you are sure the configs are not needed.
Step 5: Advanced Package Search and Analysis
apt-cache is a powerful tool for querying the local package database.
- Search packages by name/description:
apt-cache search <keyword> # Example: search for JSON tools apt-cache search json | grep -i tool - Show detailed information about a package:
apt-cache show <package_name> - Show all available versions of a package and their repositories:
This is the primary command for debugging pinning.apt-cache policy <package_name> - Show dependencies (what is required for installation):
apt-cache depends <package_name> - Show reverse dependencies (what requires this package):
apt-cache rdepends <package_name> - Find the package that provides a specific file (if a file is lost):
First, installapt-file search <filename>apt-fileand update its database:sudo apt install apt-file && sudo apt-file update.
Verification
- For hold/unhold: Run
apt-mark showhold— your package should (or should not) be in the list. - For pinning: Run
apt-cache policy <package_name>. The "Installed" field should display the version from the prioritized repository. - For cleanup: Check the cache size:
sudo du -sh /var/cache/apt/archives/. It should be minimal afterapt clean. - General check: Try running
sudo apt upgradein simulation mode to see which packages will be upgraded and with which versions:sudo apt upgrade --simulate
Potential Issues
- Error
Unable to lock directory /var/lib/dpkg/lock— another process (perhaps another apt instance or synaptic) is using the package manager. Wait or kill the process:sudo killall apt apt-get(use with caution!). - After configuring pinning, a package does not update to the desired version — check
apt-cache policy <package>and ensure the priority (Pin-Priority) is set correctly (usually >= 990 for forced selection). Also verify that the version in the target repository is actually newer. apt autoremovesuggests removing an important package — review the list carefully before confirming. If the package is indeed needed but apt considers it unnecessary, another installed package might have incomplete dependencies. Useapt-cache rdepends <important_package>to find what references it.- GPG errors when adding a new repository — ensure you imported the key correctly (use
signed-byin sources.list) and that the key is not expired.
Additional Resources and Tips
- Always back up important configuration files (
/etc/apt/sources.list,/etc/apt/preferences.d/) before editing them. - For rollback of a problematic install/upgrade, use
apt-get install <package_name>=<version>(specifying the exact version fromapt-cache policyoutput). - The
deborphantool (install viasudo apt install deborphan) helps find "orphans" — packages that are not dependencies of anything else. Useful in combination withapt autoremove. - Never edit files in
/var/lib/apt/lists/manually. These are cached repository metadata and are overwritten onapt update.