How to Install Nginx Mainline on Ubuntu Linux

Nginx Mainline provides the latest features, performance improvements, and bug fixes before they reach the stable branch. Whether you’re setting up a reverse proxy, serving static sites, or load balancing web applications, the mainline version delivers new modules, updated TLS support, and security patches ahead of the stable release cycle. This guide walks you through installing Nginx Mainline from the official nginx.org repository on Ubuntu.

Choose Your Nginx Version

The nginx.org repository offers two release branches. Understanding the differences helps you choose the right version for your environment:

VersionRelease CycleBest ForTrade-offs
MainlineFrequent updates with new featuresDevelopment, testing, users who want latest capabilitiesMore frequent updates, potential for newer bugs
StableOnly critical fixes backportedProduction servers prioritizing stabilitySlower access to new features

For most users, mainline is recommended by the Nginx team 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.

Update System Packages

Before installing new software, ensure your Ubuntu system has the latest package information and security updates:

sudo apt update && sudo apt upgrade

Install Prerequisites

Next, install the packages required to add and verify the nginx.org repository:

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

Remove Existing Nginx Installation (Optional)

If you have a previous Nginx installation from Ubuntu’s default repositories, remove it to prevent package conflicts. First, back up your existing configuration:

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

Then, 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 Key

Now, download and add the official Nginx signing key to verify package authenticity:

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

Then, verify the downloaded key contains the correct fingerprint:

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

The output should display the full fingerprint 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 along with additional signing keys:

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 Repository

With the GPG key in place, add the nginx.org mainline repository to your system. This command creates a repository configuration file 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

If you prefer the stable branch instead of mainline, replace mainline/ubuntu with ubuntu in 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 APT Pinning

Additionally, set up APT pinning to prioritize nginx.org packages over Ubuntu’s default repositories:

cat <<EOF | sudo tee /etc/apt/preferences.d/99nginx
Package: *
Pin: origin nginx.org
Pin-Priority: 900
EOF

This pinning configuration takes effect during the next apt update. The priority value of 900 ensures nginx.org packages are preferred over Ubuntu’s default nginx packages (which have a priority of 500).

Install Nginx Mainline

Finally, update your package list to include the new repository, then install Nginx:

sudo apt update
sudo apt install nginx

During the update, you should see the nginx.org repository listed:

Get:1 https://nginx.org/packages/mainline/ubuntu noble InRelease
Get:2 https://nginx.org/packages/mainline/ubuntu noble/nginx amd64 Packages

Confirm the pinning is working correctly:

apt-cache policy nginx | head -8
nginx:
  Installed: (none)
  Candidate: 1.29.3-1~noble
  Version table:
     1.29.3-1~noble 900
        900 https://nginx.org/packages/mainline/ubuntu noble/nginx amd64 Packages
     1.24.0-2ubuntu7 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 pinning works correctly.

Verify the Installation

Once installation completes, confirm Nginx installed correctly by checking the version:

nginx -v

The output displays the mainline version (version number will vary as nginx.org releases updates):

nginx version: nginx/1.29.x

Next, start the Nginx service and enable it to launch at boot:

sudo systemctl start nginx
sudo systemctl enable nginx

Then, verify the service is running:

systemctl status nginx
● nginx.service - nginx - high performance web server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
     Active: active (running)

Finally, test the configuration file syntax before making 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 Firewall Rules (Optional)

If you use UFW firewall, allow HTTP and HTTPS traffic to reach Nginx:

sudo ufw allow 'Nginx Full'

Afterward, verify the rule was added:

sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
Nginx Full                 ALLOW       Anywhere
Nginx Full (v6)            ALLOW       Anywhere (v6)

This opens both ports 80 (HTTP) and 443 (HTTPS). Alternatively, to allow only HTTP traffic, use sudo ufw allow 'Nginx HTTP' instead.

Next Steps

With Nginx Mainline installed, consider these guides to extend your setup:

Ubuntu-specific stacks:

Nginx configuration:

Remove Nginx Mainline

To completely remove Nginx and the nginx.org repository from your system:

sudo systemctl stop nginx
sudo apt purge nginx -y
sudo apt autoremove -y

Afterward, remove the repository configuration 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

Note that configuration files in /etc/nginx/ remain after package removal. Therefore, delete this directory only if you no longer need your server blocks and settings.

Conclusion

You now have Nginx Mainline installed from the official nginx.org repository with APT pinning ensuring future updates come from nginx.org. To maintain your installation, keep it current with sudo apt update && sudo apt upgrade, and always test configuration changes with nginx -t before reloading. From here, consider enabling Gzip compression to improve page load times or setting up FastCGI caching if you’re serving PHP applications.

2 thoughts on “How to Install Nginx Mainline on Ubuntu Linux”

  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

Leave a Comment