Skip to content

Put your Homelab behind a Reverse Proxy with Nginx Proxy Manager

Access services in your Homelab from the “outside Internet” may be hardly needed but it is fun and therefore, why not do it? I will show you, what you need to set up to get your (multiple) services accessible from the internet using your DYNDNS service of choice and Nginx Proxy Manager.

As always, there are some prerequisites, that need to be fulfilled before getting started with a Reverse Proxy.

  • You need a DYNDNS service configured. Ideally one, that will allow you to add multiple DNS prefixes to your DNS name or, even better, a wildcard DNS. (e.G. service1.someurl.com, service2.someurl.com or *.someurl.com) If you use Hetzner as your DNS Provider, you may want to have a look here for an Ansible Playbook to automate the whole DYNDNS configuration.
  • You need docker and docker-compose setup on a Server or VM.
  • I assume, that you have the services you want to get behind the Proxy Manager are already up and running.

A few quick words for the reason and benefits of a Reverse Proxy. A Reverse Proxy will handle traffic that comes from the “outside” with a given DNS Name in the header and forwards this traffic to the actual service on a given IP or DNS Name on a configureable port. So we can use one entry gate to our network using one set of ports. One additional benefit is, that Nginx Proxy Manager in special, will handle SSL encryption and certificates for us. He will “terminate” SSL connections using a signed certificate from Let’s Encrypt and will “speak” to the service either encrypted or unencrypted in the local network using maybe a self signed certificate from the service itself. So no more quirky messages regarding untrusted certificates and unsafe connections.

First step is to setup the Nginx Proxy Manager as our Reverse Proxy on our Docker host. You can find a detailed installation instruction for Nginx Proxy Manager here. We keep the setup minimal, you can find the docker-compose.yaml also in my Github repository here. In this compose, I’m doing a bind mount of two directories of my docker host. Adapt these to your needs.

docker-compose.yaml
version: '3'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    container_name: nginx-proxy-manager
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - /docker/nginx-reverse/data:/data
      - /docker/nginx-reverse/certs:/etc/letsencrypt

You can see, that we map three ports to the container. Port 80 and 443 for the http and https traffic. Port 81 is for accessing the WebUI of Nxing Proxy Manager. If one of the ports is already in use on your Docker host, feel free to change them as you need (you will have to consider this when doing the port forwarding later 🙂 ). Start the container setup by issueing docker-compose up -d.

You may check the logs of the created container by doing docker logs nginx-proxy-manager. But if you have created the directories and the ports you’ve selected are available, the container should come up without issues. You now can access the WebUI of Nginx Proxy Manager using your browser and the URL like http://mydockerhost:81. The first time logon credentials for Nginx Proxy Manager are the following:

Email:    admin@example.com
Password: changeme

First login

You will then get asked to change the password and provide a new username for the admin user.

So, Proxy Manager is set up and running. Time to get out Internet Router ready to do a “Port forward” to our new Proxy Manager instance. This works a little bit different for every Router, but Google is your friend here. What you want to configure is, forwarding all http (port 80) and https (port 443) traffic that reaches your router, will get forwarded to your Docker host on the ports you’ve configured for your container before (see the docker-compose.yaml).

A quick side note here. In my case, I couldn’t do a direct port forward from my Internet router to my Docker host. The reason is, that my Homelab is located in a different subnet that is not managed by my router. I’ve a second router in between (Mikrotik). In this case, you may need to configure your Internet router, to forward all traffic on the named ports to your second router (using the gateway address). On the second router, you then also have to do a port forward for every request on the respective ports to your Docker host.

So it’s time to configure our webservices. Head back to the WebUI of the Proxy Manager and click on “Proxy Hosts”, then “Add Proxy Host”.

Configure Proxy Host

Under “Domain Names” enter you external DNS Name (the DYNDNS Name, which points to your external IP address). As “Forward Hostname / IP” you enter the local IP address or servername, where your Webservice is reachable. Also configure the according port as “Forward Port”. I recommend to enable “Block Common Exploits”. If you want, you can also add another layer of security, by configure an “Access List” (see below). Under the SSL register, you may also configure a signed Let’s Encrypt certificate. But we leave this for now. Hit “Save” and try to connect to your Webservice using the external (DYNDNS) URL. In this example http://webservice1.mydomain.com. If your Webservice only “speaks” https, you need to specify this under “Scheme” and also provide the according Port (443 in default).

This should already work. So let’s try out to add a SSL certificate to our service. Open the “Proxy Host” again, head to the SSL register and select “Request a new SSL Certificate” from the drop down menu. I recommend here to select “Force SSL” and “HTTP/2 Support”. Provide your valid email address and check the “I agree…” checkbox. By clicking on “Save”, Proxy Manager will try to request a signed certificate using the HTTP challenge (if you haven’t selected DNS challenge though). If all works without an error, you now can access your Webservice using https://webservice1.mydomain.com and you should see now more certificate warning in your browser.

I mentioned the “Access List” above. Using this feature, you can add another authentication level as well as a list of IP addresses that are allowed to access your webservice. If you want all possible IP addresses as a source, you may select “Satisfy Any”. After creating the Access List, you can specify it in your “Proxy Host” and hit “Save” again.

Philip

4 thoughts on “Put your Homelab behind a Reverse Proxy with Nginx Proxy Manager”

    1. Avatar photo

      Hello,

      NPM can’t help you with that AFAIK. You would need something, that either protects you from both scenarios behind or in front of NPM (I would go to behind)

      Philip

  1. Hello,
    I have a keycloak server which is working on 8080. As you mentioned in New Proxy Host page, I’ve set
    “http for scheme”,
    “IP address of keycloak for Forward IP”,
    “8080 for Forward Port”.

    Not working! I’ve got 504 Gateway Time-out. If my service would use port 80 instead of 8080, it would work.

    what’s wrong with Nginx Proxy Manager which works only with 80?

    1. Avatar photo

      Hi,
      I’m sorry, there are to less information here. Have you ensured, that keycloak is really using http and not using https here?
      I can assure you, that NPM is able to handle whichever port you configure in general.

      Philip

Leave a Reply to TheDatabaseMe Cancel reply

Your email address will not be published. Required fields are marked *