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, 12, and 11 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
sudofor 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 one base package and several optional module bundles. For most servers, nginx is the right starting point because it gives you the web server itself without forcing the larger add-on sets.
| Package | What Debian adds | Best for |
|---|---|---|
nginx | The base web server plus nginx-common | Most reverse proxies, static sites, and PHP stacks |
nginx-light | The base server plus the Echo module | Minimal installs that still need Echo |
nginx-core | The base server plus GeoIP, image filter, XSLT, mail, and stream modules | Servers that need Debian’s standard dynamic modules |
nginx-full | The base server plus auth PAM, DAV, GeoIP2, Echo, subs-filter, and upstream-fair modules | Broader feature coverage without the largest extras set |
nginx-extras | The base server plus Lua, cache purge, headers-more, nchan, and a larger module bundle | Advanced setups that need extra dynamic modules |
From Debian’s default APT sources, the current package versions are Nginx 1.26.3 on Debian 13, 1.22.1 on Debian 12, and 1.18.0 on Debian 11.
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 base server 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 reportsnginx/1.18.0from the current default package sources.
Confirm that systemd started the service and enabled it at boot.
sudo systemctl status nginx --no-pager
Expected output (key lines):
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (nginx.service; enabled; preset: enabled)
Active: active (running)
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 QUICprofile. If you are not configuring HTTP/3 right now,Nginx Fullis still the normal rule set for a standard web server.
Allow Nginx Traffic and Enable UFW on Debian
Pick the profile that matches the traffic you want to expose, then enable the firewall.
sudo ufw allow 'Nginx HTTP'
sudo ufw allow 'Nginx HTTPS'
sudo ufw allow 'Nginx Full'
If you need both ports 80 and 443, use Nginx Full. That is the profile most Debian web servers need.
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 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 -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
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 /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
curlyet. Install it withsudo apt install curl -yif needed, or run the same request from another machine that can reach the server.
curl -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.
sudo systemctl reload nginx
sudo systemctl restart nginx
sudo systemctl enable --now nginx
sudo 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.
| Path | Purpose |
|---|---|
/etc/nginx/nginx.conf | Main 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.log | Request log |
/var/log/nginx/error.log | Error 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
sudo systemctl status certbot.timer --no-pager
Expected output (key lines):
● certbot.timer - Run certbot twice daily
Loaded: loaded (certbot.timer; enabled; preset: enabled)
Active: active (waiting)
Once your DNS records already point at the server, request the certificate and let Certbot update the Nginx configuration for you.
sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email you@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. 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.
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 base package, include that package name in the upgrade command too so the matching module bundle stays in sync with nginx-common.
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.
nginx: [emerg] unknown directive "server_nam" in /etc/nginx/sites-enabled/example.com.conf:4
sudo nginx -t
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'
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
sudo systemctl status nginx --no-pager
Expected output after the conflict is resolved:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (nginx.service; enabled; preset: enabled)
Active: active (running)
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 -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 /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.
sudo systemctl disable nginx --now
Purging only
nginxleavesnginx-commonand/etc/nginx/behind. Include both package names when you want a clean removal.
sudo apt purge nginx nginx-common -y
sudo apt autoremove -y
If you also installed Certbot for this Nginx stack,
sudo apt autoremove -ycan also removecertbot,python3-certbot, and related Python packages once Nginx andnginx-commonare gone. Runapt -s autoremovefirst if you want to preview that removal set.
Your web content under /var/www/ is not removed by APT. Delete only the site directories you created and no longer need.
Verify that both 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
Nginx on Debian FAQ
From Debian’s default package sources, Debian 13 currently installs Nginx 1.26.3, Debian 12 installs 1.22.1, and Debian 11 installs 1.18.0. Those package revisions can change as Debian publishes security updates, but the upstream major and minor versions in this guide were verified from the live APT repositories.
On some Debian SSH sessions, the nginx binary lives in /usr/sbin, which is outside the regular user PATH. The package can be installed and the service can be running even when a plain nginx -v check fails. Use sudo nginx -v or /usr/sbin/nginx -v to verify it.
Most readers should install nginx. It gives you the standard web server without forcing one of Debian’s larger module bundles. Choose nginx-extras, nginx-full, nginx-core, or nginx-light only when you know you need the extra dynamic modules they add.
Debian’s package is the safer default for most production servers because it follows Debian’s security updates and packaging conventions. Use mainline only when you specifically need newer upstream features that Debian stable does not ship yet. If that is your case, see how to install Nginx mainline on Debian.
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.
Reading package lists… Done
Building dependency tree… Done
Reading state information… Done
E: Unable to locate package python3-certbot-nginx
Thanks for reporting this, schel4ok. The
python3-certbot-nginxpackage 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:
If it still fails, check whether the package is available from your configured repositories:
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).