New Nginx Virtual Host is a Bash script to simplify the process of setting up a new virtual host in Nginx with proper configuration and SSL certificate from Let’s Encrypt. Link to the script on Github can be found at the bottom of the page.
The script:
- Creates the necessary vHost directories:
- Website Root:
/var/www/domain.com/wwwroot/
- Log folder:
/var/www/domain.com/logs/
- Website Root:
- Sets up a temporary HTTP-only Nginx configuration to allow Certbot to verify the domain.
- Requests an SSL certificate using Certbot.
- Replaces the temporary Nginx configuration with a final secure version supporting HTTPS and proper PHP handling.
Nginx Configuration
- The Nginx configuration contains a HTTP server block used for ACME challenge and Cloudflare Flexible mode. If DNS is not proxied by Cloudflare Flexible mode, it will redirect to the HTTPS server block.
- Both HTTP and HTTPS will 301 redirect www to non-www.
- Index files allowed, in order: index.php index.html index.htm default.cshtml, default.aspx, default.asp
- If a file or directory is not found, the server will fall back to /index.php
- PHP with FastCGI is configured in the script. You might need to adjust PHP version and other PHP settings to your needs.
- .ht and .git files are denied, as well as xmlrpc.php (WordPress).
This script implements the ACME Challenge method for SSL certificate issuance and renewal using Certbot. By configuring the .well-known/acme-challenge/
directory within the Nginx virtual host, Certbot can automatically verify domain ownership over HTTP (port 80). This means users do not need to set up DNS-based challenges for SSL renewal.
However, automatic renewal is not configured by this script. To ensure certificates remain valid, users must manually set up a cron job or systemd timer to run:
sudo certbot renew --quiet
It is recommended to schedule this command to run at least twice per day to allow Certbot to handle retries in case of temporary failures.
I’ve made a complete guide on: How to Renew Let’s Encrypt SSL Certificates with Certbot and Cron Job
Cloudlfare Notice
Before running the script, if you use Cloudflare, be sure to log in and navigate to the DNS settings for your domain, and toggle the proxy status (orange cloud) to ‘DNS Only’ (grey cloud) for the A record of domain.com and www.domain.com. This ensures Certbot can reach your server on port 80 to validate the SSL certificate.
After the script completes and the SSL certificate is issued, you can safely re-enable Cloudflare proxying by toggling the orange cloud back on.
Renewals however will work with proxy on as they are handled by the HTTP server block.
Usage
To use the script, simply run it with admin privileges:
./new-nginx-vhost.sh domain.com
You will be prompted to specify an email address for Certbot notifications.
Afterwards you will be promoted to specify ‘X-Powered-By’ header. Write what ever you like, or leave it empty, and header will be completely removed from the configuration.
As per best practice, don’t expose any version numbers in the ‘X-Powered-By’ header.
That’s it, the script will take care of the rest!