Step-by-step guide to installing Nginx on Debian 12, managing the service, creating a virtual host, and enabling HTTPS with Let’s Encrypt. Written for Boxis customers and system administrators.
Install and configure Nginx on Debian 12 (Bookworm)
Last updated: March 2026
Reading time: ~12 minutes
Audience: System administrators and advanced users managing a Debian 12 server.
Nginx is a high-performance HTTP server and reverse proxy. On Debian 12 (Bookworm), it integrates cleanly with systemd and works well in front of PHP, Node.js, or upstream APIs. This guide walks you through a clean installation, basic hardening, a minimal virtual host, and optional TLS with Let’s Encrypt—without relying on default placeholder content from other vendors.
What you will achieve
- Install Nginx from Debian repositories and verify the service.
- Open HTTP/HTTPS ports safely (UFW example).
- Create an isolated document root and a dedicated
serverblock. - Optionally obtain and renew a Let’s Encrypt certificate with Certbot.
Prerequisites
Before you start, ensure you have:
- A Debian 12 machine (VPS, dedicated server, or VM) with SSH access.
- A user account with
sudoprivileges (avoid working asrootfor routine tasks). - A DNS name (e.g.
app.example.com) pointing to the server’s public IPv4 or IPv6 address, if you plan to use HTTPS and automatic renewal. - Basic familiarity with the shell (
cd,sudo, a text editor).
Boxis note: If your site is hosted on Boxis managed infrastructure, server-level changes may be restricted; open a ticket before modifying the web stack on shared or managed products.
1. Update package index and install Nginx
Refresh the APT index, then install the nginx package:
sudo apt update
sudo apt install -y nginx
Debian ships a well-tested Nginx build; for most workloads this is preferable to third-party repositories unless you need a specific module.
2. Firewall: allow HTTP and HTTPS (UFW)
If UFW is enabled, allow web traffic explicitly:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
sudo ufw status
If you use another firewall (nftables, cloud security groups), open TCP 80 and TCP 443 there instead.
3. Manage Nginx with systemd
Common commands:
| Action | Command |
|---|---|
| Enable at boot | sudo systemctl enable nginx |
| Start | sudo systemctl start nginx |
| Status | sudo systemctl status nginx |
| Reload config (no drop) | sudo systemctl reload nginx |
| Test configuration | sudo nginx -t |
Always run nginx -t after editing configuration files; a syntax error can prevent reloads until fixed.
4. Where configuration lives on Debian
Typical layout:
- Main config:
/etc/nginx/nginx.conf - Site snippets:
/etc/nginx/sites-available/(enabled via symlink insites-enabled/) - Extra includes:
/etc/nginx/conf.d/*.conf
Prefer sites-available / sites-enabled for virtual hosts so you can enable or disable sites without deleting files.
5. Create a virtual host (server block)
Example: host app.example.com with files under /var/www/app.example.com/html.
5.1 Create directories and a test page
sudo mkdir -p /var/www/app.example.com/html
echo '<!DOCTYPE html><html><head><meta charset="utf-8"><title>OK</title></head><body><h1>It works</h1></body></html>' | sudo tee /var/www/app.example.com/html/index.html
sudo chown -R www-data:www-data /var/www/app.example.com
5.2 Add a server block
Create /etc/nginx/sites-available/app.example.com.conf:
server {
listen 80;
listen [::]:80;
server_name app.example.com;
root /var/www/app.example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Enable the site and disable the default page if you do not need it:
sudo ln -sf /etc/nginx/sites-available/app.example.com.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Visit http://app.example.com in a browser (or curl -I http://app.example.com from your workstation).
6. Secure the site with HTTPS (Let’s Encrypt)
Install Certbot and the Nginx plugin:
sudo apt install -y certbot python3-certbot-nginx
Obtain a certificate (replace email and domain):
sudo certbot --nginx -d app.example.com -m you@example.com --agree-tos --non-interactive
Certbot will adjust your Nginx server block for TLS. Verify automatic renewal:
sudo certbot renew --dry-run
Renewal is typically handled by a systemd timer or cron job installed with the package—check systemctl list-timers | grep certbot.
7. Operational best practices
- Reload, not restart, when only configuration changed:
sudo systemctl reload nginx. - Separate logs per site if traffic is high: use
access_log/error_loginside eachserverblock. - Hide version strings where policy allows:
server_tokens off;(often set globally). - PHP or apps behind Nginx: use
fastcgi_passto PHP-FPM orproxy_passto an upstream; keep sockets or ports consistent with your stack. - Back up
/etc/nginx/before major changes.
8. Troubleshooting quick reference
| Symptom | Things to check |
|---|---|
502 Bad Gateway |
Upstream app down; wrong proxy_pass / fastcgi_pass socket or port. |
403 Forbidden |
Directory permissions; root path; SELinux/AppArmor if applicable. |
| Config won’t load | Run sudo nginx -t and fix reported line numbers. |
| Certificate renewal fails | DNS must still point to this server; port 80 reachable for HTTP-01. |
9. Summary
You installed Nginx on Debian 12, allowed web ports, created a dedicated virtual host, and optionally enabled HTTPS with Certbot. For production workloads, review logging, rate limits, and upstream health checks as your traffic grows.
Related topics (internal placeholders)
- Search the Boxis knowledge base:
/{lang}/knowledgebase/search/ - Hosting and DNS basics: use category Hosting & domains when available.
This article is provided for general guidance. Commands and paths may vary slightly depending on your image provider and customizations.