mirror of
https://github.com/fosrl/pangolin.git
synced 2026-10-29 15:09:07 +01:00
Clean up config for dns servers
This commit is contained in:
@@ -52,6 +52,8 @@ ENV ENVIRONMENT=prod
|
||||
ENV NODE_ENV=production
|
||||
|
||||
EXPOSE 53/udp
|
||||
# HTTP health check (GET /healthz)
|
||||
EXPOSE 8053/tcp
|
||||
|
||||
ARG VERSION="dev"
|
||||
ARG REVISION=""
|
||||
|
||||
@@ -4,6 +4,7 @@ import { configFilePath1, configFilePath2 } from "./consts";
|
||||
import { z } from "zod";
|
||||
import stoi from "./stoi";
|
||||
import { getEnvOrYaml, readEnvOrFile } from "./getEnvOrYaml";
|
||||
import { getRunMode } from "./runMode";
|
||||
// type-only: offlineThresholds imports config, which imports this file
|
||||
import type { OfflineThresholds } from "@server/lib/offlineThresholds";
|
||||
|
||||
@@ -325,6 +326,10 @@ export const configSchema = z
|
||||
base_endpoint: z
|
||||
.string()
|
||||
.optional()
|
||||
// The standalone DNS server never creates exit nodes
|
||||
.transform((url) =>
|
||||
url === undefined && getRunMode() === "dns" ? "" : url
|
||||
)
|
||||
.pipe(z.string())
|
||||
.transform((url) => url.toLowerCase()),
|
||||
subnet_group: z.string().optional().default("100.89.137.0/18"),
|
||||
@@ -516,6 +521,10 @@ export const configSchema = z
|
||||
)
|
||||
.refine(
|
||||
(data) => {
|
||||
// The standalone DNS server never uses the secret
|
||||
if (getRunMode() === "dns") {
|
||||
return true;
|
||||
}
|
||||
// If hybrid is not defined, server secret must be defined
|
||||
return (
|
||||
data.server?.secret !== undefined &&
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Which entry point is running. Standalone entry points set this before
|
||||
// anything loads the config, so the config schema can skip requirements
|
||||
// that only apply to the full Pangolin server.
|
||||
export type RunMode = "server" | "dns";
|
||||
|
||||
let runMode: RunMode = "server";
|
||||
|
||||
export function setRunMode(mode: RunMode) {
|
||||
runMode = mode;
|
||||
}
|
||||
|
||||
export function getRunMode(): RunMode {
|
||||
return runMode;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* This file is part of a proprietary work.
|
||||
*
|
||||
* Copyright (c) 2025-2026 Fossorial, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is licensed under the Fossorial Commercial License.
|
||||
* You may not use this file except in compliance with the License.
|
||||
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
|
||||
*
|
||||
* This file is not licensed under the AGPLv3.
|
||||
*/
|
||||
|
||||
// Imported first by dnsServer.ts: modules evaluate in import order, so this
|
||||
// runs before any later import loads (and validates) the config.
|
||||
import { setRunMode } from "@server/lib/runMode";
|
||||
|
||||
setRunMode("dns");
|
||||
@@ -14,13 +14,19 @@
|
||||
// Standalone entry point that runs only the authoritative DNS server against
|
||||
// an existing Pangolin database, without the API, dashboard or schedulers.
|
||||
// Migrations are left to the main Pangolin server that owns the database.
|
||||
// Must stay the first import - see dnsRunMode.ts
|
||||
import "./dnsRunMode";
|
||||
import "@server/extendZod";
|
||||
|
||||
import http from "http";
|
||||
import logger from "@server/logger";
|
||||
import { privateConfig } from "#private/lib/config";
|
||||
import { rateLimitService } from "#private/lib/rateLimit";
|
||||
import { startDnsServer, stopDnsServer } from "./dns";
|
||||
|
||||
// The DNS server only speaks UDP, which orchestrators can't probe directly
|
||||
const HEALTHCHECK_PORT = 8053;
|
||||
|
||||
async function start() {
|
||||
if (!privateConfig.getRawPrivateConfig().dns?.enabled) {
|
||||
throw new Error(
|
||||
@@ -30,11 +36,25 @@ async function start() {
|
||||
|
||||
await startDnsServer({ requireLicense: false });
|
||||
|
||||
const healthcheckServer = http.createServer((req, res) => {
|
||||
if (req.url === "/healthz") {
|
||||
res.writeHead(200, { "Content-Type": "text/plain" });
|
||||
res.end("OK");
|
||||
} else {
|
||||
res.writeHead(404);
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
healthcheckServer.listen(HEALTHCHECK_PORT, () => {
|
||||
logger.info(`Healthcheck server listening on port ${HEALTHCHECK_PORT}`);
|
||||
});
|
||||
|
||||
let stopping = false;
|
||||
const shutdown = async () => {
|
||||
if (stopping) return;
|
||||
stopping = true;
|
||||
try {
|
||||
healthcheckServer.close();
|
||||
await stopDnsServer();
|
||||
await rateLimitService.cleanup();
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user