Table of Contents#
- Prerequisites
- Step 1: Update the System
- Step 2: Install Nginx
- Step 3: Configure the Firewall
- Step 4: Create a Website Directory and Content
- Step 5: Create an Nginx Server Block
- Step 6: Test the Configuration and Enable the Site
- Step 7: Securing Nginx with Let's Encrypt SSL
- Step 8: Verifying the HTTPS Configuration
- Step 9: (Optional) Enable Automatic Certificate Renewal
- Troubleshooting Common Issues
- Conclusion
- References
Prerequisites#
Before you begin, ensure you have the following:
- A Server Running Debian 12: You can use a virtual private server (VPS) from providers like DigitalOcean, Linode, Vultr, or a local machine.
- A Non-root User with Sudo Privileges: It's a security best practice to avoid using the
rootuser directly. Set up a user account withsudoaccess. - A Registered Domain Name (for HTTPS): To obtain a trusted SSL certificate, you need a domain name that points to your server's public IP address. You can do this by creating an
Arecord in your domain's DNS settings (e.g.,@for the root domain orwwwfor a subdomain). - Terminal Access: You will need to be connected to your server via SSH.
Step 1: Update the System#
First, log in to your server as your sudo user. It's always a good idea to update the local package index and upgrade the existing packages to their latest versions to ensure you have the latest security patches and bug fixes.
sudo apt update
sudo apt upgrade -yIf the upgrade process includes updates to the kernel, you may need to reboot your server with sudo reboot.
Step 2: Install Nginx#
Nginx is available in Debian 12's default repositories, making installation straightforward.
sudo apt install nginx -yOnce the installation is complete, the Nginx service will automatically start. You can verify that Nginx is running with the following command:
sudo systemctl status nginxYou should see an output indicating that the service is active (running).
Step 3: Configure the Firewall#
Debian often comes with iptables or nftables, but ufw (Uncomplicated Firewall) is a user-friendly frontend that is easier to manage. If it's not installed, you can install it.
sudo apt install ufwBefore enabling UFW, we need to ensure we don't get locked out of our SSH connection. Add a rule for OpenSSH.
sudo ufw allow OpenSSHNow, we can add the Nginx profiles. Nginx registers a few profiles with UFW. You can list them with:
sudo ufw app listYou should see:
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
- Nginx HTTP: Opens port 80 (normal, unencrypted web traffic).
- Nginx HTTPS: Opens port 443 (TLS/SSL encrypted traffic).
- Nginx Full: Opens both port 80 and port 443.
Since we will be configuring HTTPS, it's best to allow Nginx Full.
sudo ufw allow 'Nginx Full'Now, enable the firewall. You will see a warning; type y and press Enter to proceed.
sudo ufw enableYou can check the status of the firewall to confirm the rules are active.
sudo ufw statusStep 4: Create a Website Directory and Content#
By default, Nginx on Debian serves content from /var/www/html. However, for better organization, especially if you plan to host multiple sites, it's best practice to create a dedicated directory for your domain.
Replace your_domain with your actual domain name throughout the rest of this guide.
sudo mkdir -p /var/www/your_domain/htmlAssign ownership of the directory to the user you are currently logged in as (e.g., $USER). This makes it easier to manage files without needing sudo for every change.
sudo chown -R $USER:$USER /var/www/your_domain/htmlSet the correct permissions. The 755 permission for directories allows the owner to read, write, and execute, while others can only read and execute.
sudo chmod -R 755 /var/www/your_domainNow, let's create a simple index.html page to test our configuration.
nano /var/www/your_domain/html/index.htmlAdd the following basic HTML content inside the file:
<html>
<head>
<title>Welcome to your_domain!</title>
</head>
<body>
<h1>Success! Your Nginx server is running on your_domain!</h1>
<p>This is a test page.</p>
</body>
</html>Save and close the file (in nano, press Ctrl+X, then Y, then Enter).
Step 5: Create an Nginx Server Block#
Server blocks (similar to virtual hosts in Apache) allow you to host multiple websites on a single server. We will create a new server block for our domain.
Nginx stores site-specific configurations in /etc/nginx/sites-available/ and enables them by creating a symbolic link to the /etc/nginx/sites-enabled/ directory.
Create a new configuration file for your domain:
sudo nano /etc/nginx/sites-available/your_domainPaste the following configuration into the file. This is a basic configuration that listens on port 80 (HTTP) and points to the root directory we created.
server {
listen 80;
listen [::]:80;
root /var/www/your_domain/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain www.your_domain;
location / {
try_files $uri $uri/ =404;
}
}listen: Directives for IPv4 and IPv6 on port 80.root: The directory from which Nginx will serve the files for this site.index: The order of files Nginx will try to serve if a directory is requested.server_name: This is critical. It should list your domain name(s) that this server block should respond to.
Save and close the file.
Step 6: Test the Configuration and Enable the Site#
Before enabling the new site, it's crucial to test the Nginx configuration for syntax errors.
sudo nginx -tIf the test is successful, you will see:
nginx: configuration file /etc/nginx/nginx.conf test is successful
Now, enable the server block by creating a symbolic link from sites-available to sites-enabled:
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/This can sometimes cause a conflict with the default server block. To avoid this, it's good practice to disable the default site.
sudo rm /etc/nginx/sites-enabled/defaultFinally, reload the Nginx service to apply the changes.
sudo systemctl reload nginxYour website should now be accessible via HTTP. Open your web browser and navigate to http://your_domain. You should see the test HTML page you created.
Step 7: Securing Nginx with Let's Encrypt SSL#
Let's Encrypt is a certificate authority that provides free SSL certificates. We'll use the certbot tool to automate the process.
Install Certbot#
We need to install Certbot and its Nginx plugin.
sudo apt install certbot python3-certbot-nginx -yAllow HTTPS Through the Firewall#
We've already allowed Nginx Full (ports 80 and 443) in Step 3, so we are good to go.
Obtain an SSL Certificate#
Certbot can automatically configure SSL for Nginx by modifying your server block configuration. Run the following command, replacing your_domain and www.your_domain with your details.
sudo certbot --nginx -d your_domain -d www.your_domainThe Certbot utility will guide you through the process:
- It will ask for your email address for urgent renewal and security notices.
- You must agree to the Terms of Service.
- You can choose to share your email with the Electronic Frontier Foundation (optional).
- Finally, you will be asked whether to redirect all HTTP traffic to HTTPS. It is highly recommended to select option 2 (Redirect). This ensures all visitors use the secure version of your site.
If everything is successful, Certbot will congratulate you, and your configuration will be updated. The certificates are stored in /etc/letsencrypt/live/your_domain/.
Certbot automatically reloads Nginx with the new configuration.
Step 8: Verifying the HTTPS Configuration#
Return to your browser and this time, navigate to https://your_domain. You should see your site, and the browser's address bar should indicate a secure connection (usually a padlock icon).
You can also test that the HTTP to HTTPS redirect is working by visiting http://your_domain. It should automatically redirect to the https:// version.
Step 9: (Optional) Enable Automatic Certificate Renewal#
Let's Encrypt certificates are valid for 90 days. The Certbot package we installed sets up a automatic renewal timer, but it's a good idea to test that the renewal process works correctly.
You can test the automatic renewal with a dry run:
sudo certbot renew --dry-runIf no errors are reported, your certificates will be automatically renewed when they have less than 30 days of validity remaining. You can also manually renew all certificates with sudo certbot renew.
Troubleshooting Common Issues#
Nginx fails to start (nginx -t fails):Double-check your server block file for typos, missing semicolons, or incorrect file paths.- "Welcome to nginx" page appears instead of your site: You might not have disabled the default site (
sudo rm /etc/nginx/sites-enabled/default), or yourserver_namedirective might be incorrect. Ensure your domain's DNSArecord correctly points to your server's IP address. DNS changes can take time to propagate. - SSL/T Certificate errors in the browser: The most common cause is an incorrect
server_namein your Nginx configuration or a DNS issue. Ensure the domain in your browser matches exactly the domain you used with thecertbotcommand.
Conclusion#
Congratulations! You have successfully installed and configured Nginx on Debian 12 to host a website secured with HTTPS. You have a solid foundation for hosting web applications. From here, you can explore more advanced Nginx configurations, such as setting up reverse proxies for applications like Node.js or Python (Django/Flask), or adding more security headers.
The combination of Nginx's performance and the free, automated SSL from Let's Encrypt provides a powerful and secure platform for any web project.