diff --git a/headscale/compose.yaml b/headscale/compose.yaml index 052310f..29e2812 100644 --- a/headscale/compose.yaml +++ b/headscale/compose.yaml @@ -1,14 +1,16 @@ services: - server: + headscale: image: headscale/headscale:latest restart: unless-stopped + container_name: headscale-server command: serve networks: - proxy volumes: - - ./config:/etc/headscale + - ./config/headscale.yaml:/etc/headscale/config.yaml - data:/var/lib/headscale labels: + - "me.tale.headplane.target: headscale" - "traefik.enable=true" - "traefik.docker.network=proxy" - "traefik.http.services.headscale.loadbalancer.server.port=8080" @@ -47,33 +49,29 @@ services: - "traefik.http.routers.headscale-metrics-dev.entrypoints=websecure" - "traefik.http.routers.headscale-metrics-dev.service=headscale-metrics" - "traefik.http.routers.headscale-metrics-dev.tls=true" - web: - image: goodieshq/headscale-admin:latest + headplane: + image: ghcr.io/tale/headplane:latest + container_name: headplane restart: unless-stopped - labels: - - "traefik.enable=true" - - "treafik.docker.network=proxy" - - "traefik.http.services.headscale-ui.loadbalancer.server.port=80" - - # Prod Router - - "traefik.http.routers.headscale-ui.rule=Host(`hs.forust.xyz`) && PathPrefix(`/admin`)" - - "traefik.http.routers.headscale-ui.entrypoints=websecure" - - "traefik.http.routers.headscale-ui.middlewares=security-chain@file" - - "traefik.http.routers.headscale-ui.tls=true" - # Local Router - - "traefik.http.routers.headscale-ui-local.rule=Host(`hs.workstation.internal`) && PathPrefix(`/admin`)" - - "traefik.http.routers.headscale-ui-local.entrypoints=websecure" - - "traefik.http.routers.headscale-ui-local.middlewares=security-chain@file" - - "traefik.http.routers.headscale-ui-local.tls=true" - # Dev Router - - "traefik.http.routers.headscale-ui-dev.rule=Host(`hs.gigaforust.internal`) && PathPrefix(`/admin`)" - - "traefik.http.routers.headscale-ui-dev.entrypoints=websecure" - - "traefik.http.routers.headscale-ui-dev.middlewares=security-chain@file" - - "traefik.http.routers.headscale-ui-dev.tls=true" + ports: + - '3000:3000' + volumes: + - ./config/headplane.yaml:/etc/headplane/config.yaml + - ./config/headscale.yaml:/etc/headscale/config.yaml + - headplane-data:/var/lib/headplane + - /var/run/docker.sock:/var/run/docker.sock:ro networks: - proxy + healthcheck: + test: [ "CMD", "/bin/hp_healthcheck" ] + interval: 30s + timeout: 5s + start_period: 5s + retries: 3 volumes: data: + headplane-data: + name: headplane_data networks: proxy: external: true diff --git a/headscale/config/headplane.yaml.example b/headscale/config/headplane.yaml.example new file mode 100644 index 0000000..fc11b0c --- /dev/null +++ b/headscale/config/headplane.yaml.example @@ -0,0 +1,221 @@ +# Configuration for the Headplane server and web application +server: + # These are the default values, change them as needed + host: "0.0.0.0" + port: 3000 + # Should not include the dashboard prefix (/admin) portion. + # # Prod server_url + # base_url: https://hs.forust.xyz + # # Local base_url + # base_url: https://hs.workstation.internal + # # Dev base_url + # base_url: https://hs.gigaforust.internal + + # You may provide `cookie_secret_path` instead to read a value from disk. + # See https://headplane.net/configuration/#sensitive-values + cookie_secret: "" + + # Whether cookies should be marked as Secure + # * Should be false if running without HTTPs + # * Should be true if running behind a reverse proxy with HTTPs + cookie_secure: true + # The maximum age of the session cookie in seconds + cookie_max_age: 86400 # 1 day in seconds + + # This is not required, but if you want to restrict the cookie + # to a specific domain, set it here. Otherwise leave it commented out. + # This may not work as expected if not using a reverse proxy. + # cookie_domain: "" + + # The path to persist Headplane specific data. All data going forward + # is stored in this directory, including the internal database and + # any cache related files. + data_path: "/var/lib/headplane" + + # The info secret is optional and allows access to certain debug endpoints + # that may expose sensitive information about your Headplane instance. + # + # As of now, this protects the /api/info endpoint which exposes details about + # the Headplane and Headscale versions in use. In the future, more endpoints + # may be protected by this secret. + # + # If not set, these endpoints will be disabled. + # info_secret: "" + +# Headscale specific settings to allow Headplane to talk +# to Headscale and access deep integration features +headscale: + # The URL to your Headscale instance + # (All API requests are routed through this URL) + # (THIS IS NOT the gRPC endpoint, but the HTTP endpoint) + # + # IMPORTANT: If you are using TLS this MUST be set to `https://` + url: "http://headscale-server:8080" + + # If you use the TLS configuration in Headscale, and you are not using + # Let's Encrypt for your certificate, pass in the path to the certificate. + # (This has no effect if `url` does not start with `https://`) + # tls_cert_path: "/var/lib/headplane/tls.crt" + + # Optional, public URL if its different from the `headscale.url` + # This affects certain parts of the web UI which shows Headscale's URL + public_url: "https://headscale.example.com" + + # Path to the Headscale configuration file + # This is optional, but HIGHLY recommended for the best experience + # If this is read only, Headplane will show your configuration settings + # in the Web UI, but they cannot be changed. + config_path: "/etc/headscale/config.yaml" + + # Whether the Headscale configuration should be strictly validated + # when reading from `config_path`. If true, Headplane will not interact + # with Headscale if there are any issues with the configuration file. + # + # This is recommended to be true for production deployments to, however it + # may not work if you are using a version of Headscale that has configuration + # options unknown to Headplane. + config_strict: true + + # If you are using `dns.extra_records_path` in your Headscale + # configuration, you need to set this to the path for Headplane + # to be able to read the DNS records. + # + # Pass it in if using Docker and ensure that the file is both + # readable and writable to the Headplane process. + # When using this, Headplane will no longer need to automatically + # restart Headscale for DNS record changes. + # dns_records_path: "/var/lib/headscale/extra_records.json" + +# Integration configurations for Headplane to interact with Headscale +integration: + # The Headplane agent allows retrieving information about nodes + # This allows the UI to display version, OS, and connectivity data + # You will see the Headplane agent in your Tailnet as a node when + # it connects. + agent: + enabled: false + + # To connect to your Tailnet, you need to generate a pre-auth key + # This can be done via the web UI or through the `headscale` CLI. + pre_authkey: "" + + # Optionally change the name of the agent in the Tailnet. + # host_name: "headplane-agent" + + # Configure different caching settings. By default, the agent will store + # caches in the path below for a maximum of 1 minute. If you want data + # to update faster, reduce the TTL, but this will increase the frequency + # of requests to Headscale. + # cache_ttl: 60 + # cache_path: /var/lib/headplane/agent_cache.json + + # The work_dir represents where the agent will store its data to be able + # to automatically reauthenticate with your Tailnet. It needs to be + # writable by the user running the Headplane process. + # + # If using Docker, it is best to leave this as the default. + # work_dir: "/var/lib/headplane/agent" + + # Only one of these should be enabled at a time or you will get errors + # This does not include the agent integration (above), which can be enabled + # at the same time as any of these and is recommended for the best experience. + docker: + enabled: true + + # By default we check for the presence of a container label (see the docs) + # to determine the container to signal when changes are made to DNS settings. + container_label: "me.tale.headplane.target=headscale" + + # HOWEVER, you can fallback to a container name if you desire, but this is + # not recommended as its brittle and doesn't work with orchestrators that + # automatically assign container names. + # + # If `container_name` is set, it will override any label checks. + # container_name: "headscale-server" + + # The path to the Docker socket (do not change this if you are unsure) + # Docker socket paths must start with unix:// or tcp:// and at the moment + # https connections are not supported. + socket: "unix:///var/run/docker.sock" + + # Please refer to docs/integration/Kubernetes.md for more information + # on how to configure the Kubernetes integration. There are requirements in + # order to allow Headscale to be controlled by Headplane in a cluster. + kubernetes: + enabled: false + # Validates the manifest for the Pod to ensure all of the criteria + # are set correctly. Turn this off if you are having issues with + # shareProcessNamespace not being validated correctly. + validate_manifest: true + # This should be the name of the Pod running Headscale and Headplane. + # If this isn't static you should be using the Kubernetes Downward API + # to set this value (refer to docs/Integrated-Mode.md for more info). + pod_name: "headscale" + + # Proc is the "Native" integration that only works when Headscale and + # Headplane are running outside of a container. There is no configuration, + # but you need to ensure that the Headplane process can terminate the + # Headscale process. + # + # (If they are both running under systemd as sudo, this will work). + proc: + enabled: false + +# OIDC Configuration for simpler authentication +# (This is optional, but recommended for the best experience) +# oidc: +# The OIDC issuer URL +# issuer: "https://accounts.google.com" + +# If you are using OIDC, you need to generate an API key +# that can be used to authenticate other sessions when signing in. +# +# This can be done with `headscale apikeys create --expiration 999d` +# headscale_api_key: "" + +# If your OIDC provider does not support discovery (does not have the URL at +# `/.well-known/openid-configuration`), you need to manually set endpoints. +# This also works to override endpoints if you so desire or if your OIDC +# discovery is missing certain endpoints (ie GitHub). +# For some typical providers, see https://headplane.net/features/sso. +# authorization_endpoint: "" +# token_endpoint: "" +# userinfo_endpoint: "" + +# The authentication method to use when communicating with the token endpoint. +# This is fully optional and Headplane will attempt to auto-detect the best +# method and fall back to `client_secret_basic` if unsure. +# token_endpoint_auth_method: "client_secret_post" + +# The client ID for the OIDC client +# For the best experience please ensure this is *identical* to the client_id +# you are using for Headscale. because +# client_id: "your-client-id" + +# The client secret for the OIDC client +# You may also provide `client_secret_path` instead to read a value from disk. +# See https://headplane.net/configuration/#sensitive-values +# client_secret: "" + +# Whether to use PKCE when authenticating users. This is recommended as it +# adds an extra layer of security to the authentication process. Enabling this +# means your OIDC provider must support PKCE and it must be enabled on the +# client. +# use_pkce: true + +# If you want to disable traditional login via Headscale API keys +# disable_api_key_login: false + +# By default profile pictures are pulled from the OIDC provider when +# we go to fetch the userinfo endpoint. Optionally, this can be set to +# "oidc" or "gravatar" as of 0.6.1. +# profile_picture_source: "gravatar" + +# The scopes to request when authenticating users. The default is below. +# scope: "openid email profile" + +# Extra query parameters can be passed to the authorization endpoint +# by setting them here. This is useful for providers that require any kind +# of custom hinting. +# extra_params: +# prompt: "select_account" # Example: force account selection on Google diff --git a/headscale/config/config.yaml.example b/headscale/config/headscale.yaml.example similarity index 100% rename from headscale/config/config.yaml.example rename to headscale/config/headscale.yaml.example