mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-15 18:30:39 +09:00
Introduce bind presets for deployment setup
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
e1bf9d66a7
commit
2a84e53c1b
35 changed files with 915 additions and 176 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { readConfigFile } from "./config-file.js";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { existsSync, realpathSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { config as loadDotenv } from "dotenv";
|
||||
|
|
@ -6,15 +7,20 @@ import { resolvePaperclipEnvPath } from "./paths.js";
|
|||
import { maybeRepairLegacyWorktreeConfigAndEnvFiles } from "./worktree-config.js";
|
||||
import {
|
||||
AUTH_BASE_URL_MODES,
|
||||
BIND_MODES,
|
||||
DEPLOYMENT_EXPOSURES,
|
||||
DEPLOYMENT_MODES,
|
||||
SECRET_PROVIDERS,
|
||||
STORAGE_PROVIDERS,
|
||||
type BindMode,
|
||||
type AuthBaseUrlMode,
|
||||
type DeploymentExposure,
|
||||
type DeploymentMode,
|
||||
type SecretProvider,
|
||||
type StorageProvider,
|
||||
inferBindModeFromHost,
|
||||
resolveRuntimeBind,
|
||||
validateConfiguredBindMode,
|
||||
} from "@paperclipai/shared";
|
||||
import {
|
||||
resolveDefaultBackupDir,
|
||||
|
|
@ -44,6 +50,8 @@ type DatabaseMode = "embedded-postgres" | "postgres";
|
|||
export interface Config {
|
||||
deploymentMode: DeploymentMode;
|
||||
deploymentExposure: DeploymentExposure;
|
||||
bind: BindMode;
|
||||
customBindHost: string | undefined;
|
||||
host: string;
|
||||
port: number;
|
||||
allowedHostnames: string[];
|
||||
|
|
@ -78,6 +86,24 @@ export interface Config {
|
|||
telemetryEnabled: boolean;
|
||||
}
|
||||
|
||||
function detectTailnetBindHost(): string | undefined {
|
||||
const explicit = process.env.PAPERCLIP_TAILNET_BIND_HOST?.trim();
|
||||
if (explicit) return explicit;
|
||||
|
||||
try {
|
||||
const stdout = execFileSync("tailscale", ["ip", "-4"], {
|
||||
encoding: "utf8",
|
||||
stdio: ["ignore", "pipe", "ignore"],
|
||||
});
|
||||
return stdout
|
||||
.split(/\r?\n/)
|
||||
.map((line) => line.trim())
|
||||
.find(Boolean);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function loadConfig(): Config {
|
||||
const fileConfig = readConfigFile();
|
||||
const fileDatabaseMode =
|
||||
|
|
@ -148,6 +174,18 @@ export function loadConfig(): Config {
|
|||
deploymentMode === "local_trusted"
|
||||
? "private"
|
||||
: (deploymentExposureFromEnv ?? fileConfig?.server.exposure ?? "private");
|
||||
const bindFromEnvRaw = process.env.PAPERCLIP_BIND;
|
||||
const bindFromEnv =
|
||||
bindFromEnvRaw && BIND_MODES.includes(bindFromEnvRaw as BindMode)
|
||||
? (bindFromEnvRaw as BindMode)
|
||||
: null;
|
||||
const configuredHost = process.env.HOST ?? fileConfig?.server.host ?? "127.0.0.1";
|
||||
const tailnetBindHost = detectTailnetBindHost();
|
||||
const bind =
|
||||
bindFromEnv ??
|
||||
fileConfig?.server.bind ??
|
||||
inferBindModeFromHost(configuredHost, { tailnetBindHost });
|
||||
const customBindHost = process.env.PAPERCLIP_BIND_HOST ?? fileConfig?.server.customBindHost;
|
||||
const authBaseUrlModeFromEnvRaw = process.env.PAPERCLIP_AUTH_BASE_URL_MODE;
|
||||
const authBaseUrlModeFromEnv =
|
||||
authBaseUrlModeFromEnvRaw &&
|
||||
|
|
@ -223,11 +261,32 @@ export function loadConfig(): Config {
|
|||
fileDatabaseBackup?.dir ??
|
||||
resolveDefaultBackupDir(),
|
||||
);
|
||||
const bindValidationErrors = validateConfiguredBindMode({
|
||||
deploymentMode,
|
||||
deploymentExposure,
|
||||
bind,
|
||||
host: configuredHost,
|
||||
customBindHost,
|
||||
});
|
||||
if (bindValidationErrors.length > 0) {
|
||||
throw new Error(bindValidationErrors[0]);
|
||||
}
|
||||
const resolvedBind = resolveRuntimeBind({
|
||||
bind,
|
||||
host: configuredHost,
|
||||
customBindHost,
|
||||
tailnetBindHost,
|
||||
});
|
||||
if (resolvedBind.errors.length > 0) {
|
||||
throw new Error(resolvedBind.errors[0]);
|
||||
}
|
||||
|
||||
return {
|
||||
deploymentMode,
|
||||
deploymentExposure,
|
||||
host: process.env.HOST ?? fileConfig?.server.host ?? "127.0.0.1",
|
||||
bind: resolvedBind.bind,
|
||||
customBindHost: resolvedBind.customBindHost,
|
||||
host: resolvedBind.host,
|
||||
port: Number(process.env.PORT) || fileConfig?.server.port || 3100,
|
||||
allowedHostnames,
|
||||
authBaseUrlMode,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue