In this serie of guides, I’m going to explain how to install NGINX with Let’s Encrypt and an automatic renewal of SSL certificates. All of this on a Debian 9 server.
By following this guide steps, you’re going to have a NGINX webserver ready to serve static files, PHP websites and also .NET Core web applications!
Prerequisites
- A domain name (OVH sells domains here)
- A wildcard entry in your domain name configuration that points on your root domain site
- A VPS or dedicated server with admin rights and SSH access (OVH also sells VPS and servers!)
- An example website (static html files)
- (if necessary) A PHP Website and PHP installed on your server (PHP 7.2 for this guide but you can adapt the instructions)
- (if necessary) A ASP․NET Core website and ASP․NET Core installed on your server
Preparation
In the first part of this guide, we’re going to only install NGINX and configure Let’s Encrypt but you must already think of the file structure of your website.
I won’t say I have the best practices or the best security but this is how I, a hobbyist sysadmin, have set my own environment. I’ll use one of my latest Linux environments as an real-life example for this guide but won’t use the real domain and subdomains names.
Available websites
Let’s say our domain name is contoso.com and we have several subsites:
1 | - contoso.com (ASP.Net Core Web Application) |
On the server filesystem, these website will be located here:
1 | - contoso.com => /home/www/contoso.com |
NGINX will have a configuration file for each sites (3) and a default configuration file. We’ll also need to add all subdomains to our SSL certificate (blog and php).
NGINX Installation
As always, before installing a new package, we update our repositories and update, if necessary, our installed packages:
1 | sudo apt-get update && sudo apt-get upgrade |
Then we can install NGINX. The package will add a new service to systemd and will start it immediatly.
1 | sudo apt-get install nginx |
Check if you successfully have installed NGINX by getting its systemd status:
1 | sudo service nginx status |
Expected output:
1 | [16:56]lyyn@mayako:~$ sudo service nginx status |
If you can read “Active: active (running)”, your NGINX has been successfully started.
Configuration
NGINX configuration is located in /etc/nginx/
. You set up your different servers (= domains / subdomains) in the sites-available
folder and you activate them by creating a symlink in the sites-enabled
folder.
The default config file will just show the default NGINX page, you can leave it as it is for now but this is a good time to check if you can see this page: in your browser, simply type http://<your server ip>
and you should have the following page shown:
If you get an error, check the following:
- you have an internet access (yes I know but a double check won’t kill anyone)
- NGINX is still running on your server (type
sudo service nginx status
) - You don’t have a firewall on your webserver that blocks the port 80 (TCP)
Setting up our sites
So, we need to create 3 files, one for each sites:
1 | sudo touch /etc/nginx/sites-available/contoso.com |
Let’s configure all of them…
1. contoso․com (ASP․Net Core Web Application)
Edit this site configuration file:
1 | sudo nano /etc/nginx/sites-available/contoso.com |
Assuming that your ASP.Net Core Web Application is running and listening on the port 5000, you’re going to have this configuration file:
1 | server { |
Here, NGINX act as a reverse proxy: it gets the HTTP requests and redirect them, locally, to the Kestrel webserver. When a response is ready, Kestrel give it to NGINX and NGINX will returns with this data.
Configuration file explanation
Each server block describe a new site, or subsite. You can set a specific behavior per site by using this server block.
Properties used:
-
listen: Listening port to use, 80 is the default http port
-
server_name: DNS name to listen to. If someone enters
http://contoso.com
, NGINX will know that it will have to apply the rules in this specific file -
location /: Here, this is used to give a default behavior from the root site level, that will be inherited by all URL paths
- proxy_pass: Set this to the URL listened by the targeted application of the reverse proxy. Our ASP.Net Core Web app listen to the port 5000, so I set that to http://localhost:5000
- proxy_http_version: Proxy version to use. 1.1 allow to use “keepalive” connections and “NTLM authentication” (only used on Windows OS)
- proxy_set_header: Some HTTP headers to add to each request, from the reverse proxy to the web application (values suggested by Microsoft)
- proxy_cache_bypass: Conditions under which the response won’t be taken from the cache (value suggested by Microsoft, again)
2. blog․contoso․com (Static HTML blog)
A static HTML website is simply a website without any server calculation.
Edit this site configuration file:
1 | sudo nano /etc/nginx/sites-available/blog.contoso.com |
This site configuration file will have this content:
1 | server { |
(New) Properties used:
- root: Indicates where are this site files
- index: Tell NGINX what are the default files to read (here, if index.html doesn’t exist, NGINX will try to read index.htm before sending an error)
This is the simplest configuration file as there is no computation done by a specific web server.
3. php․contoso․com (PHP Website)
Here, NGINX will use FastCGI technology to act as a bridge for PHP, and this last one will be use to dynamically generate the pages.
Edit this site configuration file:
1 | sudo nano /etc/nginx/sites-available/php.contoso.com |
And this site configuration will have this content:
1 | server { |
fastcgi_pass
socket path to your proper PHP-FPM executable ⚠ (New) Properties used
- try_files: Here, each request will target a specific file or folder, if these files or folders don’t exist, it will throw a 404 error
- fastcgi_pass: Address of the FastCGI server. Here, this is the PHP-FPM socket
- fastcgi_index: If the URL ends with a “/”, the $fastcgi_script_name variable will be set to this variable value
- fastcgi_intercept_errors: Tells NGINX to intercept the HTTP error codes thrown by the FastCGI server (PHP-FPM)
- fastcgi_param: For the param “SCRIPT_FILENAME”, set the value “fastcgi_script_name”. Here, document root will be “/home/www/php.contoso.com” and $fastcgi_script_name will be the script name to execute (here, by default, it will be “index.php”)
- include: Used here to include the fastcgi_param parameters (only one here, but you can set even more if you want)
NGINX configuration registration
Currently, we only have prepared our files but they won’t be applied by NGINX. We need to create a symlink to our files, from /etc/nginx/sites-enabled/
to /etc/nginx/sites-available
. Let’s do this:
1 | sudo ln -s /etc/nginx/sites-available/contoso.com /etc/nginx/sites-enabled/contoso.com |
Before reloading NGINX and thus applying our new sites configuration, we should if we don’t have any configuration error:
1 | nginx -t |
If no error are reported, you can safely restart NGINX:
1 | sudo service nginx restart |
Now we’re going to install Let’s Encrypt but this will be explained in this blog post: [2/2] Install NGINX with Let's Encrypt on Debian 9 (automatic certificate renewal)