Open larrydewey opened 1 month ago
Are you running Headscale and Headplane on different domains? There could be possible CORS issues. In general the handling for that is pretty brittle and I'd ideally want to fix it anyways.
They are both being deployed via docker compose on the same node. The domain will be the same for accessing both, just a different port.
I'm under the impression that it is actually a CORS error that isn't being propagated into logs or the user UI for some reason, the API key does work if you query the API yourself with cURL right? curl -H 'Authorization: Bearer <token>' https://myheadscaleinstance.com/api/
I'm also having this issue, I created a separate Headscale instance so I could test Headplane without breaking my main instance.
Both Headscale and Headplane are running on the same node via docker compose. It's proxied by NPM in the same way that my main instance of Headscale is.
I can query the API myself using curl -H 'Authorization: Bearer *****' http://myheadscaleinstance.com/api/v1/apikeys
from both my device and from inside the Headplane container.
headscale | 2024-06-15T03:48:08Z ERR home/runner/work/headscale/headscale/hscontrol/app.go:414 > failed to validate token error="failed to parse ApiKey" client_address=10.0.1.202:54336
headscale | 2024-06-15T03:48:08Z ERR home/runner/work/headscale/headscale/hscontrol/app.go:414 > failed to validate token error="failed to parse ApiKey" client_address=10.0.1.202:54352
headplane | HeadscaleError: Unauthorized
headplane | at pull (file:///app/build/server/index.js?t=1716228566000:846:11)
headplane | at processTicksAndRejections (node:internal/process/task_queues:95:5)
headplane | at async Promise.all (index 0)
headplane | at loader$8 (file:///app/build/server/index.js?t=1716228566000:1927:31)
headplane | at Object.callRouteLoader (/app/node_modules/.pnpm/@remix-run+server-runtime@2.9.2_typescript@5.4.5/node_modules/@remix-run/server-runtime/dist/data.js:66:16)
headplane | at /app/node_modules/.pnpm/@remix-run+router@1.16.1/node_modules/@remix-run/router/router.ts:4266:21
headplane | at callLoaderOrAction (/app/node_modules/.pnpm/@remix-run+router@1.16.1/node_modules/@remix-run/router/router.ts:4328:16)
headplane | at async Promise.all (index 2)
headplane | at callDataStrategyImpl (/app/node_modules/.pnpm/@remix-run+router@1.16.1/node_modules/@remix-run/router/router.ts:4169:17)
headplane | at callDataStrategy (/app/node_modules/.pnpm/@remix-run+router@1.16.1/node_modules/@remix-run/router/router.ts:3503:19) {
headplane | status: 500
headplane | }
Are you sure either of you are running Headscale 0.23 beta?
I'm using 0.23.0-alpha12. I've included my dev docker compose file below.
services:
db:
image: postgres:latest
environment:
POSTGRES_USER: headscale
POSTGRES_PASSWORD: password
POSTGRES_DB: headscale
ports:
- 5432:5432
volumes:
- ./postgres/data:/var/lib/postgresql/data
server:
image: headscale/headscale:v0.23.0-alpha12
ports:
- 8080:8080
- 9090:9090
- 50443:50443
volumes:
- ./prod_headscale:/etc/headscale
command: serve
depends_on:
- db
ui:
image: ghcr.io/tale/headplane:0.1.5
volumes:
- './headscale:/etc/headscale'
- '/var/run/docker.sock:/var/run/docker.sock:ro'
ports:
- '7070:7070'
environment:
# This is always required for Headplane to work
COOKIE_SECRET: 'Ya1jBVCDeDgjxWg2G92E68HWZ8FyJYqU'
HEADSCALE_INTEGRATION: 'docker'
HEADSCALE_CONTAINER: 'headscale-server-1'
DISABLE_API_KEY_LOGIN: 'false'
HOST: '0.0.0.0'
PORT: '7070'
ACL_FILE: /etc/headscale/acl.yaml
# Overrides the configuration file values if they are set in config.yaml
# If you want to share the same OIDC configuration you do not need this
# OIDC_CLIENT_ID: 'headscale'
# OIDC_ISSUER: 'https://sso.example.com'
# OIDC_CLIENT_SECRET: 'super_secret_client_secret'
# This NEEDS to be set with OIDC, regardless of what's in the config
# This needs to be a very long-lived (999 day) API key used to create
# shorter ones for OIDC and allow the OIDC functionality to work
ROOT_API_KEY: '3BqeIbI6bQ.CQZsbKfKkZfnGuIOmI10DJWfywQLjq-Gr_N1tnCZldI'
depends_on:
- db
- server
Strangely enough, I bit the bullet and deployed it in my "prod" version and it worked seamlessly.
I am running Alpha 12, as well. Let me try the Beta release.
@larrydewey the issue seems to be related to port numbers. Deploying on a domain might fix it.
I had this is exact issue and I can still reproduce this issue in my current setup.
What I tried that didn't work: native linux headscale + native linux headplane running on :3000/admin (non ssl) traefik proxy in front of docker headcale + docker headplane running on :3000/admin (but not proxied by traefik)
What works: traefik proxy in front of docker headcale AND traefik proxied docker headplane...
The major difference in this setup and where I think it needs to be looked into is when using a proxy, I used the endpoint of /admin which is pointing to container port of :3000
But the container itself won't respond on :3000 alone, it wants /admin/ in front of it
this is the config with the traefik labels for clarity:
services:
headscale:
image: 'headscale/headscale:0.23.0-alpha10'
container_name: 'headscale'
restart: 'unless-stopped'
command: 'serve'
volumes:
- '/etc/headscale:/etc/headscale'
- '/var/lib/headscale:/var/lib/headscale'
ports:
- '8080:8080'
networks:
- exposed
environment:
TZ: 'Australia/Sydney'
labels:
- "traefik.enable=true"
## HTTP Routers
- "traefik.http.routers.headscale.entrypoints=websecure"
- "traefik.http.routers.headscale.rule=Host(`headscale.domain.com.au`)"
- "traefik.http.routers.headscalenottls.entrypoints=web"
- "traefik.http.routers.headscalenottls.rule=Host(`headscale.domain.com.au`)"
- "traefik.http.routers.headscale.tls=true"
- "traefik.http.routers.headscale.tls.certresolver=leresolver"
## HTTP Services
- "traefik.http.services.headscale.loadbalancer.server.port=8080"
headplane:
container_name: headplane
image: ghcr.io/tale/headplane:latest
restart: unless-stopped
networks:
- exposed
ports:
- '3000:3000'
volumes:
- "/etc/headscale/config.yaml:/etc/headscale/config.yaml:rw"
- "/etc/headscale/acls.json:/etc/headscale/acls.json:rw"
- '/var/run/docker.sock:/var/run/docker.sock:ro'
# - "/proc:/proc:rw"
environment:
HEADSCALE_URL: 'http://headscale:8080'
COOKIE_SECRET: 'omitted'
CONFIG_FILE: '/etc/headscale/config.yaml'
HEADSCALE_INTEGRATION: 'docker'
HEADSCALE_CONTAINER: 'headscale'
API_KEY: 'omitted'
ACL_FILE: ''
HOST: '0.0.0.0'
PORT: '3000'
labels:
- "traefik.enable=true"
## HTTP Routers
- "traefik.http.routers.headscale-ui.entrypoints=web,websecure"
- "traefik.http.routers.headscale-ui.rule=Host(`headscale.domain.com.au`) && PathPrefix(`/admin`)"
- "traefik.http.routers.headscale-ui.tls.certresolver=leresolver"
## HTTP Services
- "traefik.http.services.headscale-ui.loadbalancer.server.port=3000"
- "traefik.http.services.headscale-ui.loadbalancer.server.scheme=http"
networks:
exposed:
name: exposed
Overview:
When attempting to connect to a newly instantiated instance of headscale, I am attempting to generate a new API key, as per the instructions from the
/admin
interface. However, when I paste the newly created API key, I am getting an error saying it is unable to be parsed. I have tried using older versions, as well, but that does not seem to fix the issue.docker-compose.yaml
Generating API key from Headscale:
Attempting to use the API Key
docker-compose logs from headscale when attempting to use the API key