IC, Caddyfile

This commit is contained in:
2026-07-15 04:29:40 +02:00
commit 344608f056
11 changed files with 245 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
.src/config.ts
/config.ts
# dependencies (bun install)
node_modules
# output
out
dist
*.tgz
# code coverage
coverage
*.lcov
# logs
logs
_.log
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# caches
.eslintcache
.cache
*.tsbuildinfo
# IntelliJ based IDEs
.idea
# Finder (MacOS) folder config
.DS_Store
+17
View File
@@ -0,0 +1,17 @@
# generated by typescript
memos.lyr41n.net {
reverse_proxy 92.222.229.62:8032
}
git.lyr41n.net {
reverse_proxy 92.222.229.62:8030
}
beszel.lyr41n.net {
reverse_proxy 92.222.229.62:9091
}
pi. {
reverse_proxy 10.0.0.2:8084
}
llama. {
reverse_proxy 10.0.0.2:8080
}
+15
View File
@@ -0,0 +1,15 @@
# pulumi
To install dependencies:
```bash
bun install
```
To run:
```bash
bun run index.ts
```
This project was created using `bun init` in bun v1.3.14. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
+26
View File
@@ -0,0 +1,26 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "pulumi",
"devDependencies": {
"@types/bun": "latest",
},
"peerDependencies": {
"typescript": "^5",
},
},
},
"packages": {
"@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
"@types/node": ["@types/node@26.1.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw=="],
"bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
}
}
+14
View File
@@ -0,0 +1,14 @@
{
"name": "pulumi",
"module": "src/index.ts",
"type": "module",
"scripts": {
"gen": "bun run src/index.ts"
},
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5"
}
}
+19
View File
@@ -0,0 +1,19 @@
import type { Service } from "./types";
/**
assembles the contents for caddyfile
**/
export function formatcaddyfile(proxies: Service[]): string {
let output = "# generated by typescript\n\n";
const proxyconfig = proxies.map(proxy => {
const fullDomain = `${proxy.subdomain}.${proxy.host.baseDomain}`;
const destination = `${proxy.host.ip}:${proxy.port}`
return `${fullDomain} {
reverse_proxy ${destination}
}`
}).join('\n');
return output + proxyconfig
}
+31
View File
@@ -0,0 +1,31 @@
import { services } from "./config";
import { formatcaddyfile } from "./formatter";
import type { Service } from "./types";
import { ConfigValidator } from "./validator";
import { ConfigWriter } from "./writer";
console.log("Hello via Bun!");
// const vpsservices: Service[] = services.filter(service => service.host.id == "vps-ovh");
// console.log(vpsservices);
/**
entry point / manager
**/
async function main() {
try {
console.log("starting caddy config");
ConfigValidator.validate(services);
const output = formatcaddyfile(services);
await ConfigWriter.writeLocal("Caddyfile", output);
console.log("completed succesfully");
} catch (error) {
console.error("error", error);
}
}
main();
+24
View File
@@ -0,0 +1,24 @@
export interface Host {
id: string;
ip: string;
sshPort: number;
user: string;
baseDomain: string;
}
export interface Service {
name: string;
subdomain: string;
port: number;
type: "binary" | "compose";
workingDir?: string;
dataDir?: string;
host: Host;
}
export interface StaticSite {
domains: string[];
root: string;
encode?: string;
custom404?: boolean;
}
+26
View File
@@ -0,0 +1,26 @@
import type { Service } from "./types";
/**
should validate config, for now just checks for port collisions
**/
export class ConfigValidator {
static validate(services: Service[]){
const hostports = new Map<string, Set<number>>();
for (const service of services) {
const hostip = service.host.ip;
if (!hostports.has(hostip)) {
hostports.set(hostip, new Set());
}
const ports = hostports.get(hostip)!;
if (ports.has(service.port)) {
throw new Error(`port collision: host ${hostip} already has a service on ${service.port}(${service.name})`)
}
ports.add(service.port);
}
console.log("validated collision");
}
}
+6
View File
@@ -0,0 +1,6 @@
export class ConfigWriter{
static async writeLocal(filename: string, content: string) {
await Bun.write(filename, content);
console.log(`written to ${filename}`);
}
}
+30
View File
@@ -0,0 +1,30 @@
{
"compilerOptions": {
// Environment setup & latest features
"lib": ["ESNext"],
"target": "ESNext",
"module": "Preserve",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
"types": ["bun"],
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
}