Nginx Mainline delivers the latest features, performance improvements, and security patches ahead of the stable branch, making it the recommended choice for reverse proxies, static-site servers, and load balancers that need current TLS support and new modules. Ubuntu’s default repositories ship an older Nginx build that does not receive upstream feature updates or non-critical bug fixes. Installing Nginx Mainline on Ubuntu from the official nginx.org repository with APT pinning locks your system to the latest nginx.org packages and keeps your server current with every upstream release.
Understand Nginx Mainline vs Stable on Ubuntu
The nginx.org repository offers two release branches. Understanding the differences helps you choose the right Nginx version for your environment:
| Branch | Release Cycle | Best For | Trade-offs |
|---|---|---|---|
| Mainline | Frequent updates with new features | Development, testing, production servers that need the latest capabilities | More frequent updates, potential for newer bugs |
| Stable | Only critical fixes backported | Production servers prioritizing long-term stability | Slower access to new features and non-critical fixes |
The Nginx team recommends mainline for most users because it receives all bug fixes, including those that may not be backported to stable. The mainline branch is well-tested before release and suitable for production use. If you prefer the stable branch instead, see the guide on how to install Nginx on Ubuntu.
Ubuntu’s default repositories ship an older Nginx stable version that does not receive upstream feature updates:
| Ubuntu Version | Default Nginx Version | nginx.org Mainline |
|---|---|---|
| 26.04 (Resolute) | 1.28.x | 1.29.x * |
| 24.04 (Noble) | 1.24.x | 1.29.x |
| 22.04 (Jammy) | 1.18.x | 1.29.x |
* nginx.org does not yet publish packages for Ubuntu 26.04 directly. A workaround using the 24.04 repository is covered in the repository section below.
Update Ubuntu and Install Nginx Mainline Prerequisites
Update your package lists and apply any pending security patches before adding the nginx.org repository:
sudo apt update && sudo apt upgrade
This guide uses
sudofor commands that need root privileges. If your user is not in the sudoers file yet, follow the guide on how to add a new user to sudoers on Ubuntu.
Install the packages needed to download the GPG key and configure the repository:
sudo apt install curl ca-certificates lsb-release ubuntu-keyring -y
The lsb-release package provides the lsb_release command used later to detect your Ubuntu codename automatically, and ubuntu-keyring includes the archive signing keys that APT needs for repository verification.
Remove Existing Nginx Installation on Ubuntu (Optional)
If you have a previous Nginx installation from Ubuntu’s default repositories, remove it to prevent package conflicts.
Back Up Nginx Configuration
First, back up your existing configuration so you can restore it after installing the mainline version:
sudo cp -r /etc/nginx/ /etc/nginx.backup/
Stop and Remove Ubuntu Default Nginx
Stop the running service and remove the existing packages:
sudo systemctl stop nginx
sudo apt purge nginx nginx-common nginx-core -y
sudo apt autoremove -y
If you skip removal and install directly over an existing Nginx, dpkg will prompt you about modified config files. Choose N (keep your version) to preserve your existing configuration, then manually review any differences afterward.
Import the Nginx GPG Signing Key on Ubuntu
Download and add the official Nginx signing key to verify package authenticity:
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
Verify the downloaded key contains the correct fingerprints:
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
The output should display three signing keys, including the primary fingerprint 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62:
pub rsa4096 2024-05-29 [SC]
8540A6F18833A80E9C1653A42FD21310B49F6B46
uid nginx signing key <signing-key-2@nginx.com>
pub rsa2048 2011-08-19 [SC] [expires: 2027-05-24]
573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
uid nginx signing key <signing-key@nginx.com>
pub rsa4096 2024-05-29 [SC]
9E9BE90EACBCDE69FE9B204CBCDCD8A38D88A2B3
uid nginx signing key <signing-key-3@nginx.com>
Add the Nginx Mainline Repository on Ubuntu
With the GPG key in place, add the nginx.org mainline repository using the modern DEB822 format:
cat <<EOF | sudo tee /etc/apt/sources.list.d/nginx.sources
Types: deb
URIs: https://nginx.org/packages/mainline/ubuntu
Suites: $(lsb_release -cs)
Components: nginx
Architectures: $(dpkg --print-architecture)
Signed-By: /usr/share/keyrings/nginx-archive-keyring.gpg
EOF
The $(lsb_release -cs) command inserts your Ubuntu codename (noble on 24.04, jammy on 22.04) and $(dpkg --print-architecture) inserts your system architecture (amd64 on most systems). Both run automatically when you paste the block.
At the time of writing, nginx.org publishes mainline packages for Ubuntu 24.04 (
noble) and 22.04 (jammy) but does not yet publish packages for Ubuntu 26.04 (resolute). If you are on 26.04, edit the file and replaceresolutewithnobleon the Suites line:
sudo sed -i 's/Suites: resolute/Suites: noble/' /etc/apt/sources.list.d/nginx.sources
If you prefer the stable branch instead of mainline, replace
mainline/ubuntuwithubuntuin the URIs line above.
Verify the repository was added correctly:
cat /etc/apt/sources.list.d/nginx.sources
Types: deb URIs: https://nginx.org/packages/mainline/ubuntu Suites: noble Components: nginx Architectures: amd64 Signed-By: /usr/share/keyrings/nginx-archive-keyring.gpg
Configure Nginx APT Pinning on Ubuntu
Set up APT pinning to prioritize nginx.org packages over Ubuntu’s default repositories. Without pinning, apt upgrade could replace the mainline version with the older Ubuntu default:
cat <<EOF | sudo tee /etc/apt/preferences.d/99nginx
Package: *
Pin: origin nginx.org
Pin-Priority: 900
EOF
The priority value of 900 ensures nginx.org packages are preferred over Ubuntu’s default nginx packages (which have a priority of 500). This takes effect during the next apt update.
Install Nginx Mainline on Ubuntu
Update your package list to include the new repository, then install Nginx Mainline:
sudo apt update
sudo apt install nginx
During the update, you should see the nginx.org repository listed in the fetch output:
Get:1 https://nginx.org/packages/mainline/ubuntu noble InRelease Get:2 https://nginx.org/packages/mainline/ubuntu noble/nginx amd64 Packages
Confirm that the pinning is working correctly before installing:
apt-cache policy nginx
nginx:
Installed: (none)
Candidate: 1.29.5-1~noble
Version table:
1.29.5-1~noble 900
900 https://nginx.org/packages/mainline/ubuntu noble/nginx amd64 Packages
1.24.0-2ubuntu7.6 500
500 http://archive.ubuntu.com/ubuntu noble/main amd64 Packages
The nginx.org version shows priority 900 while Ubuntu’s version shows 500, confirming that APT will install from nginx.org.
Verify the Nginx Mainline Installation on Ubuntu
Once installation completes, confirm the Nginx Mainline version:
nginx -v
nginx version: nginx/1.29.x
Start and Enable the Nginx Service
Start the Nginx service and enable it to launch at boot:
sudo systemctl start nginx
sudo systemctl enable nginx
Verify the service is running:
systemctl status nginx
● nginx.service - nginx - high performance web server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running)
Test Nginx Configuration Syntax
Validate the configuration file syntax before making any changes:
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Configure UFW Firewall Rules for Nginx on Ubuntu
If you use UFW firewall on Ubuntu, allow HTTP and HTTPS traffic to reach Nginx. The nginx.org mainline package does not include UFW application profiles, so use port numbers directly:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Verify the rules were added:
sudo ufw status
Status: active To Action From -- ------ ---- 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere 80/tcp (v6) ALLOW Anywhere (v6) 443/tcp (v6) ALLOW Anywhere (v6)
If you only need HTTP traffic, omit the
443/tcprule. For HTTPS-only setups, omit80/tcpor add a redirect from port 80 to 443 in your Nginx configuration.
Troubleshoot Nginx Mainline on Ubuntu
Nginx Fails to Start with Address Already in Use
If Nginx fails to start after installation, another process may be using port 80. Check which process owns the port:
sudo ss -tlnp | grep :80
If Apache or another web server is running, stop it before starting Nginx:
sudo systemctl stop apache2
sudo systemctl disable apache2
sudo systemctl start nginx
Nginx GPG Key Verification Fails
If apt update reports a GPG signature error after adding the repository, the key file may be corrupted. Remove and re-download it:
sudo rm /usr/share/keyrings/nginx-archive-keyring.gpg
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
sudo apt update
Nginx Config Test Shows Errors After Upgrade
If nginx -t reports errors after upgrading from the Ubuntu default package, deprecated directives or changed default paths may be the cause. Check the Nginx changelog for breaking changes, and compare your configuration against the backup you created earlier:
diff /etc/nginx/nginx.conf /etc/nginx.backup/nginx.conf
Update Nginx Mainline on Ubuntu
Because the nginx.org repository is configured as an APT source with pinning, Nginx Mainline updates arrive through the standard system update process:
sudo apt update && sudo apt upgrade
To update only Nginx without upgrading other packages:
sudo apt install --only-upgrade nginx
Extend Your Nginx Mainline Setup on Ubuntu
With Nginx Mainline running, these guides help you configure and optimize your web server:
Nginx Web Application Stacks on Ubuntu
- Install WordPress with Nginx, MariaDB, and PHP on Ubuntu for a complete CMS stack
- Set up Nginx FastCGI caching on Ubuntu to improve PHP application performance
- Install Matomo with Nginx on Ubuntu for self-hosted, privacy-focused analytics
- Install phpMyAdmin with LEMP on Ubuntu for a web-based database management interface
- Build Nginx from source on Ubuntu when you need custom modules or compile-time options
Nginx Performance and Security on Ubuntu
- Enable Gzip compression in Nginx to reduce bandwidth and improve page load times
- Configure security headers in Nginx to protect against XSS, clickjacking, and other attacks
- Set up rate limiting in Nginx to protect against brute-force attacks and abuse
- Create a reverse proxy in Nginx to route traffic to backend applications
- Configure www/non-www redirects in Nginx to standardize your domain format
- Install Fail2Ban on Ubuntu to block brute-force login attempts and suspicious traffic
Remove Nginx Mainline from Ubuntu
To completely remove Nginx Mainline and the nginx.org repository from your system, stop the service and purge the package:
sudo systemctl stop nginx
sudo apt purge nginx -y
sudo apt autoremove -y
Remove the repository configuration, APT pinning file, and GPG key:
sudo rm /etc/apt/sources.list.d/nginx.sources
sudo rm /etc/apt/preferences.d/99nginx
sudo rm /usr/share/keyrings/nginx-archive-keyring.gpg
sudo apt update
Verify the removal with apt-cache policy:
apt-cache policy nginx
nginx:
Installed: (none)
Candidate: 1.24.0-2ubuntu7.6
Version table:
1.24.0-2ubuntu7.6 500
500 http://archive.ubuntu.com/ubuntu noble/main amd64 Packages
The output confirms Nginx is uninstalled and only Ubuntu’s default repository version remains as a candidate. The nginx.org source is no longer listed.
Configuration files in
/etc/nginx/remain after package removal. Delete this directory only if you no longer need your server blocks and settings:sudo rm -rf /etc/nginx/
Frequently Asked Questions About Nginx Mainline on Ubuntu
Nginx Mainline receives all new features, bug fixes, and security patches first. The Stable branch only gets critical security fixes and serious bug patches backported from Mainline. The Nginx team recommends Mainline for most users because important non-critical fixes may never reach the Stable branch.
Yes. Despite the name, Mainline undergoes thorough testing before each release and is the branch the Nginx team recommends for production servers. The “mainline” label indicates it is the primary development line, not that it is unstable or experimental.
Ubuntu’s default repositories have a priority of 500. Setting the nginx.org repository to 900 ensures APT always prefers the mainline package over Ubuntu’s default version during installs and upgrades. Without pinning, APT might revert to the older Ubuntu version if it has a higher version string format.
No. The nginx.org mainline package does not ship UFW application profiles like “Nginx Full” or “Nginx HTTP”. These profiles come from Ubuntu’s nginx-common package. When using the nginx.org package, open ports directly with sudo ufw allow 80/tcp and sudo ufw allow 443/tcp instead.
Yes. The ppa:ondrej/nginx-mainline PPA maintained by Ondrej Sury is a popular alternative that also provides Nginx Mainline builds for Ubuntu. This guide uses the official nginx.org repository because it receives updates directly from the Nginx team, often before third-party PPAs. Both sources deliver the same upstream code, so choose whichever fits your workflow.
Conclusion
Nginx Mainline is now running from the official nginx.org repository, with APT pinning at priority 900 ensuring every future update comes from nginx.org rather than Ubuntu’s default packages. Keep it current with sudo apt update && sudo apt upgrade, and validate configuration changes with sudo nginx -t before reloading. From here, consider enabling Gzip compression in Nginx to cut page load times or setting up Nginx FastCGI caching on Ubuntu for PHP applications.
Thanks so much for this guide. It was excellent! I used this to upgrade from 1.24.0 on Ubuntu 24.04 to 1.27.1.
I chose to
cp -rp /etc/nginx /etc/nginx.bak
rather than
mv /etc/nginx /etc/nginx.old
I wasn’t sure if a running Nginx service would have an issue moving the directory.
When I ran
apt autoremove nginx*
I got
E: Unable to locate package nginx.bak
E: Couldn’t find any package by glob ‘nginx.bak’
That may have been because I ran it from the /etc directory, and it picked up the nginx.bak directory I created there. So, instead, I ran
apt autoremove nginx nginx-common nginx-doc
which were all of the packages I had installed.
There may need to be a note at the end stating that if you upgraded from a prior install and you moved the /etc/nginx directory to /etc/nginx.old, you must selectively copy some or all of the files from /etc/nginx.old into the newly created/etc/nginx directory to restore the previous website functionality. Some changes may also be needed if the nginx configuration changes between releases.
If you choose to copy rather than move the /etc/nginx directory, there will be a prompt during installation:
Configuration file ‘/etc/nginx/nginx.conf’
==> Modified (by you or by a script) since installation.
==> Package distributor has shipped an updated version.
What would you like to do about it ? Your options are:
Y or I : install the package maintainer’s version
N or O : keep your currently-installed version
D : show the differences between the versions
Z : start a shell to examine the situation
The default action is to keep your current version.
*** nginx.conf (Y/I/N/O/D/Z) [default=N] ? n
I could not install Brotli Compression. The package libnginx-mod-brotli seems to exist in nginx 1.25.1 but not in 1.27.1. I found a suggestion that it is now in libnginx-mod-http-brotli-filter and libnginx-mod-http-brotli-static, but when I try to install them, they have unmet dependencies.
Thanks for the detailed feedback, Craig. Your observations about the upgrade process are spot on, and the article has since been updated to address several of these points.
You are correct about using
cp -rpinstead ofmv. The updated guide now usescp -rto preserve the original directory during upgrades. The glob expansion issue you encountered withapt autoremove nginx*is a common pitfall. The shell expandsnginx*to match files in the current directory before apt sees it. The guide now specifies exact package names to avoid this.Regarding Brotli, you are right that
libnginx-mod-brotliis unavailable from nginx.org packages. The nginx.org repository provides a minimal package set without third-party modules. For Brotli support with mainline nginx, you would need to compile from source with the Brotli module included.Your tip about the dpkg config prompt is valuable. Users upgrading from an existing installation should generally keep their current version (N) when prompted, then manually merge any needed changes afterward.