Skip to content
View in the app

A better way to browse. Learn more.

Unraid

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[Support] Headscale-admin - A UI for headscale

Featured Replies

Summary: Support Thread for Headscale-admin Docker

Application: Headscale-admin

DockerHub: https://hub.docker.com/r/goodieshq/headscale-admin

 

This template has been tested on a production machine. Please read the notes to get the login info.

 

If you find any errors with the template please post here so that I can fix them. If you need some support or guidance also write here.

 

If you find errors in the app itself then please contact the developer through their issues page: https://github.com/GoodiesHQ/headscale-admin/issues

 

Also do note that it's recommended to run this container under the same DNS as the headscale docker.

Edited by gxs
Changed the whole template to a docker with less issues

  • gxs changed the title to [Support] Headscale-admin - A UI for headscale
  • 2 months later...

First of all, thank you for providing this thread.

 

My configuration:

Headscale runs on port 1111 (http)

Headscale-Admin runs on port 1112 (http).

 

My Domain is a subdomain.duckdns.org which is managed by the NGIXProxyManager (jlesage/nginx-proxy-manager). My configuration in there is as follows:

subdomain.duckdns.org points to internalserverip:1111 and has an https certificate by Lets Encrypt. Under Custom Locations, I pointed "subdomain.duckdns.org/admin" to internalserverip:1112.

 

Headscale is working properly on the subdomain, and I have no issues connecting from a remote location. However no luck in accessing the admin panel. If I point to internalserverip:1112 on my lan, I can see the settings page (and only the setting page nothing else seems to work even if I put the token). Howeever if I use subdomain.duckdns.org/admin, I get a blank page only.

 

I think that the configuration I am using is probably not amongst the recommended ones, but can you advise on what I am doing wrong?

 

Thank you for your help.

 

Edit: I was able to solve the issue in the following manner:

 

Do not put anything under "Custom Locations"

 

Put the followinger in your advanced config:

location ^~ /admin/ { proxy_pass http://headscale-admin-ip:port/admin/; proxy_redirect http:// https://; ;

 

location ^~ /admin/ {
        proxy_pass http://headscale-admin-ip:port/admin/;
        proxy_redirect http:// https://;        
}

 

With special thanks to this blog post: https://www.lucasjanin.com/2025/01/03/headscale-tailscale-in-a-self-hosted-environment/

Edited by jpfordtc

  • 5 months later...

i've a problem the container starts but the webui doesn't work even locally

here's the log:

{"level":"info","ts":1750427046.086969,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1750427046.0900357,"msg":"adapted config to JSON","adapter":"caddyfile"}
{"level":"info","ts":1750427046.0963833,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//127.0.0.1:2019","//localhost:2019","//[::1]:2019"]}
{"level":"warn","ts":1750427046.0973032,"logger":"http.auto_https","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv0","http_port":80}
{"level":"info","ts":1750427046.0994487,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000654100"}
{"level":"warn","ts":1750427046.10093,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"warn","ts":1750427046.1009972,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"info","ts":1750427046.10101,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1750427046.1448653,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1750427046.145038,"msg":"serving initial configuration"}
{"level":"info","ts":1750427046.1562846,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/data/caddy"}
{"level":"info","ts":1750427046.1615646,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1750427290.333008,"msg":"shutting down apps, then terminating","signal":"SIGTERM"}
{"level":"warn","ts":1750427290.7241375,"msg":"exiting; byeee!! 👋","signal":"SIGTERM"}
{"level":"info","ts":1750427290.7241929,"logger":"http","msg":"servers shutting down with eternal grace period"}
{"level":"info","ts":1750427290.8150594,"logger":"admin","msg":"stopped previous server","address":"localhost:2019"}
{"level":"info","ts":1750427290.8151479,"msg":"shutdown complete","signal":"SIGTERM","exit_code":0}
{"level":"info","ts":1751397140.596764,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1751397140.6047528,"msg":"adapted config to JSON","adapter":"caddyfile"}
{"level":"info","ts":1751397140.615143,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"warn","ts":1751397140.617368,"logger":"http.auto_https","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv0","http_port":80}
{"level":"info","ts":1751397140.618013,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000177180"}
{"level":"warn","ts":1751397140.6391418,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"warn","ts":1751397140.6391969,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"info","ts":1751397140.639207,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1751397140.6430118,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1751397140.643077,"msg":"serving initial configuration"}
{"level":"info","ts":1751397140.8830633,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/data/caddy"}
{"level":"info","ts":1751397140.932447,"logger":"tls","msg":"finished cleaning storage units"}

  • 5 months later...

This took me a while to work out so I thought I would share my swag config to hopefully help others in the future.

htpasswd configured specifically for the admin section as I would like to be able to add nodes while remote from the server

swag htpasswd -c /config/nginx/.htpasswd

create a file in proxy-confs, I used headscale.subdomain.conf

Both headscale and headscale-admin on my proxynet so containers can be called by name rather than ip.

server {


    listen 443      ssl;
    listen [::]:443 ssl;

    server_name hs.[yourdomian.com];

    include /config/nginx/ssl.conf;

    location / {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app headscale;
        set $upstream_port 8085;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
        proxy_buffering off;
        add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
        auth_basic off;
    }
    
    location /admin/ {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app headscale-admin;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
        proxy_buffering off;
        add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
        auth_basic "Restricted";
        auth_basic_user_file /config/nginx/.htpasswd;
    }
}

Also some changes need to be made to the headscale config as described here: https://gist.github.com/Und3rf10w/1cd618f0656191b7db30fb29aaa35678

Edited by Tristankin

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.