How to Install Nginx on Debian 13, 12 and 11

Last updated Friday, May 22, 2026 7:57 am Joshua James 9 min read 2 comments

Most self-hosted stacks need a web server or reverse proxy before the rest of the application can do much. That is why many admins install Nginx on Debian for reverse proxies, PHP sites, API front ends, and simple static deployments.

Debian 13 (Trixie), Debian 12 (Bookworm), and Debian 11 (Bullseye) all make Nginx available from the default APT sources, although it is not installed by default on fresh server or minimal images. From those default APT sources, Debian 13 installs Nginx 1.26, Debian 12 installs 1.22, and Debian 11 installs 1.18; if you need newer upstream features, see how to install Nginx mainline on Debian.

Install Nginx on Debian

Start with the standard Debian package unless you already know you need a larger module bundle or the nginx.org mainline repository.

Update Debian Before Installing Nginx

Refresh the package index and install any pending updates before you add the web server.

sudo apt update && sudo apt upgrade -y

These commands use sudo for root privileges. If your account does not have sudo access yet, run the commands as root or follow the guide on how to add a user to sudoers on Debian.

Choose an Nginx Package on Debian

Debian splits Nginx into the standard web server package and optional module bundles. For most servers, nginx is the right starting point because it follows Debian’s default package source and avoids the larger add-on sets unless you need them.

PackageWhat Debian installsBest for
nginxThe standard web server package plus nginx-common on Debian 13 and 12; on Debian 11, APT also pulls nginx-coreMost reverse proxies, static sites, and PHP stacks
nginx-lightThe standard server plus the Echo module bundleMinimal installs that specifically need Echo
nginx-coreGeoIP, image filter, XSLT, mail, and stream modulesServers that need Debian’s standard dynamic modules
nginx-fullauth PAM, DAV, GeoIP2, Echo, subs-filter, upstream-fair, and stream GeoIP2 modulesBroader feature coverage without the largest extras set
nginx-extrasLua, cache purge, headers-more, nchan, Perl, upload progress, and the larger module bundleAdvanced setups that need extra dynamic modules

Current default APT candidates are Nginx 1.26.3 on Debian 13, 1.22.1 on Debian 12, and 1.18.0 on Debian 11. Security revision suffixes can change as Debian publishes updates, so treat the major and minor branch as the important release signal.

If you need custom builds or modules outside Debian’s packaged set, see how to build Nginx from source on Debian.

Install the Nginx Package on Debian

Install the standard Nginx package with APT.

sudo apt install nginx -y

If you picked one of the larger Debian module bundles instead, replace nginx with nginx-light, nginx-core, nginx-full, or nginx-extras.

Verify the Nginx Installation on Debian

On Debian SSH sessions, the nginx binary may live in /usr/sbin, which is not always on an unprivileged user’s PATH. Use sudo nginx -v for a reliable version check.

sudo nginx -v

Expected output on Debian 13:

nginx version: nginx/1.26.3

Debian 12 reports nginx/1.22.1, and Debian 11 reports nginx/1.18.0 from the current default package sources.

Confirm that systemd started the service and enabled it at boot.

systemctl is-active nginx
systemctl is-enabled nginx

Expected output:

active
enabled

Allow Nginx Through UFW on Debian

UFW is optional, but it is the quickest way to keep SSH open while only exposing the HTTP and HTTPS ports you actually need. If you want a full firewall walkthrough, see how to install UFW on Debian.

Install UFW on Debian

Install UFW from Debian’s default repositories.

sudo apt install ufw -y

Allow SSH Before Enabling UFW on Debian

If you are connected over SSH, allow SSH before you enable UFW so you do not lock yourself out of the server.

Use the generic ssh profile name here. It works cleanly across Debian installs and avoids relying on a profile label that may differ on minimal systems.

sudo ufw allow ssh

Review Available Nginx UFW Profiles on Debian

Check which Nginx application profiles UFW already knows about.

sudo ufw app list | grep Nginx

Expected output on Debian 12 and 11:

Nginx Full
Nginx HTTP
Nginx HTTPS

Debian 13 also shows an Nginx QUIC profile. If you are not configuring HTTP/3 right now, Nginx Full is still the normal rule set for a standard web server.

Allow Nginx Traffic and Enable UFW on Debian

Use one profile for the ports you want to expose. Nginx HTTP opens port 80, Nginx HTTPS opens port 443, and Nginx Full opens both ports for the usual HTTP-to-HTTPS web server path.

sudo ufw allow 'Nginx Full'

Use Nginx HTTP or Nginx HTTPS instead when the server should expose only one of those ports.

sudo ufw enable

Verify that both the SSH rule and the Nginx rule are active.

sudo ufw status numbered

Expected output after allowing SSH and Nginx Full:

Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] Nginx Full                 ALLOW IN    Anywhere
[ 3] 22/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 4] Nginx Full (v6)            ALLOW IN    Anywhere (v6)

Test the Nginx Welcome Page on Debian

Open your server IP address in a browser after the service and firewall rules are in place. On a local Debian machine, you can also test with http://localhost.

If the welcome page loads, Nginx is listening and the firewall is not blocking the request path you just opened.

Configure an Nginx Server Block on Debian

Server blocks let one Debian host serve multiple domains with separate document roots and site-specific settings. Replace example.com with your own domain name before you save the configuration; for deeper virtual host patterns, see how to configure Nginx server blocks and virtual hosts.

For production sites, you may also want to redirect non-www or www in Nginx, add rewrite rules in Nginx, or put an application behind a reverse proxy in Nginx.

Create the Web Root for Your Nginx Site on Debian

Create the document root and assign it to the www-data account that Debian’s Nginx service uses.

sudo install -d -o www-data -g www-data /var/www/example.com

Create a Test Page for the Nginx Server Block on Debian

Write a simple test page so you can tell the custom server block apart from Debian’s default welcome page.

printf '%s\n' \
'<html>' \
'  <head><title>Welcome to Example.com</title></head>' \
'  <body><h1>Success! The Nginx server block is working!</h1></body>' \
'</html>' | sudo tee /var/www/example.com/index.html > /dev/null

The tee command writes the file with root privileges. A plain > redirection would still run in your regular shell and fail against a root-owned path.

Create the Nginx Server Block on Debian

Write the site configuration into /etc/nginx/sites-available/.

printf '%s\n' \
'server {' \
'    listen 80;' \
'    listen [::]:80;' \
'    server_name example.com www.example.com;' \
'    root /var/www/example.com;' \
'    index index.html;' \
'    location / {' \
'        try_files $uri $uri/ =404;' \
'    }' \
'}' | sudo tee /etc/nginx/sites-available/example.com.conf > /dev/null

This server block listens on port 80 for both the apex domain and the www hostname, then serves files from /var/www/example.com.

Enable the Nginx Server Block on Debian

Enable the site by creating the symlink that Debian’s Nginx package reads from sites-enabled.

sudo ln -sfn /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com.conf

Debian also enables a default site in /etc/nginx/sites-enabled/default. You can leave it in place, but if you do not want the welcome page to answer unmatched requests, remove that symlink after your own site is working.

sudo rm -f /etc/nginx/sites-enabled/default

Test and Reload the Nginx Configuration on Debian

Validate the configuration before you reload the service.

sudo nginx -t

Expected output:

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

Reload Nginx once the syntax check passes.

sudo systemctl reload nginx

Test the Nginx Server Block on Debian

If your DNS already points at the server, open the domain in a browser. For a quick local test, send a request with the expected host header.

Some minimal Debian installs do not include curl yet. Install it with sudo apt install curl -y if needed, or run the same request from another machine that can reach the server.

curl --noproxy '*' -H 'Host: example.com' http://127.0.0.1/

Expected output:

<html>
  <head><title>Welcome to Example.com</title></head>
  <body><h1>Success! The Nginx server block is working!</h1></body>
</html>

Manage Nginx on Debian

After the web server is online, the next jobs are usually TLS, log review, and routine package updates.

Use systemctl to manage Nginx on Debian

Use reload after configuration changes, restart after deeper package or module changes, and enable --now when you need to bring the service back immediately.

TaskCommand
Reload after a valid configuration editsudo systemctl reload nginx
Restart after package, module, or deeper service changessudo systemctl restart nginx
Enable and start the servicesudo systemctl enable --now nginx
Stop and disable the servicesudo systemctl disable --now nginx

Find Important Nginx Files and Directories on Debian

These are the Debian paths you will return to most often when you manage sites, logs, and the stock welcome page.

PathPurpose
/etc/nginx/nginx.confMain global Nginx configuration file
/etc/nginx/sites-available/Site definitions that are available but not necessarily enabled
/etc/nginx/sites-enabled/Symlinks for the server blocks Nginx actually loads
/var/www/html/Debian’s default web root for the stock welcome page
/var/log/nginx/access.logRequest log
/var/log/nginx/error.logError log for syntax, permissions, and upstream failures

Debian’s Nginx worker processes run as www-data by default, which matters when you set ownership on web roots, PHP-FPM sockets, cache directories, or upload paths.

Secure Nginx with Let’s Encrypt on Debian

Install the Debian Certbot package for Nginx, then confirm that Debian’s renewal timer is active.

sudo apt install python3-certbot-nginx -y

If APT reports Unable to locate package python3-certbot-nginx, refresh the package index with sudo apt update and confirm the main Debian repository is enabled. The package is available from Debian’s main repository on Debian 13, 12, and 11.

systemctl is-enabled certbot.timer
systemctl is-active certbot.timer

Expected output:

enabled
active

Once your DNS records already point at the server, request the certificate and let Certbot update the Nginx configuration for you. Replace the email address and domains with values you control.

sudo certbot --nginx --non-interactive --agree-tos --no-eff-email --redirect --email admin@example.com -d example.com -d www.example.com

Run sudo certbot renew --dry-run only after at least one certificate exists. On a fresh install with no certificates yet, Certbot simply reports No simulated renewals were attempted. Add stricter options such as HSTS only after the HTTPS site is stable, because HSTS tells browsers to keep forcing HTTPS for the domain. For a full walkthrough, see how to secure Nginx with Let’s Encrypt on Debian.

For extra HTTPS hardening after the certificate is in place, see how to configure security headers in Nginx.

Monitor Nginx Logs on Debian

Check the access and error logs when you need to confirm requests, trace reload failures, or inspect traffic. For a fuller log workflow, see the Nginx access and error logs guide.

sudo ls -l /var/log/nginx/
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

Update Nginx on Debian

Use --only-upgrade when you want to update Nginx without turning the command into a full system upgrade.

sudo apt update
sudo apt install --only-upgrade nginx nginx-common -y

If you installed nginx-extras, nginx-full, nginx-core, or nginx-light instead of the standard package, include that package name in the upgrade command too so the matching module bundle stays in sync.

Troubleshoot Nginx on Debian

These checks cover the failure modes most readers hit first: missing commands in SSH sessions, broken configuration syntax, port conflicts with another web service, and the stock welcome page still appearing after you add your own site.

Fix Nginx Command Not Found on Debian

If nginx -v reports command not found, check whether the package is installed before you assume the installation failed.

apt-cache policy nginx

Expected output after installation:

nginx:
  Installed: 1.x.x
  Candidate: 1.x.x
  Version table:
 *** 1.x.x 500
        500 http://security.debian.org/debian-security [your-release]-security/main amd64 Packages

If the package is installed, use sudo nginx -v or the full path /usr/sbin/nginx -v. On some Debian SSH sessions, /usr/sbin is not part of the regular user PATH.

Fix Nginx Configuration Errors on Debian

When a reload fails, test the configuration first so Nginx tells you which file and line caused the problem.

sudo nginx -t

Relevant error output can look like this when a directive is misspelled:

nginx: [emerg] unknown directive "server_nam" in /etc/nginx/sites-enabled/example.com.conf:4

Expected output after you correct the file:

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

Fix Port 80 and 443 Conflicts for Nginx on Debian

If Nginx cannot bind to port 80 or 443, check which process is already listening there.

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
sudo ss -tlnp | grep -E ':(80|443)\b'

Example output when Apache already owns port 80:

LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("apache2",pid=1234,fd=4))

Stop the conflicting service or move one of the listeners to another port. If you need to change Nginx itself, see how to change ports in Nginx.

sudo systemctl start nginx
systemctl is-active nginx
systemctl is-enabled nginx

Expected output after the conflict is resolved:

active
enabled

Fix the Welcome to nginx page after adding a site on Debian

If the browser still shows the stock welcome page, the usual causes are unfinished DNS propagation or Debian’s default site still being enabled.

curl --noproxy '*' -H 'Host: example.com' http://127.0.0.1/

If that request returns your custom page, Nginx is already serving the right server block and DNS is the remaining issue. If it still lands on the stock page and this server only needs your own site, remove the default symlink and reload Nginx.

sudo rm -f /etc/nginx/sites-enabled/default
sudo systemctl reload nginx

Remove Nginx from Debian

Stop the service first, then purge the package and Debian’s shared Nginx files. Keep UFW installed if it manages rules for SSH or other services; remove only Nginx-specific firewall profiles that you no longer need.

sudo systemctl disable nginx --now

If you opened Nginx through UFW, remove the profile rule before purging nginx-common. Debian’s Nginx package owns the UFW application profile file, so deleting the rule is cleaner while the profile still exists.

sudo ufw --force delete allow 'Nginx Full'

Purging only nginx leaves nginx-common and can leave the optional module bundle on Debian 11. Include the common package and bundle names when you want a clean removal.

sudo apt purge nginx nginx-common nginx-core nginx-full nginx-light nginx-extras -y

If you installed the Certbot Nginx plugin for this site and no other certificate workflows need it, purge those packages explicitly. APT marks python3-certbot-nginx as manually installed when you install it directly, so autoremove alone is not the right cleanup path.

sudo apt purge certbot python3-certbot python3-certbot-nginx -y
apt -s autoremove --purge

Run the real autoremove only after you review the simulation and confirm the listed packages belong to this Nginx or Certbot cleanup. Do not delete site content under /var/www/ until you are sure no other server block uses it.

sudo apt autoremove --purge -y

Verify that the main Nginx packages are gone.

sudo apt update
apt-cache policy nginx nginx-common

Expected output:

nginx:
  Installed: (none)
  Candidate: 1.x.x

nginx-common:
  Installed: (none)
  Candidate: 1.x.x

Conclusion

Nginx is running on Debian and ready for static sites, reverse proxies, and the front end of a full web stack. The usual next steps are to secure Nginx with Let’s Encrypt on Debian, install PHP on Debian for dynamic applications, or install MariaDB on Debian when you need a database-backed site.

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 on Debian 13, 12 and 11”

    • Thanks for reporting this, schel4ok. The python3-certbot-nginx package is in the main repository on all current Debian releases (11, 12, and 13). This error typically occurs when the package cache is stale or the main repository is missing from your sources configuration.

      First, refresh your package cache and retry:

      sudo apt update && sudo apt install python3-certbot-nginx -y

      If it still fails, check whether the package is available from your configured repositories:

      apt-cache policy python3-certbot-nginx

      If the output shows “Candidate: (none)”, your main Debian repository is missing. Some minimal server installations only include security repositories. Check your sources with cat /etc/apt/sources.list /etc/apt/sources.list.d/* and ensure you have an entry for your release’s main repository (bullseye, bookworm, or trixie).

      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: