2025-06-08 11:25:38 +02:00
|
|
|
{
|
|
|
|
lib,
|
|
|
|
fetchFromGitHub,
|
|
|
|
esbuild,
|
|
|
|
buildNpmPackage,
|
2025-07-19 21:32:36 +10:00
|
|
|
makeWrapper,
|
|
|
|
formats,
|
2025-06-08 11:25:38 +02:00
|
|
|
inter,
|
2025-07-19 21:32:36 +10:00
|
|
|
databaseType ? "sqlite",
|
|
|
|
environmentVariables ? { },
|
2025-06-08 11:25:38 +02:00
|
|
|
}:
|
|
|
|
|
2025-07-19 21:32:36 +10:00
|
|
|
assert lib.assertOneOf "databaseType" databaseType [
|
|
|
|
"sqlite"
|
|
|
|
"pg"
|
|
|
|
];
|
|
|
|
|
|
|
|
let
|
|
|
|
db =
|
|
|
|
isLong:
|
|
|
|
if (databaseType == "sqlite") then
|
|
|
|
"sqlite"
|
|
|
|
else if isLong then
|
|
|
|
"postgresql"
|
|
|
|
else
|
|
|
|
"pg";
|
|
|
|
in
|
|
|
|
|
|
|
|
buildNpmPackage (finalAttrs: {
|
2025-06-08 11:25:38 +02:00
|
|
|
pname = "pangolin";
|
2025-07-19 21:32:36 +10:00
|
|
|
version = "1.8.0";
|
2025-06-08 11:25:38 +02:00
|
|
|
|
|
|
|
src = fetchFromGitHub {
|
|
|
|
owner = "fosrl";
|
|
|
|
repo = "pangolin";
|
2025-07-19 21:32:36 +10:00
|
|
|
tag = finalAttrs.version;
|
|
|
|
hash = "sha256-Cy5COyZAH0NPQDMpKUmweYWkyupDC2sNf2CP+EJ5GiE=";
|
2025-06-08 11:25:38 +02:00
|
|
|
};
|
|
|
|
|
2025-07-19 21:32:36 +10:00
|
|
|
npmDepsHash = "sha256-OGqYmOO6pizcOrdaoSGgjDQgqpjU0SIw3ceh57eyjr4=";
|
|
|
|
|
|
|
|
nativeBuildInputs = [
|
|
|
|
esbuild
|
|
|
|
makeWrapper
|
|
|
|
];
|
|
|
|
|
|
|
|
prePatch = ''
|
|
|
|
cat > server/db/index.ts << EOF
|
|
|
|
export * from "./${db false}";
|
|
|
|
EOF
|
|
|
|
'';
|
|
|
|
|
|
|
|
# Replace the googleapis.com Inter font with a local copy from Nixpkgs.
|
|
|
|
# Based on pkgs.nextjs-ollama-llm-ui.
|
2025-06-08 11:25:38 +02:00
|
|
|
postPatch = ''
|
|
|
|
substituteInPlace src/app/layout.tsx --replace-fail \
|
2025-07-19 21:32:36 +10:00
|
|
|
"{ Inter } from \"next/font/google\"" \
|
2025-06-08 11:25:38 +02:00
|
|
|
"localFont from \"next/font/local\""
|
|
|
|
|
|
|
|
substituteInPlace src/app/layout.tsx --replace-fail \
|
|
|
|
"Inter({ subsets: [\"latin\"] })" \
|
|
|
|
"localFont({ src: './Inter.ttf' })"
|
|
|
|
|
|
|
|
cp "${inter}/share/fonts/truetype/InterVariable.ttf" src/app/Inter.ttf
|
|
|
|
'';
|
|
|
|
|
2025-07-19 21:32:36 +10:00
|
|
|
preBuild = "npx drizzle-kit generate --dialect ${db true} --schema ./server/db/${db false}/schema.ts --name migration --out init";
|
|
|
|
|
|
|
|
npmBuildScript = "build:${db false}";
|
|
|
|
|
|
|
|
postBuild = "npm run build:cli";
|
|
|
|
|
|
|
|
preInstall = "mkdir -p $out/{bin,share/pangolin}";
|
2025-06-08 11:25:38 +02:00
|
|
|
|
|
|
|
installPhase = ''
|
|
|
|
runHook preInstall
|
|
|
|
|
2025-07-19 21:32:36 +10:00
|
|
|
cp -r node_modules $out/share/pangolin
|
|
|
|
|
|
|
|
cp -r .next/standalone/.next $out/share/pangolin
|
|
|
|
cp .next/standalone/package.json $out/share/pangolin
|
|
|
|
|
|
|
|
cp -r .next/static $out/share/pangolin/.next/static
|
|
|
|
cp -r public $out/share/pangolin/public
|
2025-06-08 11:25:38 +02:00
|
|
|
|
2025-07-19 21:32:36 +10:00
|
|
|
cp -r dist $out/share/pangolin/dist
|
|
|
|
cp -r init $out/share/pangolin/dist/init
|
|
|
|
|
|
|
|
cp server/db/names.json $out/share/pangolin/dist/names.json
|
2025-06-08 11:25:38 +02:00
|
|
|
|
|
|
|
runHook postInstall
|
|
|
|
'';
|
|
|
|
|
2025-07-19 21:32:36 +10:00
|
|
|
preFixup =
|
|
|
|
let
|
|
|
|
defaultConfig = (formats.yaml { }).generate "pangolin-default-config" {
|
|
|
|
app.dashboard_url = "https://pangolin.example.test";
|
|
|
|
domains.domain1.base_domain = "example.test";
|
|
|
|
gerbil.base_endpoint = "pangolin.example.test";
|
|
|
|
server.secret = "A secret string used for encrypting sensitive data. Must be at least 8 characters long.";
|
|
|
|
};
|
|
|
|
variablesMapped =
|
|
|
|
isServer:
|
|
|
|
(lib.concatMapAttrsStringSep " " (name: value: "--set ${name} ${value}") (
|
|
|
|
{
|
|
|
|
NODE_OPTIONS = "enable-source-maps";
|
|
|
|
NODE_ENV = "development";
|
|
|
|
ENVIRONMENT = "prod";
|
|
|
|
}
|
|
|
|
// environmentVariables
|
|
|
|
))
|
|
|
|
# If we're running Pangolin, test if we have a .nix_skip_setup file in the public
|
|
|
|
# and .next directories. If we don't, clean them up and re-create them.
|
|
|
|
+ lib.optionalString isServer " --run '${
|
|
|
|
(lib.concatMapStringsSep " && "
|
|
|
|
(
|
|
|
|
dir:
|
|
|
|
"test -f ${dir}/.nix_skip_setup || { rm -${lib.optionalString (dir == ".next") "r"}f ${dir} && ${
|
|
|
|
if (dir == ".next") then "cp -rd" else "ln -s"
|
|
|
|
} ${placeholder "out"}/share/pangolin/${dir} .; }"
|
|
|
|
)
|
|
|
|
[
|
|
|
|
".next"
|
|
|
|
"public"
|
|
|
|
"node_modules"
|
|
|
|
]
|
|
|
|
)
|
|
|
|
# Also deploy a small config (if none exists) and run the
|
|
|
|
# database migrations before running the server.
|
|
|
|
} && test -f config/config.yml || { install -Dm600 ${defaultConfig} config/config.yml && { test -z $EDITOR && { echo \"Please edit $(pwd)/config/config.yml\" and run the server again. && exit 255; } || $EDITOR config/config.yml; }; } && command ${placeholder "out"}/bin/migrate-pangolin-database'";
|
|
|
|
in
|
|
|
|
lib.concatMapStrings
|
|
|
|
(
|
|
|
|
attr:
|
|
|
|
"makeWrapper $out/share/pangolin/dist/${attr.mjs}.mjs $out/bin/${attr.command} ${
|
|
|
|
variablesMapped (attr.mjs == "server")
|
|
|
|
}\n"
|
|
|
|
)
|
|
|
|
[
|
|
|
|
{
|
|
|
|
mjs = "cli";
|
|
|
|
command = "pangctl";
|
|
|
|
}
|
|
|
|
{
|
|
|
|
mjs = "migrations";
|
|
|
|
command = "migrate-pangolin-database";
|
|
|
|
}
|
|
|
|
{
|
|
|
|
mjs = "server";
|
|
|
|
command = "pangolin";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
|
|
|
passthru = { inherit databaseType; };
|
|
|
|
|
2025-06-08 11:25:38 +02:00
|
|
|
meta = {
|
|
|
|
description = "Tunneled reverse proxy server with identity and access control";
|
|
|
|
homepage = "https://github.com/fosrl/pangolin";
|
2025-07-19 21:32:36 +10:00
|
|
|
changelog = "https://github.com/fosrl/pangolin/releases/tag/${finalAttrs.version}";
|
2025-06-08 11:25:38 +02:00
|
|
|
license = lib.licenses.agpl3Only;
|
2025-07-19 21:32:36 +10:00
|
|
|
maintainers = with lib.maintainers; [
|
|
|
|
jackr
|
|
|
|
sigmasquadron
|
|
|
|
];
|
2025-06-08 11:25:38 +02:00
|
|
|
platforms = lib.platforms.linux;
|
2025-07-19 21:32:36 +10:00
|
|
|
mainProgram = "pangolin";
|
2025-06-08 11:25:38 +02:00
|
|
|
};
|
2025-07-19 21:32:36 +10:00
|
|
|
})
|