How to Install Nginx on Debian Linux

Nginx handles everything from serving static websites and hosting PHP applications to acting as a reverse proxy for backend services. Whether you need to host a WordPress site, serve a Node.js application, or load balance traffic across multiple servers, Nginx provides the performance and flexibility to handle it. By the end of this guide, you will have a working Nginx installation with server blocks configured, firewall rules in place, and optional SSL encryption ready for production use.

Nginx is available directly from the default Debian repositories, making installation straightforward with no additional repository configuration required. If you need the latest features before they reach Debian stable, see how to install Nginx mainline on Debian.

Preparing Your System Before Nginx Installation

First, ensure your system is updated before installing Nginx. This prevents potential conflicts during the installation and also reduces the risk of compatibility issues and security vulnerabilities.

To update your system packages, run the following:

sudo apt update && sudo apt upgrade -y

This command fetches the list of available updates (via apt update) and then upgrades the current software packages to their latest versions (using apt upgrade). The -y flag automatically confirms the upgrade prompt.

Choose Your Nginx Package

Debian offers several Nginx package variants. On Debian 12 and later, the base nginx package contains the actual web server binary, while variant packages add optional modules on top.

PackageModules IncludedBest For
nginxCore web server onlyMost users, minimal footprint
nginx-corenginx + GeoIP, image-filter, XSLT, mail, streamUsers who need standard modules
nginx-lightnginx + echo moduleMinimal installations with echo support
nginx-fullnginx-core + PAM auth, DAV, GeoIP2, upstream-fairExtended functionality without Lua
nginx-extrasnginx-full + Lua, cache-purge, headers-more, nchanAdvanced users needing Lua scripting

For most users, install the standard nginx package. The base package handles static sites, reverse proxying, and SSL termination without additional modules. Install nginx-core if you need image filtering or GeoIP lookup, or nginx-extras if you require Lua scripting or cache purging. If you need custom modules or specific compile-time options, see how to build Nginx from source on Debian.

Install Nginx Web Server

Now, install Nginx from the default Debian repositories:

sudo apt install nginx -y

Once complete, APT installs Nginx along with its dependencies and automatically starts the service.

Verify Nginx Installation

Next, confirm the installed Nginx version:

nginx -v

Expected output:

nginx version: nginx/1.x.x

Nginx versions vary by Debian release: Debian 11 ships nginx 1.18.0, Debian 12 ships 1.22.1, and Debian 13 ships 1.26.3. Your output will match your specific release.

Additionally, check the Nginx service status:

systemctl status nginx

Expected output (key lines):

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running)

If the status shows “active (running),” Nginx is working correctly. However, if the service is not running, start and enable it with the following command:

sudo systemctl enable nginx --now

Configure UFW Firewall for Nginx

UFW (Uncomplicated Firewall) provides an easy-to-use interface for managing iptables firewall rules. Although it is not installed on Debian by default, you can easily install it from the default repositories. For a comprehensive guide on UFW configuration, see how to install UFW on Debian.

Install UFW Firewall

First, install UFW from the Debian repositories:

sudo apt install ufw -y

Enable UFW Firewall

If you are connected via SSH, allow SSH access before enabling UFW to prevent lockout from your server.

Before enabling UFW, allow SSH connections to prevent being locked out of a remote server:

sudo ufw allow OpenSSH

Now enable UFW:

sudo ufw enable

By default, UFW’s settings block all incoming connections and allow all outgoing ones. As a result, the SSH rule you just added ensures you maintain remote access.

View UFW Application Profiles

UFW uses application profiles, which are sets of rules for specific applications. To see which installed applications have UFW profiles available, simply run:

sudo ufw app list

Allow Nginx Through UFW

Next, configure UFW to allow Nginx connections through HTTP (Port 80), HTTPS (Port 443), or both.

For HTTP (Port 80) only:

sudo ufw allow 'Nginx HTTP'

For HTTPS (Port 443) only:

sudo ufw allow 'Nginx HTTPS'

Alternatively, to allow both HTTP and HTTPS:

sudo ufw allow 'Nginx Full'

Verify Firewall Rules

Finally, confirm your rules are in place by checking the active firewall rules:

sudo ufw status

Expected output:

Status: active

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

Test Nginx in Browser

After setting up UFW, verify you can see the Nginx landing page. In your browser, go to your server’s IP address:

http://your_server_ip

For local setups, use:

http://localhost

If you see the Nginx default welcome page, then the firewall configuration is complete and Nginx is serving traffic correctly.

Create Nginx Server Blocks

Server blocks (similar to Apache virtual hosts) allow you to host multiple domains from a single server. Each domain has its own configuration file with separate document roots and settings. For production sites, you’ll also want to configure www to non-www redirects and URL rewrite rules. Throughout this section, replace example.com with your actual domain name.

Create a Directory for Your Domain

Create a directory for your domain to store your website’s files:

sudo mkdir -p /var/www/example.com/

Assign Ownership to the Nginx Directory

Next, assign directory ownership to the www-data user and group, which Nginx uses by default:

sudo chown -R www-data:www-data /var/www/example.com/

Create a Test HTML Page

After that, create a test HTML page in your domain directory to confirm your Nginx server block works:

sudo nano /var/www/example.com/index.html

Then, add the following HTML code:

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

Once you’ve pasted the code into the nano editor, press CTRL+O to save the changes and then CTRL+X to exit the editor.

Create the Server Block Configuration

Now, create a server block configuration file for your domain:

sudo nano /etc/nginx/sites-available/example.com.conf

Then, add the following configuration:

server {
 listen 80;
 listen [::]:80;

 root /var/www/example.com/;
 index index.html index.htm index.nginx-debian.html;

 server_name example.com www.example.com;

 location / {
  try_files $uri $uri/ =404;
 }
}

This configuration tells Nginx to listen for incoming connections on port 80 for both example.com and www.example.com. Replace the server_name directive with your actual domain.

Enable the Server Block

Subsequently, enable your server block by creating a symbolic link from the sites-available directory to the sites-enabled directory:

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

Configure Server Names Hash Bucket Size

If you use long domain names or host many domains, you may need to increase the server names hash bucket size to avoid configuration errors.

Edit the Main Nginx Configuration

Open the nginx.conf file:

sudo nano /etc/nginx/nginx.conf

Inside this file, look for the line server_names_hash_bucket_size 64; within the http {} block and uncomment it.

This directive allows Nginx to handle long domain names and a larger number of server names by allocating more memory. However, only uncomment this line if you encounter an error about the server names hash bucket size.

Afterward, save the changes and exit the editor by pressing CTRL+O and CTRL+X.

Test and Reload Nginx Configuration

Before restarting Nginx, verify that your configuration syntax is correct:

sudo nginx -t

If your configuration is correct, you’ll see this output:

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

These messages indicate that your Nginx configuration has been successfully validated. Therefore, reload Nginx to apply the changes:

sudo systemctl reload nginx

Test the Server Block

Finally, open your domain in a web browser. You should see the test page confirming your server block is active.

Manage Nginx Service and Files

Set File Permissions for Web Content

Security for files and folders on your web server is paramount. Avoid overly permissive access rights by setting correct permissions for all files and directories in your webroot.

Remember to replace /var/www/example.com/ with your webroot path:

sudo find /var/www/example.com/ -type d -exec chmod 755 "{}" \;
sudo find /var/www/example.com/ -type f -exec chmod 644 "{}" \;

These commands set read and execute permissions for directories and read-write permissions for files for the owner. Groups and others get read-only access. Adjust these permissions as your application demands.

Secure Nginx with Let’s Encrypt SSL

HTTPS encrypts traffic between your server and visitors, which is essential for any production website. Let’s Encrypt provides free SSL certificates that are widely trusted. For a complete walkthrough including advanced configuration options, see how to secure Nginx with Let’s Encrypt on Debian.

First, refresh the package cache and install the Certbot package with Nginx integration:

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

If you see “Unable to locate package”, your main Debian repository may be missing. Run apt-cache policy python3-certbot-nginx to check. Some minimal server installations only include security repositories and need the main repository added.

Then, obtain and install a certificate for your domain:

sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d example.com -d www.example.com

Replace you@example.com with your email address and the domain names with your actual domains. Include both the apex domain (example.com) and www subdomain to match your server block configuration. This command obtains a certificate, configures Nginx to use it, enables HTTP to HTTPS redirection, and adds security headers. For additional hardening, see how to configure security headers in Nginx.

Verify Automatic Certificate Renewal

Let’s Encrypt certificates expire after 90 days. Fortunately, Debian automatically installs a systemd timer that handles certificate renewal, so manual cron configuration is not required.

To confirm this, verify the renewal timer is active:

sudo systemctl status certbot.timer

Expected output:

● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; preset: enabled)
     Active: active (waiting)

Additionally, test that the renewal process works without actually renewing:

sudo certbot renew --dry-run

If the dry run completes without errors, automatic renewal is configured correctly.

Monitor Nginx Server Logs

Monitor your server logs to troubleshoot issues and track visitor activity. Nginx logs are stored in /var/log/nginx/. List the log files:

ls -l /var/log/nginx/

Among these, the most relevant log files are the access.log and error.log. To monitor logs in real-time, use tail -f followed by the path to the log:

tail -f /var/log/nginx/access.log

Update Nginx

Before updating your Nginx server, creating a backup of your current configurations is wise. To back up your main nginx.conf file, use the following command:

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

Alternatively, if you have extensively customized your Nginx setup, you might want to back up your entire Nginx directory:

sudo cp -r /etc/nginx/ /etc/nginx-bkup

With your configurations safely backed up, you can now proceed to update Nginx:

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

Using --only-upgrade updates only Nginx without upgrading other system packages. As a best practice, regularly back up your configurations, especially in complex setups.

Configure Log Rotation

By default, Nginx includes a daily log rotation feature through logrotate. However, you can customize these settings based on your retention and storage requirements.

Edit the Log Rotation Configuration

Open the Nginx logrotate configuration file:

sudo nano /etc/logrotate.d/nginx

Once you open the file, you’ll see content resembling the following. From here, adjust the directives in this file to fit your log retention and rotation needs, especially if you use monitoring tools like fail2ban.

Default Log Rotation Configuration

The default configuration looks like this:

/var/log/nginx/*.log {
  daily
  missingok
  rotate 14
  compress
  delaycompress
  notifempty
  create 0640 www-data adm
  sharedscripts
  prerotate
  if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
  run-parts /etc/logrotate.d/httpd-prerotate; \
  fi \
  endscript
  postrotate
  invoke-rc.d nginx rotate >/dev/null 2>&1
  endscript
}

Log Rotation Parameters Explained

The key settings to adjust are:

  1. Daily: This setting sets the log rotation frequency. While it defaults to ‘daily,’ you can change it to ‘weekly’ or ‘monthly.’ However, daily rotations typically simplify log management.
  2. Rotate 14: This number tells the system how many log files to keep. For example, a setting of ’14’ retains the 14 latest logs. If you want to store only a week of logs, adjust this number to ‘7’.

While Nginx lets you modify other settings, always make changes with care. Otherwise, changing settings without understanding their impact can cause unexpected results. Therefore, ensure you modify these settings to suit your needs without causing unintended issues.

After making changes, test the configuration with a dry run:

sudo logrotate --debug /etc/logrotate.d/nginx

This command simulates log rotation without actually modifying files, allowing you to verify your configuration before it takes effect.

Troubleshoot Common Nginx Issues

If Nginx fails to start or reload, use these diagnostic steps to identify and resolve the problem.

Configuration Syntax Errors

If you see an error like this when reloading Nginx:

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

Test the configuration for syntax errors:

sudo nginx -t

The output identifies the exact file and line number. Fix the typo in the configuration file, then verify:

sudo nginx -t

Expected output after fixing:

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

Port Binding Conflicts

If Nginx fails to start with an error like:

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)

Check which process is using the port:

sudo ss -tlnp | grep -E ':80|:443'

Example output showing Apache using 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 configure Nginx to use a different port. After resolving the conflict, start Nginx and verify:

sudo systemctl start nginx
systemctl status nginx

Review Error Logs

For errors not caught by the syntax test, check the Nginx error log:

sudo tail -50 /var/log/nginx/error.log

Alternatively, filter for specific errors:

sudo grep -i "error" /var/log/nginx/error.log | tail -20

Remove Nginx

If you no longer need Nginx, follow these steps to remove it completely.

First, stop and disable the Nginx service:

sudo systemctl disable nginx --now

Next, remove Nginx and its configuration files:

sudo apt purge nginx -y

Then, remove any orphaned dependencies that were installed with Nginx:

sudo apt autoremove -y

Warning: The following command permanently deletes all Nginx configuration files in /etc/nginx/, including any custom server blocks and SSL configurations. Ensure you have backed up any configurations you want to keep.

If configuration remnants exist after purging, remove them manually:

sudo rm -rf /etc/nginx/

Finally, verify Nginx has been removed:

nginx -v

Expected output:

bash: nginx: command not found

Conclusion

You now have Nginx installed and configured on Debian with server blocks for hosting multiple domains, firewall rules for controlled access, and SSL certificates for encrypted connections. From here, consider enabling Gzip compression to reduce bandwidth usage, configuring rate limiting to prevent abuse, and setting up a database server with MariaDB on Debian or PHP on Debian for dynamic web applications.

2 thoughts on “How to Install Nginx on Debian Linux”

    • 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

Leave a Comment