How to Install Nginx Mainline on Ubuntu 26.04, 24.04 and 22.04

Last updated Thursday, May 7, 2026 6:19 pm Joshua James 7 min read 2 comments

Installing Nginx Mainline on Ubuntu from the nginx.org APT repository gives you upstream mainline packages instead of the release-frozen Nginx builds in Ubuntu’s default archive. Use this path when you specifically want nginx.org mainline updates delivered through APT with repository pinning, while keeping the package separate from Ubuntu’s older archive version.

Mainline is a branch choice, not always the highest visible version number at every point in the Nginx release cycle. If you want nginx.org’s current stable branch instead, use the guide on how to install Nginx on Ubuntu.

Compare Nginx Mainline, Stable, and Ubuntu Packages

Nginx packages for Ubuntu can come from three practical sources: Ubuntu’s own archive, the nginx.org stable repository, or the nginx.org mainline repository. The source controls how quickly you receive upstream changes and which packaging assumptions apply.

Package SourceBranch or Version CadenceBest FitTrade-off
Ubuntu repository packageRelease-frozen package series, such as 1.28.x on 26.04, 1.24.x on 24.04, and 1.18.x on 22.04Servers that prioritize Ubuntu archive integration and fewer upstream branch changesOlder Nginx feature set on long-term support releases
nginx.org stable repositoryCurrent upstream stable branch, currently 1.30.xServers that want upstream Nginx packages but prefer the stable branchNew feature work waits for the next stable branch
nginx.org mainline repositoryMainline branch packages, currently 1.29.x until the next mainline branch opensServers that intentionally track mainline branch updates from nginx.orgNew features can affect third-party module compatibility sooner

The installation path here uses the nginx.org Linux package repository for mainline packages on Ubuntu 26.04, 24.04, and 22.04. Current nginx.org metadata publishes separate suites for resolute, noble, and jammy, so no older-suite workaround is needed.

If you came here for the Ondrej PPA, keep the source distinction clear. ppa:ondrej/nginx is third-party packaging that Launchpad currently labels as NGINX Stable, and Launchpad now labels the old ppa:ondrej/nginx-mainline builds as deprecated. This installation flow uses nginx.org directly instead.

Install Nginx Mainline on Ubuntu

Update Ubuntu and Install Prerequisites

Refresh your package lists before adding the nginx.org repository:

sudo apt update && sudo apt upgrade

Commands that need root privileges use sudo. If your account is not configured for sudo yet, follow the guide on how to add a new user to sudoers on Ubuntu.

Install the tools needed to fetch the signing key, inspect the key, and detect your Ubuntu codename:

sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring -y

The lsb-release package provides lsb_release, and gnupg2 provides the gpg commands used to convert and verify the repository key.

Remove Existing Ubuntu Nginx Packages (Optional)

If Ubuntu’s archive Nginx package is already installed, back up the configuration before switching package sources:

sudo cp -a /etc/nginx /etc/nginx.backup

Stop the service and purge the archive packages. Skip this block on fresh systems where Nginx is not installed yet.

sudo systemctl stop nginx
sudo apt purge nginx nginx-common nginx-core

Review optional dependency cleanup separately so unrelated packages are not removed by surprise:

sudo apt autoremove --dry-run

If the preview only lists packages you no longer need, run the cleanup without forcing automatic confirmation:

sudo apt autoremove

If you install over an existing Nginx package without purging first, dpkg may ask whether to keep modified configuration files. Choose the keep-current-file option when you need to preserve existing server blocks, then compare any package-provided changes afterward.

Import the Nginx Signing Key

Fetch the official Nginx signing key, convert it to a binary keyring, and place it where the repository definition can reference it:

curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg > /dev/null

Inspect the imported key before trusting the repository:

gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg

Relevant output should include the Nginx signing fingerprint 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62. The key file can also contain newer signing keys used by nginx.org.

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

Create a DEB822 source file for the nginx.org mainline repository:

printf '%s\n' \
  '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' | sudo tee /etc/apt/sources.list.d/nginx.sources > /dev/null

The codename and architecture are inserted automatically. On supported Ubuntu LTS releases, that resolves to resolute on 26.04, noble on 24.04, and jammy on 22.04.

Confirm that the source file points at the mainline repository and the correct suite:

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 APT Pinning for Nginx

Pin nginx.org packages at priority 900 so APT prefers them over Ubuntu’s archive packages when package names overlap:

printf '%s\n' \
  'Package: *' \
  'Pin: origin nginx.org' \
  'Pin-Priority: 900' | sudo tee /etc/apt/preferences.d/99nginx > /dev/null

Priority 900 keeps nginx.org ahead of Ubuntu archive packages, which normally appear at priority 500. It does not make unrelated third-party repositories safer, so keep this pin tied to the nginx.org origin only.

Install the Nginx Mainline Package

Update package metadata after adding the source:

sudo apt update

Check the candidate before installation so you can confirm APT is selecting nginx.org at priority 900:

apt-cache policy nginx
nginx:
  Installed: (none)
  Candidate: 1.29.x-1~noble
  Version table:
     1.29.x-1~noble 900
        900 https://nginx.org/packages/mainline/ubuntu noble/nginx amd64 Packages
     1.24.0-2ubuntu7.x 500
        500 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages

Install Nginx when the candidate comes from nginx.org:

sudo apt install nginx

Verify Nginx Mainline on Ubuntu

Confirm the installed Nginx version:

nginx -v
nginx version: nginx/1.29.x

The nginx.org package may not start the service automatically. Start it now and enable it for future boots:

sudo systemctl start nginx
sudo systemctl enable nginx

Use narrow service checks for normal verification:

systemctl is-active nginx
systemctl is-enabled nginx
active
enabled

Test the configuration syntax:

sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Probe the local listener when Nginx is running on the default port:

curl -I http://127.0.0.1/
HTTP/1.1 200 OK
Server: nginx/1.29.x
Content-Type: text/html

Configure UFW Firewall Rules for Nginx

If you use UFW firewall on Ubuntu, allow HTTP and HTTPS traffic to reach Nginx. The nginx.org package does not ship Ubuntu’s Nginx Full, Nginx HTTP, or Nginx HTTPS UFW application profiles, so open the ports directly.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Verify the rules:

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)

Open only the ports your site needs. HTTP-only sites need port 80, HTTPS sites need port 443, and most certificate issuance workflows still need port 80 available for validation or redirects.

Troubleshoot Nginx Mainline on Ubuntu

Nginx Fails to Start with Address Already in Use

If Nginx cannot bind to port 80, check which process owns the listener:

sudo ss -tlnp | grep ':80'

If Apache or another web server is already using the port, stop that service before starting Nginx:

sudo systemctl stop apache2
sudo systemctl disable apache2
sudo systemctl start nginx

APT Reports a Nginx GPG Key Error

If sudo apt update reports a signature error for the nginx.org repository, recreate the keyring and refresh package metadata:

sudo rm -f /usr/share/keyrings/nginx-archive-keyring.gpg
curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg > /dev/null
sudo apt update

Nginx Reports CPU ISA Level Is Lower Than Required

On some Ubuntu 26.04 amd64 systems, especially virtual machines that do not expose AVX and related CPU flags, the current nginx.org package can fail with a CPU ISA message:

nginx: CPU ISA level is lower than required

This error means the installed binary needs CPU features your environment is not exposing. On a VM, enable host CPU passthrough or AVX/AVX2 support if your hypervisor offers it. If the host cannot expose those features, purge the failed nginx.org package and use Ubuntu’s archive package or a source-build path instead.

sudo apt purge nginx

Ubuntu Brotli Module Package Does Not Install with Nginx Mainline

Ubuntu dynamic module packages are built for Ubuntu’s Nginx ABI, not the nginx.org mainline ABI. For example, Ubuntu 24.04’s libnginx-mod-http-brotli-filter package depends on nginx-abi-1.24.0-1, so it cannot be installed beside nginx.org mainline 1.29.x.

sudo apt install nginx libnginx-mod-http-brotli-filter
libnginx-mod-http-brotli-filter : Depends: nginx-abi-1.24.0-1
E: Unable to correct problems, you have held broken packages.

If you need Brotli or another third-party module with nginx.org mainline, use a module path that matches that Nginx build, or consider building Nginx from source on Ubuntu. Do not force Ubuntu ABI module packages onto nginx.org mainline.

Nginx Config Test Shows Errors After Switching Packages

If sudo nginx -t reports errors after switching from Ubuntu’s package to nginx.org mainline, compare your configuration with the backup and check the Nginx changelog for branch changes that affect directives or modules:

diff /etc/nginx/nginx.conf /etc/nginx.backup/nginx.conf

Update Nginx Mainline on Ubuntu

Because nginx.org is configured as an APT source, normal package upgrades deliver future mainline updates:

sudo apt update
sudo apt upgrade

To update only the Nginx package while leaving other upgrades for a later maintenance window, target the package directly:

sudo apt install --only-upgrade nginx

Extend Your Nginx Mainline Setup on Ubuntu

After Nginx Mainline is installed, these related guides cover common web-server stacks, tuning tasks, and security layers:

Nginx Web Application Stacks on Ubuntu

Nginx Performance and Security on Ubuntu

Remove Nginx Mainline from Ubuntu

Stop and disable the service before removing the package:

sudo systemctl disable --now nginx
sudo apt purge nginx

Remove the nginx.org source and pinning file. Delete the keyring only if no other nginx.org repository on the system uses it.

sudo rm -f /etc/apt/sources.list.d/nginx.sources
sudo rm -f /etc/apt/preferences.d/99nginx
sudo rm -f /usr/share/keyrings/nginx-archive-keyring.gpg
sudo apt update

Confirm that the nginx.org source is gone and no Nginx package remains installed:

dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' nginx 2>/dev/null | grep '^ii' || echo "nginx package is not installed"
apt-cache policy nginx
nginx package is not installed
nginx:
  Installed: (none)
  Candidate: 1.24.0-2ubuntu7.x
  Version table:
     1.24.0-2ubuntu7.x 500
        500 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages

If you no longer need any server blocks, TLS snippets, or local site configuration, remove the remaining configuration directory after reviewing its contents:

sudo rm -rf /etc/nginx

Preview optional dependency cleanup before running it:

sudo apt autoremove --dry-run

If the preview only includes packages you intend to remove, run the cleanup interactively:

sudo apt autoremove

Conclusion

Nginx Mainline is now installed from nginx.org with APT pinning, so future branch updates arrive through normal package management. Keep configuration checks part of each change cycle with sudo nginx -t, and use the related Nginx tuning and stack guides when you are ready to add caching, reverse proxy rules, security headers, or a full application stack.

Follow LinuxCapable

Want more LinuxCapable guides in Google?

Add LinuxCapable as a preferred source so Google can show more of our fresh Linux tutorials in Top Stories and From your sources when relevant.

Add LinuxCapable as a preferred source on Google
Search LinuxCapable

Need another guide?

Search LinuxCapable for package installs, commands, troubleshooting, and follow-up guides related to what you just read.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffeeBuy me a coffee

2 thoughts on “How to Install Nginx Mainline on Ubuntu 26.04, 24.04 and 22.04”

  1. 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.

    Reply
    • 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 -rp instead of mv. The updated guide now uses cp -r to preserve the original directory during upgrades. The glob expansion issue you encountered with apt autoremove nginx* is a common pitfall. The shell expands nginx* 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-brotli is 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.

      Reply
Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed in published comments:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<blockquote>quote</blockquote> quote block

Got a Question or Feedback?

We read and reply to every comment - let us know how we can help or improve this guide.

Let us know you are human: