mirror of
https://github.com/tale/headplane.git
synced 2026-07-27 08:08:56 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6c83e96341 | |||
| 03e6a26b3a | |||
| 5b716ab5ce |
@@ -1,3 +1,6 @@
|
||||
### 0.5.2 (February 28, 2025)
|
||||
- Hotfixed an issue where the server bundle got reloaded on each request
|
||||
|
||||
### 0.5.1 (February 28, 2025)
|
||||
- Fixed an issue that caused the entire server to crash on start
|
||||
- Fixed the published semver tags from Docker
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# Headplane Agent
|
||||
|
||||
The Headplane agent is a lightweight service that runs alongside the Headscale server.
|
||||
It's used to interface with devices on your network locally, unlocking the following:
|
||||
|
||||
- **Node Information/Status**: View Tailscale versions, OS versions, and connection details.
|
||||
- **SSH via Web (Soon)**: Connect to devices via SSH directly from the Headplane UI.
|
||||
|
||||
It's built on top of [tsnet](https://tailscale.com/kb/1244/tsnet), the official
|
||||
set of libraries published by Tailscale for creating local services that can
|
||||
join the tailnet.
|
||||
While it isn't required to run the agent, it's highly recommended to get the
|
||||
closest experience to the SaaS version of Tailscale. This is paired with the
|
||||
integrations provided by Headplane to manage DNS and Headscale settings.
|
||||
|
||||
### Installation
|
||||
The agent can either be ran as a standalone binary or as a Docker container.
|
||||
Agent binaries are available on the [releases](https://github.com/tale/headplane/releases) page.
|
||||
The Docker image is available through the `ghcr.io/tale/headplane-agent` tag.
|
||||
|
||||
The agent requires the following environment variables to be set:
|
||||
- **`HP_AGENT_HOSTNAME`**: A hostname you want to use for the agent.
|
||||
- **`HP_AGENT_TS_SERVER`**: The URL to your Headscale instance.
|
||||
- **`HP_AGENT_TS_AUTHKEY`**: An authorization key to authenticate with Headscale (see below).
|
||||
- **`HP_AGENT_HP_SERVER`**: The URL to your Headplane instance.
|
||||
- **`HP_AGENT_HP_AUTHKEY`**: The generated auth key to authenticate with Headplane.
|
||||
|
||||
If you already have Headplane setup, you can generate all of these values within
|
||||
the Headplane UI. Navigate to the `Settings` page and click `Agent` to get started.
|
||||
|
||||
HP_AGENT_HOSTNAME=headplane-agent
|
||||
HP_AGENT_TS_SERVER=http://localhost:8080
|
||||
#HP_AGENT_AUTH_KEY=3e0cd749021e5984267cde4b0a5a2ac32c1859e56f7911aa
|
||||
HP_AGENT_TS_AUTHKEY=a4dab065c735cb4eae4f12804cf7e111206f9c7c9247c629
|
||||
HP_AGENT_HP_SERVER=http://localhost:3000/admin
|
||||
@@ -34,7 +34,7 @@ Here is what a sample Docker Compose deployment would look like:
|
||||
services:
|
||||
headplane:
|
||||
# I recommend you pin the version to a specific release
|
||||
image: ghcr.io/tale/headplane:0.5.0
|
||||
image: ghcr.io/tale/headplane:0.5.1
|
||||
container_name: headplane
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
@@ -148,7 +148,7 @@ spec:
|
||||
serviceAccountName: default
|
||||
containers:
|
||||
- name: headplane
|
||||
image: ghcr.io/tale/headplane:0.5.0
|
||||
image: ghcr.io/tale/headplane:0.5.1
|
||||
env:
|
||||
# Set these if the pod name for Headscale is not static
|
||||
# We will use the downward API to get the pod name instead
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ Here is what a sample Docker Compose deployment would look like:
|
||||
services:
|
||||
headplane:
|
||||
# I recommend you pin the version to a specific release
|
||||
image: ghcr.io/tale/headplane:0.5.0
|
||||
image: ghcr.io/tale/headplane:0.5.1
|
||||
container_name: headplane
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
|
||||
+19
-5
@@ -6,6 +6,8 @@ import {
|
||||
writeReadableStreamToWritable,
|
||||
} from '@react-router/node';
|
||||
import mime from 'mime/lite';
|
||||
import type { RequestHandler } from 'react-router';
|
||||
import type { ViteDevServer } from 'vite';
|
||||
import appContext from '~server/context/app';
|
||||
import { loadDevtools, stacksafeTry } from '~server/dev/hot-server';
|
||||
import prodBuild from '~server/prod-handler';
|
||||
@@ -16,18 +18,30 @@ declare global {
|
||||
const __hp_prefix: string;
|
||||
}
|
||||
|
||||
export const listener: RequestListener = async (req, res) => {
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Who cares man
|
||||
let devtools: { server: ViteDevServer; handler: any } | undefined = undefined;
|
||||
let prodHandler: RequestHandler | undefined = undefined;
|
||||
let loaded = false;
|
||||
|
||||
async function loadGlobals() {
|
||||
await hp_loadConfig();
|
||||
const devtools = import.meta.env.DEV ? await loadDevtools() : undefined;
|
||||
const prodHandler = import.meta.env.PROD ? await prodBuild() : undefined;
|
||||
const baseDir = resolve(join('./build', 'client'));
|
||||
devtools = import.meta.env.DEV ? await loadDevtools() : undefined;
|
||||
prodHandler = import.meta.env.PROD ? await prodBuild() : undefined;
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
const baseDir = resolve(join('./build', 'client'));
|
||||
export const listener: RequestListener = async (req, res) => {
|
||||
if (!loaded) {
|
||||
await loadGlobals();
|
||||
}
|
||||
|
||||
const url = new URL(`http://${req.headers.host}${req.url}`);
|
||||
|
||||
// build:strip
|
||||
if (devtools) {
|
||||
await new Promise((resolve) => {
|
||||
devtools.server.middlewares(req, res, resolve);
|
||||
devtools?.server.middlewares(req, res, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user