[feature] Update details nginx / reverse proxy example #407

Closed
opened 2025-12-29 01:28:26 +01:00 by adam · 5 comments
Owner

Originally created by @kev-the-dev on GitHub (Jan 9, 2023).

Feature request

A common use case is running Headscale behind a reverse proxy like nginx, which can provide the following benefits:

  1. Manipulating / logging / security of connections to Headscale
  2. Hosting additional services behind the same 443 port

The wiki currently has a basic nginx example but I don't believe it is functional anymore. For example, after #788, there appears to be a requirement to pass websocket traffic, but this is not included in the current nginx example.

Additionally, it would be helpful to adapt the example to use case (2) above - i.e. routing the traffic based on HTTP path like /headscale, /ts201 so that the same reverse proxy could be used for multiple services (the current example routes all traffic via path /, which would exclude use case 2.

I'd love to contribute a better example myself, but I haven't gotten one working yet! So wondering if other users / developers may have a working example

Originally created by @kev-the-dev on GitHub (Jan 9, 2023). <!-- Headscale is a multinational community across the globe. Our common language is English. Please consider raising the feature request in this language. --> **Feature request** A common use case is running Headscale behind a reverse proxy like nginx, which can provide the following benefits: 1. Manipulating / logging / security of connections to Headscale 2. Hosting additional services behind the same 443 port The [wiki currently has a basic nginx example](https://github.com/juanfont/headscale/wiki/nginx-configuration) but I don't believe it is functional anymore. For example, after #788, there appears to be a requirement to pass websocket traffic, but this is not included in the current nginx example. Additionally, it would be helpful to adapt the example to use case (2) above - i.e. routing the traffic based on HTTP path like /headscale, /ts201 so that the same reverse proxy could be used for multiple services (the current example routes all traffic via path /, which would exclude use case 2. I'd love to contribute a better example myself, but I haven't gotten one working yet! So wondering if other users / developers may have a working example
adam added the enhancement label 2025-12-29 01:28:26 +01:00
adam closed this issue 2025-12-29 01:28:26 +01:00
Author
Owner

@Schokobecher commented on GitHub (Jan 9, 2023):

This is my current config (using headscale-ui under /web and using certbot-nginx for SSL)

server {
    server_name example.com

    location /web {
        alias /usr/local/www/headscale-ui/web;
        index index.html;
    }

    location / {
        proxy_pass https://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $server_name;
        proxy_redirect http:// https://;
        proxy_buffering off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    keepalive_timeout 70;

}

server {
    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    server_name example.com;
    listen 80;
    return 404; # managed by Certbot
@Schokobecher commented on GitHub (Jan 9, 2023): This is my current config (using `headscale-ui` under `/web` and using `certbot-nginx` for SSL) ``` server { server_name example.com location /web { alias /usr/local/www/headscale-ui/web; index index.html; } location / { proxy_pass https://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $server_name; proxy_redirect http:// https://; proxy_buffering off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot keepalive_timeout 70; } server { if ($host = example.com) { return 301 https://$host$request_uri; } # managed by Certbot server_name example.com; listen 80; return 404; # managed by Certbot ```
Author
Owner

@kev-the-dev commented on GitHub (Jan 9, 2023):

Thanks! I just found the docs page https://github.com/juanfont/headscale/blob/main/docs/reverse-proxy.md which seems to have the same parameters as yours.

So this may be a documentation discoverability issue, where my google search got me to the inaccurate wiki page about Nginx, but users should be directed to https://github.com/juanfont/headscale/blob/main/docs/reverse-proxy.md

@kev-the-dev commented on GitHub (Jan 9, 2023): Thanks! I just found the docs page https://github.com/juanfont/headscale/blob/main/docs/reverse-proxy.md which seems to have the same parameters as yours. So this may be a documentation discoverability issue, where my google search got me to the inaccurate wiki page about Nginx, but users should be directed to https://github.com/juanfont/headscale/blob/main/docs/reverse-proxy.md
Author
Owner

@kev-the-dev commented on GitHub (Jan 9, 2023):

@juanfont Would you be willing to remove the wiki page mentioned above, or perhaps link from that page to the updated documentation?

@kev-the-dev commented on GitHub (Jan 9, 2023): @juanfont Would you be willing to remove the wiki page mentioned above, or perhaps link from that page to the updated documentation?
Author
Owner

@kev-the-dev commented on GitHub (Jan 9, 2023):

I found that my use case of hosting Headscale at a particular path (rather than location /) is currently impossible due to missing support in Headscale, but I moved that to a different ticket #1126

@kev-the-dev commented on GitHub (Jan 9, 2023): I found that my use case of hosting Headscale at a particular path (rather than `location /`) is currently impossible due to missing support in Headscale, but I moved that to a different ticket #1126
Author
Owner

@juanfont commented on GitHub (Jan 9, 2023):

@juanfont Would you be willing to remove the wiki page mentioned above, or perhaps link from that page to the updated documentation?

I have removed the wiki, as it was not in use.

@juanfont commented on GitHub (Jan 9, 2023): > @juanfont Would you be willing to remove the wiki page mentioned above, or perhaps link from that page to the updated documentation? I have removed the wiki, as it was not in use.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#407