Ubuntu’s own repositories don’t always have the version you need. You might want newer PHP, a newer Nginx, or software that isn’t packaged at all. PPAs (Personal Package Archives on Launchpad) and vendor repositories fill the gap. Here’s how to add them properly, and how to remove them when they cause trouble.
Add a PPA
sudo apt install software-properties-common # provides add-apt-repository
sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt install php8.4-fpm
add-apt-repository downloads the PPA’s signing key, writes a source file to /etc/apt/sources.list.d/ and, on current Ubuntu versions, runs apt update itself.
Well-known PPAs used on servers include:
ppa:ondrej/php— current PHP versions. See installing PHP versions.ppa:ondrej/nginx— newer Nginx builds.ppa:deadsnakes/ppa— other Python versions.
PPAs are built for Ubuntu. On Debian, use the equivalent Debian repository the maintainer provides. Ondřej Surý’s packages, for example, are at packages.sury.org.
Add a vendor repository (the modern way)
Many projects, including Docker, PostgreSQL, Node.js, MariaDB, Grafana and Elastic, provide their own apt repositories. The secure pattern stores the vendor key in its own keyring and restricts it to that repository with signed-by:
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" |
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
Why not apt-key?
apt-key add is deprecated and has been removed in newer releases. It also put keys in a global keyring that apt trusted for every repository. With signed-by, a key can only sign packages from its own repository. If you see Key is stored in legacy trusted.gpg keyring warnings, migrate the key to /etc/apt/keyrings/ and add signed-by.
deb822 .sources format
Newer Ubuntu (24.04+) and Debian use a structured format in .sources files:
# /etc/apt/sources.list.d/docker.sources
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: noble
Components: stable
Architectures: amd64
Signed-By: /etc/apt/keyrings/docker.gpg
Both .list and .sources work. Ubuntu’s own sources now live in /etc/apt/sources.list.d/ubuntu.sources.
Check where a package will come from
apt policy php8.4-fpm
This shows the installed version, the candidate version and every repository offering it, with priorities. It’s very useful when a PPA and the official archive both provide a package.
Pinning: limit what a repository may replace
A repository can offer newer versions of packages you’d rather keep from Ubuntu. Pin it so only the packages you want come from there:
# /etc/apt/preferences.d/sury
Package: *
Pin: origin ppa.launchpadcontent.net
Pin-Priority: 100
Package: php8.4*
Pin: origin ppa.launchpadcontent.net
Pin-Priority: 600
Priority 100 means packages from that origin are only used when you ask for them explicitly. Priority 600 makes the named packages preferred.
Remove a PPA or repository
sudo add-apt-repository --remove ppa:ondrej/php
# or delete the file
sudo rm /etc/apt/sources.list.d/ondrej-ubuntu-php-*.sources
sudo rm /etc/apt/keyrings/docker.gpg # and its key, for vendor repos
sudo apt update
To downgrade the packages back to the official versions, use ppa-purge:
sudo apt install ppa-purge
sudo ppa-purge ppa:ondrej/nginx
Before you add a repository
- Trust: a repository’s packages run as root during installation. Only add sources from the project itself or maintainers you trust.
- Release upgrades: do-release-upgrade disables third-party sources. Re-enable them (with the new codename) afterwards, once the vendor supports the new release.
- Support: a PPA may stop publishing for your Ubuntu version. Check before relying on it for production.
- Fewer is better: each extra source slows
apt updateand adds a way for things to break.
Common errors
NO_PUBKEY ABCDEF1234567890 — the repository’s key is missing. Download the key into /etc/apt/keyrings/ and reference it with signed-by.
The repository … does not have a Release file — the repository doesn’t support your release (for example a PPA without builds for your Ubuntu version), or the URL is wrong.
Conflicting values set for option Signed-By — the same repository is defined twice with different keys. Remove the duplicate file.
More fixes are in apt update errors.
Quick reference
| Task | Command |
|---|---|
| Add PPA | sudo add-apt-repository ppa:user/name |
| Remove PPA | sudo add-apt-repository --remove ppa:user/name |
| Downgrade to official | sudo ppa-purge ppa:user/name |
| Key location | /etc/apt/keyrings/*.gpg |
| Source files | /etc/apt/sources.list.d/ |
| Where from? | apt policy pkg |
Related: apt commands and dpkg.