Build Your Homelab: 6 – Reverse Proxy with NGINX

Homelab 6 - Nginx

Taking stock of our homelab, we now have a decent Proxmox node machine up and running with a container to host a WordPress website, and more importantly, a local DNS (Technitium) up and running. We have also set up the Technitium DNS to enable us to go to the website address wordpress.local to access the WordPress website, in stead of going to the savage-to-remember 192.168.1.43 (or whatever, I can’t remember that the container IP address is any more). But what about accessing our Proxmox server? Currently we still have to to 192.168.1.2:8006 to access Proxmox (your IP address may be different). How about we change that to something easier to remember, like proxmox.local? Although we can “kinda” do that with a DNS server, notice the ports number, 8006, at the end of the address. This means that if we add the record proxmox to our local DNS zone pointing to IP address 192.168.1.2, we are still going to be stuck with the port number. In stead of the address being proxmox.local, it will be proxmox.local:8006. That might be acceptable for some, but we can do better. And that is where a reverse proxy has it’s use. NGINX (pronounced “engine-x”) is an open-source web server software known for its high performance and scalability, used as a reverse proxy, load balancer, and HTTP cache.


Step 1: Download NGINX Container Template

By now you should be fairly well versed in accessing your Proxmox instance, so go to the (soon-to-change) website IP address, in our case http://192.168.1.2:8006, and log in with your credentials (default username is root). Once you have logged in, in the left navigation pane, expand your main Proxmox node. Select the drive local, which is the install directory of Proxmox. In the middle navigation pane, select CT Templates to see the list of all of the previously downloaded LXC Container templates. If you don’t have the NGINX template downloaded, click in the main display pane. Search for NGINX and click Download. Once the template download is completed, we can start the creation of a new container.


Step 2: Create a new NGINX Container

In the top right, click the Proxmox - Create CT button. Going through the settings, we need to fill on the following on each screen:

  • General
    In the general screen, fill in the CT ID field, this can be any number normally in the 100 – 999 range, and this is just an ID for the container. We are going to add it just after our DNS container ID, so we use 101. Fill in the hostname, preferably nginx so it is easily identifiable and choose a password. This password is the password for the rootuser of the Linux container.
  • Template
    In the template screen, select the container template. You should only have the option to select localin the Storage dropdown as that is the only place where container templates are installed. In the Template field, select the NGINX container template downloaded in Step 1.
  • Disks
    Now we come to the location where the container will be installed. Select any disk of your choosing and disk size as well. The default 8GB of storage is too much as NGINX does not need that much. You can leave as is or make it smaller, depending on your disk space limitations. (Remember you can increase this later as well if needed). A blank install of NGINX is around 1.1GB, so please make sure to make the disk bigger than that.
  • CPU
    This is just the maximum amount of CPU cores the container has access to. This does not mean that those cores are onlyassigned to this container, it merely states that the container cannot access more than these. We opted for 1 as a reverse proxy only “passes on” the request, it doesn’t actually execute the work behind the request.
  • Memory
    Same as CPU, this states the maximum. The defaults are fine as is, if we need more we can always increase this. An idle NGINX container runs at around 170MB of RAM.
  • Network
    Leave as is and just continue to the next screen. We will do a more in-depth dive of the networking (and firewall) in a future article.
  • DNS
    Again, leave as Use Host Settings, we might change this in a future container or VM.
  • Confirm
    Check that you are happy with all of the settings, and if you are, hit Proxmox - Finish. The installer will run and let you know once done. You are welcome to tick the Start after created option to save you the hassle of starting the newly created container.

Step 3: Configure the NGINX Container

Now we need to configure the Turnkey Linux Template Container, before we can configure NGINX itself. In the left navigation pane, select the newly created nginx container (and start it if it is not running). In the middle navigation pane, select Console to open a console into the container, running in your local browser. You will be greeted with the default Turnkey Linux setup screen. Firstly, a password is needed for the adminer interface. Select a password and confirm it on the following screen. Next up, you will be asked for an API key for your Turnkey Backup and Domain management accounts. For now, just skip this (we will go through the steps in a future article). On the next screen, you can decide if you want to be notified of local system notifications. Either enter your email address and Enable, or just Skip. The following screen will prompt you if you want to install the latest security updates. Actually this updates all packages to their latest versions, so it is a good idea to run this now. Once the update process finished (can take a few minutes), you will be shown all the addresses you can use to access this container. In our case, we see the container is running on IP address 192.168.1.4. Open a new tab (or browser window) and go to the address displayed. You will see a screen where you can either go to the Adminer insterface (for your databases) or the Turnkey Webmin interface to manage the container. You are welcome to have a look at both, but we are not going to use these to set up NGINX. (If you get a certificate security warning for either site, just accept and continue – see flow below).


Step 4: Configure DNS

Next up we need to set up our .local DNS names to point to the NGINX instance (NOT the IP’s of the services). Open up the Technitium DNS web interface we installed in the previous article. Go to Zones, and select the local zone. We now need to add two Records. Firstly, a record with Name of proxmox and secondly a record with name dns. Both records needs to be of type A and must have the IPv4 Address of the NGINX container, in our case 192.168.1.4. Save the records. This means that if we now go to http://dns.local or to http://proxmox.local, we will be “directed” to the NGINX server, and you should see the same interface you saw when going to the IP address directly with the option of going to Adminer or Webmin. This means our DNS is working.

Step 5: Configure NGINX

Back in the Proxmox window, and still in the NGINX container’s console window, run the following command:

cd /etc/nginx/sites-available/

This will change the working directory to that where NGINX stores its configuration files. You can run ls -al to see a list of all files in the directory (we will get to that blue one in a minute). Each of these files are a configuration file and can be seen as a group of sites. We want to add a new file, specifically for all our .local domains, so we will run the command

nano local

This creates a new file, local in the directory and opens it up for editing. We need to add the following:

server {
server_name proxmox.local;
listen 80;
location / {
proxy_pass https://192.168.1.2:8006;
proxy_ssl_verify off;                # Skip SSL verification (if using a self-signed cert)
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;      # Needed for WebSocket support
proxy_set_header Connection "upgrade";
}
}
server {
server_name dns.local;
listen 80;
location / {
include proxy_params;
proxy_pass http://192.168.1.3:5380;
}
}

Please ensure that the indentation is identical, otherwise this will not work

To break it down, the file contains the following:
– Two server blocks, one for proxmox and one for dns.
– The server_name contains the address that the user entered in their browser to reach this nginx configuration. So one is for promxmox.local and one is for dns.local
– Both listens on port 80, which is http.
– With the location as /, meaning there is nothing after the proxmox.local or dns.local address (ex: http://proxmox.local/ and http://dns.local/), we need to do two things:
– Add the header parameters stating that we are passing this request via proxy
– Pass the request (proxy_pass) to the relevant IP address… and port!

Now that we have a way to pass both the IP address and port, go ahead and save the file with Ctrl+S and exit with Ctrl+X (CMD on Mac). Next up we need to “activate” this configuration file. We do that by creating a shortcut (a soft link in Linux terms) to the activated. Run the following command:

ln -s /etc/nginx/sites-available/local /etc/nginx/sites-enabled/

To test that it worked, change into the directory /etc/nginx/sites-enabled/ and run ls-al. You will see one of those blue links for local pointing to the file we created.

We can now test our configuration by running the following command:

nginx -t

If we don’t have any errors, all we need to do is reload NGINX with the following:

systemctl reload nginx

We can now just enter the addresses http://proxmox.local in our browser to access proxmox (without worrying about the port) and the same for http://dns.local to access our Technitium DNS config.

You can now see your Proxmox with http://proxmox.local and your Technitium with http://dns.local:

promxmox local

Going to the http://proxmox.local address will open Proxmox

dns local

Going to http://dns.local will open Technitium DNS

Just a quick note, if it does not work immediately, it might be because your machine has not updated the DNS. Give it some time, or restart the machine to update the configuration


Conclusion

In conclusion, we’ve successfully transformed our homelab’s accessibility by integrating a reverse proxy with NGINX into our Proxmox environment. By setting up the NGINX container and configuring both our local DNS records and the proxy settings, we’ve replaced cumbersome IP addresses and port numbers with memorable, user-friendly domain names like proxmox.local and dns.local. This not only streamlines our workflow but also provides a scalable foundation for managing multiple services efficiently. As you continue to expand your homelab, remember that this approach can be adapted to a variety of applications, ensuring a cleaner, more organized network setup. Enjoy the newfound simplicity and flexibility that comes with a well-configured reverse proxy!