diff --git a/.env.example b/.env.example index e5f5876..b890239 100644 --- a/.env.example +++ b/.env.example @@ -1,72 +1,58 @@ # shellcheck disable= -PGID=1000 -TZ="Europe/Amsterdam" -PUID=1000 +ANILIST_TOKEN_2= +ANILIST_TOKEN_3= +ANILIST_TOKEN_4= +ATPROTO_DID= AUTO_LANGUAGES_DISCORD_WEBHOOK= -CADDY_PASSWORD= -CADDY_USERNAME= +CADDY_USERNAME_1= +CADDY_PASSWORD_1= +CADDY_USERNAME_2= +CADDY_PASSWORD_2= +CADDY_USERNAME_3= +CADDY_PASSWORD_3= CLOUDFLARE_API_KEY= -CLOUDFLARE_EMAIL= CLOUDFLARE_ZONE_ID= CONNECTION_HOST= CONNECTION_PASSWORD= CONNECTION_PORT= CONNECTION_USER= CURSEFORGE_API_KEY= -DISCORD_AUTO_LANGUAGES_WEBHOOK= EMAIL= -GHCR_TOKEN= +CLOUDFLARE_EMAIL= +FILEBROWSER_ADMIN_PASSWORD= IPINFO_APIKEY= -JDOWNLOADER_PASSWORD= -KOPIA_PASSWORD= +KANEELNAS_HOST= LIBRESPEED_PASSWORD= +PDS_ADMIN_PASSWORD= +PDS_JWT_SECRET= +PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX= +PDS_SMTP_AUTH_URI= +PEGASUS_ADMIN_PASSWORD= +PEGASUS_DPOP_NONCE_SECRET= +PEGASUS_JWK_MULTIBASE= +PEGASUS_ROTATION_KEY_MULTIBASE= +PGID= PLEX_TOKEN= +PLEX_USER_2= +PLEX_USER_3= +PLEX_USER_4= POSTGRES_PASSWORD= -PROTON_OPENVPN_PASS= -PROTON_OPENVPN_USER= +PUID= QBITTORRENT_PASSWORD= RCON_PASSWORD= -SPACEDRIVE_PASSWORD= +RELAY_ADMIN_PASSWORD= +SMTP_PASSWORD= TAILSCALE_AUTH_KEY= -USERNAME= -VALKEY_PASSWORD= -VNC_PASSWORD= -KANEELNAS_HOST= -ANILIST_TOKEN_1= -PLEX_USER_1= -ANILIST_TOKEN_2= -PLEX_USER_2= -ANILIST_TOKEN_3= -PLEX_USER_3= -ANILIST_TOKEN_4= -PLEX_USER_4= +TERRARIA_PASSWORD= +TRANQUIL_DISCORD_BOT_TOKEN= +TRANQUIL_DPOP_SECRET= +TRANQUIL_JWT_SECRET= +TRANQUIL_MASTER_KEY= +TZ= USENET_HOSTNAME= -USENET_USERNAME= USENET_PASSWORD= USENET_PORT= -PEGASUS_ADMIN_PASSWORD= -PEGASUS_ROTATION_KEY_MULTIBASE= -PEGASUS_JWK_MULTIBASE= -PEGASUS_DPOP_NONCE_SECRET= -PDS_SMTP_AUTH_URI= -PDS_ADMIN_PASSWORD= -PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX= -PDS_JWT_SECRET= -SEAFILE_MARIADB_ROOT_PASSWORD= -SEAFILE_MARIADB_USER_PASSWORD= -SEAFILE_ADMIN_EMAIL= -SEAFILE_ADMIN_PASSWORD= -SEAFILE_REDIS_PASSWORD= -SEAFILE_JWT_PRIVATE_KEY= -FILEBROWSER_ADMIN_PASSWORD= -EXPLORER_SECRET= -AUTOKUMA_USERNAME= -AUTOKUMA_PASSWORD= -ATPROTO_DID= -TRANQUIL_JWT_SECRET= -TRANQUIL_DPOP_SECRET= -TRANQUIL_MASTER_KEY= -TRANQUIL_PLC_ROTATION_KEY= -TRANQUIL_DISCORD_BOT_TOKEN= -RELAY_ADMIN_PASSWORD= -TERRARIA_PASSWORD= +USENET_USERNAME= +USERNAME= +VALKEY_PASSWORD= +VNC_PASSWORD= diff --git a/lib/service/service.ts b/lib/service/index.ts similarity index 96% rename from lib/service/service.ts rename to lib/service/index.ts index c9bf7b7..89871e3 100644 --- a/lib/service/service.ts +++ b/lib/service/index.ts @@ -88,7 +88,7 @@ class ContainerService extends ComponentResource { new RemoteImage( `${name}`, { - name: output(args.image ?? `lscr.io/linuxserver/${name}`).apply(async (image) => { + name: output(args.image).apply(async (image = `lscr.io/linuxserver/${name}`) => { if (!image.match(/\..+\//)) { image = `mirror.gcr.io/${image}`; } @@ -119,6 +119,7 @@ class ContainerService extends ComponentResource { return mounts; }); + // @ts-expect-error this.volumes = args.volumes && output(args.volumes); this.localUrl = all([args.networkMode, args.servicePort]).apply(([networkMode, servicePort]) => @@ -131,6 +132,7 @@ class ContainerService extends ComponentResource { ([hostRule, subdomain]) => hostRule ?? `${subdomain ?? name}.bas.sh`, ); + let idx = 0; const createLabels = all([ args.middlewares ?? [], args.hostRulePriority, @@ -138,7 +140,8 @@ class ContainerService extends ComponentResource { this.localUrl, ]).apply(([middlewares, hostRulePriority, monitor, localUrl]) => { return (host: string, port: string | number) => { - const id = host.replaceAll(/[^\w]+/g, "-"); + const id = idx === 0 ? name : `${name}-${idx}`; + idx++; const labels = { "traefik.enable": "true", @@ -239,8 +242,8 @@ class ContainerService extends ComponentResource { // healthcheck: {tests} networksAdvanced: args.networkMode ? [] - : all([args.networksAdvanced ?? [], defaultNetwork.name]).apply( - ([networksAdvanced, defaultNetworkName]) => [ + : all([args.networksAdvanced, defaultNetwork.name]).apply( + ([networksAdvanced = [], defaultNetworkName]) => [ ...networksAdvanced, ...(networksAdvanced.some((network) => network.name === defaultNetworkName) ? [] @@ -249,7 +252,7 @@ class ContainerService extends ComponentResource { ), hosts: args.networkMode ? [] - : output(args.hosts ?? []).apply((hosts) => [ + : output(args.hosts).apply((hosts = []) => [ { host: "host.docker.internal", ip: "host-gateway" }, ...hosts, ]), diff --git a/lib/service/mounts.ts b/lib/service/mounts.ts index 03f1a74..c562469 100644 --- a/lib/service/mounts.ts +++ b/lib/service/mounts.ts @@ -6,10 +6,11 @@ type WithOptional = Pick, K> & Omit; type WithRequired = T & { [P in K]-?: T[P] }; type CustomMountOpts = { + source?: Input; kind?: Input<"directory" | "file">; }; -export type MountOpts = WithRequired & CustomMountOpts; +export type MountOpts = Omit & WithRequired; export function _mount({ source, @@ -88,11 +89,6 @@ export const dockerSocket = _mount({ readOnly: true, }); -export const dockerSocketRw = _mount({ - source: "/var/run/docker.sock", - kind: "file", -}); - export const resolvConf = _mount({ source: "/run/systemd/resolve/stub-resolv.conf", target: "/etc/resolv.conf", diff --git a/lib/service/ports.ts b/lib/service/ports.ts index bf86635..8491309 100644 --- a/lib/service/ports.ts +++ b/lib/service/ports.ts @@ -1,7 +1,7 @@ import type { ContainerPort } from "@pulumi/docker/types/input"; import { output, type UnwrappedObject } from "@pulumi/pulumi"; -import type { ContainerServiceArgs } from "./service"; +import type { ContainerServiceArgs } from "."; function parsePort( input: string | number | UnwrappedObject, diff --git a/lib/util.ts b/lib/util.ts index 3759570..ee56ee9 100644 --- a/lib/util.ts +++ b/lib/util.ts @@ -1,11 +1,17 @@ import assert from "assert"; +import type { Input, Output } from "@pulumi/pulumi"; import { $ } from "bun"; import ky from "ky"; import z from "zod"; export async function getLatestTangledCommit(url: string) { - const html = await ky(url, { retry: 5 }).text(); + const html = await ky(url, { + retry: { + limit: 10, + retryOnTimeout: true, + }, + }).text(); const commit = html.match(/\/commit\/(\w+)/)?.[1]; return commit; } @@ -33,3 +39,10 @@ export function ensure(arg: T): NonNullable { assert(arg); return arg; } + +// export function prefix>(prefix: string, obj: T): T { +// return Object.fromEntries(Object.entries(obj).map(([key, value]) => [`${prefix}_${key}`, value])); +// } + +export const toHostRule = (domains: string[]) => + domains.map((domain) => `Host(\`${domain}\`)`).join(" || "); diff --git a/services/haring/atproto/did-web.ts b/services/haring/atproto/did-web.ts index 11afaf6..2d86a75 100644 --- a/services/haring/atproto/did-web.ts +++ b/services/haring/atproto/did-web.ts @@ -1,13 +1,36 @@ import { DnsRecord } from "@pulumi/cloudflare"; import { getEnv } from "~lib/env"; -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; -import didweb from "./did.json"; +const DID_WEB = { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/multikey/v1", + "https://w3id.org/security/suites/secp256k1-2019/v1", + ], + id: "did:web:bas.sh", + alsoKnownAs: ["at://also.bas.sh"], + verificationMethod: [ + { + id: "did:web:bas.sh#atproto", + type: "Multikey", + controller: "did:web:bas.sh", + publicKeyMultibase: "zQ3sheGf8QLgkN6kv7AdwefVrF5j3rB9bNyDSeA2PRcAFvNZJ", + }, + ], + service: [ + { + id: "#atproto_pds", + type: "AtprotoPersonalDataServer", + serviceEndpoint: "https://tranquil.bas.sh", + }, + ], +}; const CADDYFILE = ` :80 { handle /.well-known/did.json { - respond ${JSON.stringify(didweb)} 200 + respond ${JSON.stringify(DID_WEB)} 200 } } `; @@ -21,19 +44,19 @@ export const didwebCaddyService = new ContainerService("caddy-didweb", { middlewares: ["cors"], }); -export const didwebDnsRecord = new DnsRecord(`didweb`, { +export const didwebDnsRecord = new DnsRecord("didweb", { zoneId: getEnv("CLOUDFLARE_ZONE_ID"), - name: `also.bas.sh`, + name: "also.bas.sh", ttl: 1, type: "CNAME", content: "haring.bas.sh", proxied: false, }); -export const didwebDidDnsRecord = new DnsRecord(`didweb-did`, { +export const didwebDidDnsRecord = new DnsRecord("didweb-did", { zoneId: getEnv("CLOUDFLARE_ZONE_ID"), - name: `_atproto.also.bas.sh`, + name: "_atproto.also.bas.sh", ttl: 1, type: "TXT", - content: `"did=did:web:bas.sh"`, + content: '"did=did:web:bas.sh"', }); diff --git a/services/haring/atproto/did.json b/services/haring/atproto/did.json deleted file mode 100644 index 0eb743c..0000000 --- a/services/haring/atproto/did.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "@context": [ - "https://www.w3.org/ns/did/v1", - "https://w3id.org/security/multikey/v1", - "https://w3id.org/security/suites/secp256k1-2019/v1" - ], - "id": "did:web:bas.sh", - "alsoKnownAs": ["at://also.bas.sh"], - "verificationMethod": [ - { - "id": "did:web:bas.sh#atproto", - "type": "Multikey", - "controller": "did:web:bas.sh", - "publicKeyMultibase": "zQ3sheGf8QLgkN6kv7AdwefVrF5j3rB9bNyDSeA2PRcAFvNZJ" - } - ], - "service": [ - { - "id": "#atproto_pds", - "type": "AtprotoPersonalDataServer", - "serviceEndpoint": "https://tranquil.bas.sh" - } - ] -} diff --git a/services/haring/atproto/pds/motd.txt b/services/haring/atproto/pds/motd.txt deleted file mode 100644 index 923fbb4..0000000 --- a/services/haring/atproto/pds/motd.txt +++ /dev/null @@ -1,23 +0,0 @@ - ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡀⠀⠀⠀ - ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠙⠻⢶⣄⡀⠀⠀⠀⢀⣤⠶⠛⠛⡇⠀⠀⠀ - ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣇⠀⠀⣙⣿⣦⣤⣴⣿⣁⠀⠀⣸⠇⠀⠀⠀ - ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣡⣾⣿⣿⣿⣿⣿⣿⣿⣷⣌⠋⠀⠀⠀⠀ - ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣷⣄⡈⢻⣿⡟⢁⣠⣾⣿⣦⠀⠀⠀⠀ - ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣿⠘⣿⠃⣿⣿⣿⣿⡏⠀⠀⠀⠀ - ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠈⠛⣰⠿⣆⠛⠁⠀⡀⠀⠀⠀⠀⠀ - ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣦⠀⠘⠛⠋⠀⣴⣿⠁⠀⠀⠀⠀⠀ - ⠀⠀⠀⠀⠀⠀⣀⣤⣶⣾⣿⣿⣿⣿⡇⠀⠀⠀⢸⣿⣏⠀⠀⠀⠀⠀⠀ - ⠀⠀⠀⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠀⠀⠀⠾⢿⣿⠀⠀⠀⠀⠀⠀ - ⠀⣠⣿⣿⣿⣿⣿⣿⡿⠟⠋⣁⣠⣤⣤⡶⠶⠶⣤⣄⠈⠀⠀⠀⠀⠀⠀ - ⢰⣿⣿⣮⣉⣉⣉⣤⣴⣶⣿⣿⣋⡥⠄⠀⠀⠀⠀⠉⢻⣄⠀⠀⠀⠀⠀ - ⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⣋⣁⣤⣀⣀⣤⣤⣤⣤⣄⣿⡄⠀⠀⠀⠀ - ⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠋⠉⠁⠀⠀⠀⠀⠈⠛⠃⠀⠀⠀⠀ - ⠀⠀⠀⠀⠉⠉⠉⠉⠉ - -This is an AT Protocol Personal Data Server (aka, an atproto PDS) - -Most API routes are under /xrpc/ - - Code: https://github.com/bluesky-social/atproto - Self-Host: https://github.com/bluesky-social/pds - Protocol: https://atproto.com diff --git a/services/haring/atproto/pds/pds.ts b/services/haring/atproto/pds/pds.ts index a8301bb..631f851 100644 --- a/services/haring/atproto/pds/pds.ts +++ b/services/haring/atproto/pds/pds.ts @@ -5,13 +5,18 @@ import { remote } from "@pulumi/command"; import { asset, output } from "@pulumi/pulumi"; import { getEnv } from "~lib/env"; import { fetchRelays } from "~lib/relay-hosts"; +import { ContainerService, defaultConnection } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService, defaultConnection } from "~lib/service/service"; +import { toHostRule } from "~lib/util"; + +const SUBDOMAINS = ["pds"]; +const HANDLE_DOMAINS = SUBDOMAINS.map((subdomain) => `${subdomain}.bas.sh`); +const WILDCARD_HOSTS = HANDLE_DOMAINS.map((domain) => `*.${domain}`); export const pdsService = new ContainerService("pds", { image: "ghcr.io/bluesky-social/pds", servicePort: 3000, - hostRule: "HostRegexp(`^(.+\\.)?pds.bas.sh$`)", + hostRule: toHostRule([...HANDLE_DOMAINS, ...WILDCARD_HOSTS]), mounts: [confMount("pds", "/pds")], envs: { PDS_HOSTNAME: "pds.bas.sh", @@ -33,25 +38,45 @@ export const pdsService = new ContainerService("pds", { PDS_EMAIL_FROM_ADDRESS: "PDS ", }, labels: { - "traefik.http.middlewares.pds-favicon.redirectregex.regex": - "^https://pds\\.bas\\.sh/favicon\\.ico$", + "traefik.http.routers.pds-user-redirect.entrypoints": "https", + "traefik.http.routers.pds-user-redirect.rule": `(${toHostRule(WILDCARD_HOSTS)}) && !PathPrefix(\`/.well-known\`)`, + "traefik.http.routers.pds-user-redirect.middlewares": "cloudflare,bsky-user-redirect", + "traefik.http.routers.pds-user-redirect.priority": 1000, + + "traefik.http.middlewares.pds-favicon.redirectregex.regex": "^https://.+/favicon\\.ico$", "traefik.http.middlewares.pds-favicon.redirectregex.replacement": "https://tranquil.bas.sh/favicon.ico", "traefik.http.routers.pds-favicon.entrypoints": "https", - "traefik.http.routers.pds-favicon.rule": "Host(`pds.bas.sh`) && Path(`/favicon.ico`)", + "traefik.http.routers.pds-favicon.rule": `(${toHostRule(HANDLE_DOMAINS)}) && Path(\`/favicon.ico\`)`, "traefik.http.routers.pds-favicon.middlewares": "cloudflare,pds-favicon", }, }); -const webMount = ssdcacheMount("web/pds", "/var/www"); +const PDS_MOTD = ` + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠙⠻⢶⣄⡀⠀⠀⠀⢀⣤⠶⠛⠛⡇ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣇⠀⠀⣙⣿⣦⣤⣴⣿⣁⠀⠀⣸⠇ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣡⣾⣿⣿⣿⣿⣿⣿⣿⣷⣌⠋⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣷⣄⡈⢻⣿⡟⢁⣠⣾⣿⣦⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣿⠘⣿⠃⣿⣿⣿⣿⡏⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠈⠛⣰⠿⣆⠛⠁⠀⡀⠀⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣦⠀⠘⠛⠋⠀⣴⣿⠁⠀⠀ + ⠀⠀⠀⠀⠀⠀⣀⣤⣶⣾⣿⣿⣿⣿⡇⠀⠀⠀⢸⣿⣏⠀⠀⠀ + ⠀⠀⠀⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠀⠀⠀⠾⢿⣿⠀⠀⠀ + ⠀⣠⣿⣿⣿⣿⣿⣿⡿⠟⠋⣁⣠⣤⣤⡶⠶⠶⣤⣄⠈⠀⠀⠀ + ⢰⣿⣿⣮⣉⣉⣉⣤⣴⣶⣿⣿⣋⡥⠄⠀⠀⠀⠀⠉⢻⣄⠀⠀ + ⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⣋⣁⣤⣀⣀⣤⣤⣤⣤⣄⣿⡄⠀ + ⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠋⠉⠁⠀⠀⠀⠀⠈⠛⠃⠀ + ⠀⠀⠀⠀⠉⠉⠉⠉⠉ -const MOTD_FILE_NAME = "motd.txt"; -const motdFile = new asset.FileAsset(path.join(import.meta.dirname, MOTD_FILE_NAME)); -const copyMotdFile = new remote.CopyToRemote("pds-motd", { - connection: defaultConnection, - source: motdFile, - remotePath: output(webMount.source).apply((dir) => path.join(dir, MOTD_FILE_NAME)), -}); +This is an AT Protocol Personal Data Server (aka, an atproto PDS) + +Most API routes are under /xrpc/ + + Code: https://github.com/bluesky-social/atproto + Self-Host: https://github.com/bluesky-social/pds + Protocol: https://atproto.com +`.slice(1); const CADDYFILE = ` :80 { @@ -60,8 +85,7 @@ const CADDYFILE = ` } handle / { - try_files /${MOTD_FILE_NAME} - file_server + respond "${PDS_MOTD}" 200 } } `; @@ -72,8 +96,6 @@ export const pdsCaddyService = new ContainerService("pds-web", { hostRule: "Host(`pds.bas.sh`) && (Path(`/`) || Path(`/xrpc/app.bsky.ageassurance.getState`))", hostRulePriority: 1000, command: ["/bin/sh", "-c", `echo '${CADDYFILE}' | caddy run --config - --adapter caddyfile`], - mounts: [webMount], - workingDir: "/var/www", middlewares: ["cors"], }); diff --git a/services/haring/atproto/pegasus.ts b/services/haring/atproto/pegasus.ts index 6a7eae2..049ec17 100644 --- a/services/haring/atproto/pegasus.ts +++ b/services/haring/atproto/pegasus.ts @@ -1,13 +1,18 @@ import { DnsRecord } from "@pulumi/cloudflare"; import { getEnv } from "~lib/env"; import { fetchRelays } from "~lib/relay-hosts"; +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; +import { toHostRule } from "~lib/util"; + +const SUBDOMAINS = ["pegasus"]; +const HANDLE_DOMAINS = SUBDOMAINS.map((subdomain) => `${subdomain}.bas.sh`); +const WILDCARD_HOSTS = HANDLE_DOMAINS.map((domain) => `*.${domain}`); export const pegasusService = new ContainerService("pegasus", { image: "ghcr.io/futurgh/pegasus", servicePort: 8008, - hostRule: "HostRegexp(`^(.+?\\.)?pegasus\\.bas\\.sh$`)", + hostRule: toHostRule([...HANDLE_DOMAINS, ...WILDCARD_HOSTS]), mounts: [confMount("pegasus", "/data")], envs: { PSD_LOG_LEVEL: "info", @@ -21,26 +26,17 @@ export const pegasusService = new ContainerService("pegasus", { PDS_CRAWLERS: fetchRelays(), }, labels: { - "traefik.http.middlewares.pegasus-user-redirect.redirectregex.regex": - "^https://(.+\\.pegasus\\.bas\\.sh)/(.*)$", - "traefik.http.middlewares.pegasus-user-redirect.redirectregex.replacement": - "https://bsky.app/profile/${1}", "traefik.http.routers.pegasus-user-redirect.entrypoints": "https", - "traefik.http.routers.pegasus-user-redirect.rule": - "HostRegexp(`^.+\\.pegasus\\.bas\\.sh$`) && !PathPrefix(`/.well-known`)", - "traefik.http.routers.pegasus-user-redirect.middlewares": "cloudflare,pegasus-user-redirect", - "traefik.http.routers.pegasus-user-redirect.priority": 100, + "traefik.http.routers.pegasus-user-redirect.rule": `(${toHostRule(WILDCARD_HOSTS)}) && !PathPrefix(\`/.well-known\`)`, + "traefik.http.routers.pegasus-user-redirect.middlewares": "cloudflare,bsky-user-redirect", + "traefik.http.routers.pegasus-user-redirect.priority": 1000, - "traefik.http.middlewares.pegasus-favicon-witchsky.redirectregex.regex": - "^https://pegasus\\.bas\\.sh/favicon\\.ico$", - "traefik.http.middlewares.pegasus-favicon-witchsky.redirectregex.replacement": + "traefik.http.middlewares.pegasus-favicon.redirectregex.regex": "^https://.+/favicon\\.ico$", + "traefik.http.middlewares.pegasus-favicon.redirectregex.replacement": "https://wsrv.nl/?url=https://em-content.zobj.net/source/serenityos/392/horse-face_1f434.png&w=74&h=74&fit=contain&bg=ece5d3&we", - "traefik.http.routers.pegasus-favicon-witchsky.entrypoints": "https", - "traefik.http.routers.pegasus-favicon-witchsky.rule": - "Host(`pegasus.bas.sh`) && Path(`/favicon.ico`)", - // "Host(`pegasus.bas.sh`) && Path(`/favicon.ico`) && HeaderRegexp(`Referer`, `\\bwitchsky\\b`)", - "traefik.http.routers.pegasus-favicon-witchsky.middlewares": - "cloudflare,pegasus-favicon-witchsky", + "traefik.http.routers.pegasus-favicon.entrypoints": "https", + "traefik.http.routers.pegasus-favicon.rule": `(${toHostRule(HANDLE_DOMAINS)}) && Path(\`/favicon.ico\`)`, + "traefik.http.routers.pegasus-favicon.middlewares": "cloudflare,pegasus-favicon", }, }); @@ -107,7 +103,7 @@ export const horseService = new ContainerService(`caddy-horse`, { image: "caddy", servicePort: 80, hostRule: "Host(`horse.pegasus.bas.sh`) && Path(`/`)", - hostRulePriority: 1000, + hostRulePriority: 10000, command: ["/bin/sh", "-c", `echo '${CADDYFILE}' | caddy run --config - --adapter caddyfile`], mounts: [ssdcacheMount("web/horse", "/var/www")], workingDir: "/var/www", diff --git a/services/haring/atproto/relay.ts b/services/haring/atproto/relay.ts index 31193e5..67ebb53 100644 --- a/services/haring/atproto/relay.ts +++ b/services/haring/atproto/relay.ts @@ -1,15 +1,15 @@ -import dockerBuild from "@pulumi/docker-build"; +import { Image } from "@pulumi/docker-build"; import { interpolate } from "@pulumi/pulumi"; import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, nvmeMount } from "~lib/service/mounts"; import { defaultNetwork } from "~lib/service/networks"; -import { ContainerService } from "~lib/service/service"; import { getGithubContents } from "~lib/util"; import { STATIC_IPS } from "../ips"; import { unboundService } from "../networking/unbound/unbound"; -const postgresRelayService = new ContainerService("postgres-relay", { +export const postgresRelayService = new ContainerService("postgres-relay", { image: "postgres", mounts: [confMount("postgres-relay", "/var/lib/postgresql")], envs: { @@ -19,7 +19,7 @@ const postgresRelayService = new ContainerService("postgres-relay", { networksAdvanced: [{ name: defaultNetwork.name, ipv4Address: STATIC_IPS.POSTGRES_RELAY }], }); -const relayImage = new dockerBuild.Image( +const relayImage = new Image( "relay", { tags: ["relay:latest"], @@ -42,15 +42,26 @@ const relayImage = new dockerBuild.Image( ); const RELAY_MOTD = ` - 「Become a magical girl today!」 - / - /人◕ ‿‿ ◕人\ - + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠙⠻⢶⣄⡀⠀⠀⠀⢀⣤⠶⠛⠛⡇ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣇⠀⠀⣙⣿⣦⣤⣴⣿⣁⠀⠀⣸⠇ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣡⣾⣿⣿⣿⣿⣿⣿⣿⣷⣌⠋⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣷⣄⡈⢻⣿⡟⢁⣠⣾⣿⣦⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣿⠘⣿⠃⣿⣿⣿⣿⡏⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠈⠛⣰⠿⣆⠛⠁⠀⡀⠀⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣦⠀⠘⠛⠋⠀⣴⣿⠁⠀⠀ + ⠀⠀⠀⠀⠀⠀⣀⣤⣶⣾⣿⣿⣿⣿⡇⠀⠀⠀⢸⣿⣏⠀⠀⠀ + ⠀⠀⠀⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠀⠀⠀⠾⢿⣿⠀⠀⠀ + ⠀⣠⣿⣿⣿⣿⣿⣿⡿⠟⠋⣁⣠⣤⣤⡶⠶⠶⣤⣄⠈⠀⠀⠀ + ⢰⣿⣿⣮⣉⣉⣉⣤⣴⣶⣿⣿⣋⡥⠄⠀⠀⠀⠀⠉⢻⣄⠀⠀ + ⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⣋⣁⣤⣀⣀⣤⣤⣤⣤⣄⣿⡄⠀ + ⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠋⠉⠁⠀⠀⠀⠀⠈⠛⠃⠀ + ⠀⠀⠀⠀⠉⠉⠉⠉⠉ This is an atproto [https://atproto.com] relay instance, running the 'relay' codebase [https://github.com/bluesky-social/indigo] The firehose WebSocket path is at: /xrpc/com.atproto.sync.subscribeRepos -`; +`.slice(1); const CADDYFILE = ` :80 { @@ -79,7 +90,7 @@ export const relayCaddyService = new ContainerService("caddy-relay", { export const relayService = new ContainerService( "relay", { - localImage: interpolate`${relayImage.ref}@${relayImage.digest}`, + localImage: relayImage.digest, servicePort: 2470, networkMode: "host", mounts: [nvmeMount("relay", "/data/relay/persist")], @@ -87,13 +98,14 @@ export const relayService = new ContainerService( dns: [STATIC_IPS.UNBOUND], envs: { RELAY_ADMIN_PASSWORD: getEnv("RELAY_ADMIN_PASSWORD"), - DATABASE_URL: interpolate`postgres://postgres:${getEnv("POSTGRES_PASSWORD")}@${postgresRelayService.ip}/relay`, + DATABASE_URL: interpolate`postgres://postgres:${getEnv("POSTGRES_PASSWORD")}@${STATIC_IPS.POSTGRES_RELAY}/relay`, RELAY_PERSIST_DIR: "/data/relay/persist", - RELAY_REPLAY_WINDOW: "24h", + RELAY_REPLAY_WINDOW: "36h", RELAY_LENIENT_SYNC_VALIDATION: true, - MAX_DB_CONNECTIONS: 80, - RELAY_HOST_CONCURRENCY: 80, - RELAY_DEFAULT_REPO_LIMIT: 1000, + // MAX_DB_CONNECTIONS: 80, + // RELAY_HOST_CONCURRENCY: 80, + RELAY_NEW_HOSTS_PER_DAY_LIMIT: 200, + RELAY_DEFAULT_REPO_LIMIT: 100000, RELAY_TRUSTED_DOMAINS: [ "*.host.bsky.network", "atproto.brid.gy", diff --git a/services/haring/atproto/social-app.ts b/services/haring/atproto/social-app.ts index b0dcc43..f20f2f6 100644 --- a/services/haring/atproto/social-app.ts +++ b/services/haring/atproto/social-app.ts @@ -1,4 +1,4 @@ -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; export const blueskyService = new ContainerService("bluesky", { image: "ghcr.io/brw/social-app", diff --git a/services/haring/atproto/tangled/knot.ts b/services/haring/atproto/tangled/knot.ts index 3ea6b33..517c81d 100644 --- a/services/haring/atproto/tangled/knot.ts +++ b/services/haring/atproto/tangled/knot.ts @@ -1,10 +1,8 @@ import { DnsRecord } from "@pulumi/cloudflare"; -import { remote } from "@pulumi/command"; import { Image } from "@pulumi/docker-build"; -import { asset } from "@pulumi/pulumi"; import { getEnv } from "~lib/env"; -import { confMount, mount, nvmeMount } from "~lib/service/mounts"; -import { ContainerService, defaultConnection } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; +import { confMount, nvmeMount } from "~lib/service/mounts"; import { getLatestTangledCommit } from "~lib/util"; const knotImage = new Image( @@ -30,24 +28,14 @@ const knotImage = new Image( }, ); -export const knotMotd = new remote.CopyToRemote("knot-motd", { - connection: defaultConnection, - source: new asset.StringAsset( - ` /人◕ ‿‿ ◕人\ - \x1B[2mThe contract has been made.\x1B[22m\n`, - ), - remotePath: "/home/bas/docker/knot/motd", -}); +const KNOT_GIT_MOTD = ` /人◕ ‿‿ ◕人\ + \x1B[2mYour contract has been made.\x1B[22m\n`; export const knotService = new ContainerService("knot", { localImage: knotImage.digest, servicePort: 5555, ports: [22], - mounts: [ - confMount("knot", "/app"), - mount(knotMotd.remotePath, "/home/git/motd", { kind: "file" }), - nvmeMount("knot", "/home/git/repositories"), - ], + mounts: [confMount("knot", "/app"), nvmeMount("knot", "/home/git/repositories")], volumes: [{ volumeName: "knot-keys", containerPath: "/etc/ssh/keys" }], envs: { KNOT_SERVER_HOSTNAME: "knot.bas.sh", @@ -55,6 +43,53 @@ export const knotService = new ContainerService("knot", { KNOT_SERVER_DB_PATH: "/app/knotserver.db", KNOT_SERVER_INTERNAL_LISTEN_ADDR: "localhost:5444", }, + uploads: [{ content: KNOT_GIT_MOTD, file: "/home/git/motd" }], +}); + +const KNOT_WEB_MOTD = ` + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠙⠻⢶⣄⡀⠀⠀⠀⢀⣤⠶⠛⠛⡇ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣇⠀⠀⣙⣿⣦⣤⣴⣿⣁⠀⠀⣸⠇ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣡⣾⣿⣿⣿⣿⣿⣿⣿⣷⣌⠋⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣷⣄⡈⢻⣿⡟⢁⣠⣾⣿⣦⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣿⠘⣿⠃⣿⣿⣿⣿⡏⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠈⠛⣰⠿⣆⠛⠁⠀⡀⠀⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣦⠀⠘⠛⠋⠀⣴⣿⠁⠀⠀ + ⠀⠀⠀⠀⠀⠀⣀⣤⣶⣾⣿⣿⣿⣿⡇⠀⠀⠀⢸⣿⣏⠀⠀⠀ + ⠀⠀⠀⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠀⠀⠀⠾⢿⣿⠀⠀⠀ + ⠀⣠⣿⣿⣿⣿⣿⣿⡿⠟⠋⣁⣠⣤⣤⡶⠶⠶⣤⣄⠈⠀⠀⠀ + ⢰⣿⣿⣮⣉⣉⣉⣤⣴⣶⣿⣿⣋⡥⠄⠀⠀⠀⠀⠉⢻⣄⠀⠀ + ⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⣋⣁⣤⣀⣀⣤⣤⣤⣤⣄⣿⡄⠀ + ⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠋⠉⠁⠀⠀⠀⠀⠈⠛⠃⠀ + ⠀⠀⠀⠀⠉⠉⠉⠉⠉ + +This is a knot server. More info at https://docs.tangled.org/knot-self-hosting-guide + +Most API routes are under /xrpc/ +`.slice(1); + +const CADDYFILE = ` + :80 { + respond "${KNOT_WEB_MOTD}" 200 + } +`; + +export const knotCaddyService = new ContainerService("knot-web", { + image: "caddy", + servicePort: 80, + hostRule: "Host(`knot.bas.sh`) && Path(`/`)", + hostRulePriority: 1000, + command: ["/bin/sh", "-c", `echo '${CADDYFILE}' | caddy run --config - --adapter caddyfile`], + middlewares: ["cors"], + labels: { + "traefik.http.middlewares.knot-favicon.redirectregex.regex": + "^https://knot\\.bas\\.sh/favicon\\.ico$", + "traefik.http.middlewares.knot-favicon.redirectregex.replacement": + "https://tranquil.bas.sh/favicon.ico", + "traefik.http.routers.knot-favicon.entrypoints": "https", + "traefik.http.routers.knot-favicon.rule": "Host(`knot.bas.sh`) && Path(`/favicon.ico`)", + "traefik.http.routers.knot-favicon.middlewares": "cloudflare,knot-favicon", + }, }); export const knotDnsRecord = new DnsRecord("knot", { diff --git a/services/haring/atproto/tangled/spindle.ts b/services/haring/atproto/tangled/spindle.ts index be7c8f5..7f313e3 100644 --- a/services/haring/atproto/tangled/spindle.ts +++ b/services/haring/atproto/tangled/spindle.ts @@ -1,8 +1,8 @@ import { DnsRecord } from "@pulumi/cloudflare"; import { Image } from "@pulumi/docker-build"; import { getEnv } from "~lib/env"; -import { confMount, dockerSocketRw, nvmeMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; +import { confMount, dockerSocket, nvmeMount } from "~lib/service/mounts"; import { getLatestTangledCommit } from "~lib/util"; const spindleImage = new Image( @@ -33,12 +33,76 @@ export const spindleService = new ContainerService("spindle", { servicePort: 6555, mounts: [ confMount("spindle/logs", "/var/log/spindle"), - nvmeMount("spindle", "/app"), - dockerSocketRw, + nvmeMount("spindle/app", "/app"), + nvmeMount("spindle/images", "/images"), + nvmeMount("spindle/overlays", "/overlays"), + dockerSocket, ], + devices: ["/dev/kvm", "/dev/vhost-vsock", "/dev/vsock", "/dev/net/tun"].map((dev) => ({ + containerPath: dev, + hostPath: dev, + permissions: "r", + })), envs: { SPINDLE_SERVER_HOSTNAME: "spindle.bas.sh", SPINDLE_SERVER_OWNER: getEnv("ATPROTO_DID"), + SPINDLE_PIPELINES_WORKFLOW_TIMEOUT: "60m", + SPINDLE_MICROVM_PIPELINES_WORKFLOW_TIMEOUT: "60m", + SPINDLE_MICROVM_PIPELINES_IMAGE_DIR: "/images", + SPINDLE_MICROVM_PIPELINES_OVERLAY_DIR: "/overlays", + SPINDLE_NIX_CACHE_READ_URLS: "http://ncps:8501,https://cache.nixos.org", + SPINDLE_NIX_CACHE_TRUSTED_PUBLIC_KEYS: + "cache.bas.sh:HR5UV8Png8fmmG1vCPHmNHyV+lwZPjP3Sk/BjxfGOFk=,cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=", + SPINDLE_NIX_CACHE_UPLOAD_URL: "http://ncps:8501", + }, + capabilities: ["NET_ADMIN", "SYS_ADMIN"], + securityOpts: ["apparmor=unconfined", "seccomp=unconfined", "label=disable"], + privileged: true, // TODO: remove +}); + +const SPINDLE_MOTD = ` + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠙⠻⢶⣄⡀⠀⠀⠀⢀⣤⠶⠛⠛⡇ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣇⠀⠀⣙⣿⣦⣤⣴⣿⣁⠀⠀⣸⠇ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣡⣾⣿⣿⣿⣿⣿⣿⣿⣷⣌⠋⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣷⣄⡈⢻⣿⡟⢁⣠⣾⣿⣦⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣿⠘⣿⠃⣿⣿⣿⣿⡏⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠈⠛⣰⠿⣆⠛⠁⠀⡀⠀⠀ + ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣦⠀⠘⠛⠋⠀⣴⣿⠁⠀⠀ + ⠀⠀⠀⠀⠀⠀⣀⣤⣶⣾⣿⣿⣿⣿⡇⠀⠀⠀⢸⣿⣏⠀⠀⠀ + ⠀⠀⠀⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠀⠀⠀⠾⢿⣿⠀⠀⠀ + ⠀⣠⣿⣿⣿⣿⣿⣿⡿⠟⠋⣁⣠⣤⣤⡶⠶⠶⣤⣄⠈⠀⠀⠀ + ⢰⣿⣿⣮⣉⣉⣉⣤⣴⣶⣿⣿⣋⡥⠄⠀⠀⠀⠀⠉⢻⣄⠀⠀ + ⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⣋⣁⣤⣀⣀⣤⣤⣤⣤⣄⣿⡄⠀ + ⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠋⠉⠁⠀⠀⠀⠀⠈⠛⠃⠀ + ⠀⠀⠀⠀⠉⠉⠉⠉⠉ + +This is a spindle server. More info at https://docs.tangled.org/spindles#spindles + +Most API routes are under /xrpc/ +`.slice(1); + +const CADDYFILE = ` + :80 { + respond "${SPINDLE_MOTD}" 200 + } +`; + +export const spindleCaddyService = new ContainerService("spindle-web", { + image: "caddy", + servicePort: 80, + hostRule: "Host(`spindle.bas.sh`) && Path(`/`)", + hostRulePriority: 1000, + command: ["/bin/sh", "-c", `echo '${CADDYFILE}' | caddy run --config - --adapter caddyfile`], + middlewares: ["cors"], + labels: { + "traefik.http.middlewares.spindle-favicon.redirectregex.regex": + "^https://spindle\\.bas\\.sh/favicon\\.ico$", + "traefik.http.middlewares.spindle-favicon.redirectregex.replacement": + "https://tranquil.bas.sh/favicon.ico", + "traefik.http.routers.spindle-favicon.entrypoints": "https", + "traefik.http.routers.spindle-favicon.rule": "Host(`spindle.bas.sh`) && Path(`/favicon.ico`)", + "traefik.http.routers.spindle-favicon.middlewares": "cloudflare,spindle-favicon", }, }); diff --git a/services/haring/atproto/tranquil/tranquil.ts b/services/haring/atproto/tranquil/tranquil.ts index 4e43114..ca64920 100644 --- a/services/haring/atproto/tranquil/tranquil.ts +++ b/services/haring/atproto/tranquil/tranquil.ts @@ -1,22 +1,25 @@ -import path from "path"; - import { DnsRecord } from "@pulumi/cloudflare"; -import { remote } from "@pulumi/command"; -import dockerBuild from "@pulumi/docker-build"; -import { asset, interpolate } from "@pulumi/pulumi"; +import { Image } from "@pulumi/docker-build"; +import { interpolate } from "@pulumi/pulumi"; import { getEnv } from "~lib/env"; import { fetchRelays } from "~lib/relay-hosts"; -import { _mount, confMount, mount } from "~lib/service/mounts"; -import { ContainerService, defaultConnection } from "~lib/service/service"; -import { getLatestTangledCommit } from "~lib/util"; +import { ContainerService } from "~lib/service"; +import { confMount } from "~lib/service/mounts"; +import { getLatestTangledCommit, toHostRule } from "~lib/util"; -const tranquilImage = new dockerBuild.Image( +const tranquilImage = new Image( "tranquil-pds", { tags: ["tranquil-pds:latest"], context: { location: "https://tangled.org/tranquil.farm/tranquil-pds.git", }, + // platforms: [ + // dockerBuild.Platform.Linux_amd64, + // dockerBuild.Platform.Linux_arm64, + // dockerBuild.Platform.Darwin_amd64, + // dockerBuild.Platform.Darwin_arm64, + // ], buildArgs: { BUILDKIT_CONTEXT_KEEP_GIT_DIR: "true", }, @@ -44,39 +47,42 @@ const postgresTranquilService = new ContainerService("postgres-tranquil", { }, }); -const PDS_USER_HANDLE_DOMAINS = ["tranquil.bas.sh", "t.bas.sh", "on.bas.sh", "of.bas.sh"]; -for (const host of PDS_USER_HANDLE_DOMAINS) { - new DnsRecord(`tranquil-${host}`, { - zoneId: getEnv("CLOUDFLARE_ZONE_ID"), - name: host, - ttl: 1, - type: "CNAME", - content: "haring.bas.sh", - proxied: false, - }); - new DnsRecord(`tranquil-wildcard-${host}`, { - zoneId: getEnv("CLOUDFLARE_ZONE_ID"), - name: `*.${host}`, - ttl: 1, - type: "CNAME", - content: "tranquil.bas.sh", - proxied: false, - }); +const SUBDOMAINS = ["tranquil", "t", "on", "of"]; +const HANDLE_DOMAINS = SUBDOMAINS.map((subdomain) => `${subdomain}.bas.sh`); +const WILDCARD_HOSTS = HANDLE_DOMAINS.map((domain) => `*.${domain}`); + +for (const host of [...HANDLE_DOMAINS, ...WILDCARD_HOSTS]) { + new DnsRecord( + `tranquil-${host}`, + { + zoneId: getEnv("CLOUDFLARE_ZONE_ID"), + name: host, + ttl: 1, + type: "CNAME", + content: "haring.bas.sh", + proxied: false, + }, + { + aliases: [ + { + name: host.includes("*") + ? `tranquil-${host.replace("*.", "wildcard-")}` + : `tranquil-${host}`, + }, + ], + }, + ); } export const tranquilService = new ContainerService("tranquil", { localImage: tranquilImage.digest, servicePort: 3000, - hostRule: "HostRegexp(`^(.+?\\.)?(t(ranquil)|o(n|f))\\.bas\\.sh$`)", - mounts: [ - confMount("tranquil/backups", "/var/lib/tranquil/backups"), - confMount("tranquil/blobs", "/var/lib/tranquil/blobs"), - ], + hostRule: `Host(\`tranquil.bas.sh\`) || ((${toHostRule(WILDCARD_HOSTS)}) && PathPrefix(\`/.well-known\`))`, + mounts: [confMount("tranquil/blobs", "/var/lib/tranquil/blobs")], envs: { DATABASE_URL: interpolate`postgres://postgres:${getEnv("POSTGRES_PASSWORD")}@${postgresTranquilService.container.name}/pds`, PDS_HOSTNAME: "tranquil.bas.sh", BLOB_STORAGE_PATH: "/var/lib/tranquil/blobs", - BACKUP_STORAGE_PATH: "/var/lib/tranquil/backups", JWT_SECRET: getEnv("TRANQUIL_JWT_SECRET"), DPOP_SECRET: getEnv("TRANQUIL_DPOP_SECRET"), MASTER_KEY: getEnv("TRANQUIL_MASTER_KEY"), @@ -90,27 +96,23 @@ export const tranquilService = new ContainerService("tranquil", { DISCORD_BOT_TOKEN: getEnv("TRANQUIL_DISCORD_BOT_TOKEN"), INVITE_CODE_REQUIRED: true, ACCEPTING_REPO_IMPORTS: true, - PDS_USER_HANDLE_DOMAINS, + PDS_USER_HANDLE_DOMAINS: HANDLE_DOMAINS, CONTACT_EMAIL: getEnv("EMAIL"), PDS_AGE_ASSURANCE_OVERRIDE: true, CRAWLERS: fetchRelays(), }, labels: { - "traefik.http.middlewares.tranquil-redirect.redirectregex.regex": - "^https://(t|on)\\.bas\\.sh/(.*)$", - "traefik.http.middlewares.tranquil-redirect.redirectregex.replacement": - "https://tranquil.bas.sh/${2}", - "traefik.http.routers.tranquil-redirect.entrypoints": "https", - "traefik.http.routers.tranquil-redirect.rule": "HostRegexp(`^(t|on)\\.bas\\.sh$`)", - "traefik.http.routers.tranquil-redirect.middlewares": "cloudflare,tranquil-redirect", + "traefik.http.middlewares.tranquil-main-redirect.redirectregex.regex": `^.+?\\.bas.sh/(.*)?$`, + "traefik.http.middlewares.tranquil-main-redirect.redirectregex.replacement": + "https://tranquil.bas.sh/${1}", + "traefik.http.routers.tranquil-main-redirect.entrypoints": "https", + "traefik.http.routers.tranquil-main-redirect.rule": toHostRule(HANDLE_DOMAINS.slice(1)), + "traefik.http.routers.tranquil-main-redirect.middlewares": "cloudflare,tranquil-main-redirect", + "traefik.http.routers.tranquil-main-redirect.priority": 1000, - "traefik.http.middlewares.tranquil-user-redirect.redirectregex.regex": - "^https://(.+\\.(t(ranquil)?|o(n|f))\\.bas\\.sh)/(.*)$", - "traefik.http.middlewares.tranquil-user-redirect.redirectregex.replacement": - "https://bsky.app/profile/${1}", "traefik.http.routers.tranquil-user-redirect.entrypoints": "https", - "traefik.http.routers.tranquil-user-redirect.rule": - "HostRegexp(`^.+\\.(t(ranquil)?|o(n|f))\\.bas\\.sh$`) && !PathPrefix(`/.well-known`)", - "traefik.http.routers.tranquil-user-redirect.middlewares": "cloudflare,tranquil-user-redirect", + "traefik.http.routers.tranquil-user-redirect.rule": `(${toHostRule(WILDCARD_HOSTS)}) && !PathPrefix(\`/.well-known\`)`, + "traefik.http.routers.tranquil-user-redirect.middlewares": "cloudflare,bsky-user-redirect", + "traefik.http.routers.tranquil-user-redirect.priority": 1000, }, }); diff --git a/services/haring/communication/ergo.ts b/services/haring/communication/ergo.ts index 255df98..f5ff172 100644 --- a/services/haring/communication/ergo.ts +++ b/services/haring/communication/ergo.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const ergoService = new ContainerService("ergo", { image: "ghcr.io/ergochat/ergo", diff --git a/services/haring/communication/thelounge.ts b/services/haring/communication/thelounge.ts index 20d884f..2ff5119 100644 --- a/services/haring/communication/thelounge.ts +++ b/services/haring/communication/thelounge.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const theloungeService = new ContainerService("thelounge", { servicePort: 9000, diff --git a/services/haring/downloaders/jdownloader.ts b/services/haring/downloaders/jdownloader.ts index 9cfd6c2..e902ce0 100644 --- a/services/haring/downloaders/jdownloader.ts +++ b/services/haring/downloaders/jdownloader.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const jdownloaderService = new ContainerService("jdownloader", { image: "jlesage/jdownloader-2", diff --git a/services/haring/downloaders/qbittools.ts b/services/haring/downloaders/qbittools.ts index f427779..1201099 100644 --- a/services/haring/downloaders/qbittools.ts +++ b/services/haring/downloaders/qbittools.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; import { qbittorrentService } from "./qbittorrent"; diff --git a/services/haring/downloaders/qbittorrent-exporter.ts b/services/haring/downloaders/qbittorrent-exporter.ts index 056dc20..8e5486c 100644 --- a/services/haring/downloaders/qbittorrent-exporter.ts +++ b/services/haring/downloaders/qbittorrent-exporter.ts @@ -1,5 +1,5 @@ import { getEnv } from "~lib/env"; -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; import { qbittorrentService } from "./qbittorrent"; diff --git a/services/haring/downloaders/qbittorrent.ts b/services/haring/downloaders/qbittorrent.ts index f5a3f0e..cc0ab3a 100644 --- a/services/haring/downloaders/qbittorrent.ts +++ b/services/haring/downloaders/qbittorrent.ts @@ -1,8 +1,8 @@ +import { ContainerService } from "~lib/service"; import { confMount, dataMount, nvmeMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const qbittorrentService = new ContainerService("qbittorrent", { - image: "lscr.io/linuxserver/qbittorrent:5.1.4", + image: "lscr.io/linuxserver/qbittorrent:5.2.3", servicePort: 8080, // ports: [1337, "1337/udp"], envs: { diff --git a/services/haring/downloaders/qui.ts b/services/haring/downloaders/qui.ts index 6c9a5cd..8cdd1db 100644 --- a/services/haring/downloaders/qui.ts +++ b/services/haring/downloaders/qui.ts @@ -1,7 +1,7 @@ import { DnsRecord } from "@pulumi/cloudflare"; import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, dataMount, nvmeMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const quiService = new ContainerService("qui", { image: "ghcr.io/autobrr/qui", diff --git a/services/haring/downloaders/sabnzbd.ts b/services/haring/downloaders/sabnzbd.ts index 275ad8d..7714046 100644 --- a/services/haring/downloaders/sabnzbd.ts +++ b/services/haring/downloaders/sabnzbd.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const sabnzbdService = new ContainerService("sabnzbd", { servicePort: 8080, diff --git a/services/haring/files/filebrowser.ts b/services/haring/files/filebrowser.ts index d258219..d0858a1 100644 --- a/services/haring/files/filebrowser.ts +++ b/services/haring/files/filebrowser.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const filebrowserService = new ContainerService("filebrowser", { image: "ghcr.io/gtsteffaniak/filebrowser:beta", diff --git a/services/haring/files/filestash.ts b/services/haring/files/filestash.ts index bea836d..cfcc8c2 100644 --- a/services/haring/files/filestash.ts +++ b/services/haring/files/filestash.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const fileStashService = new ContainerService("filestash", { image: "machines/filestash", diff --git a/services/haring/files/h5ai.ts b/services/haring/files/h5ai.ts index 1d0224b..6e09c51 100644 --- a/services/haring/files/h5ai.ts +++ b/services/haring/files/h5ai.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const h5aiService = new ContainerService("h5ai", { image: "awesometic/h5ai", diff --git a/services/haring/files/nextcloud.ts b/services/haring/files/nextcloud.ts index edf83fb..50ae4d9 100644 --- a/services/haring/files/nextcloud.ts +++ b/services/haring/files/nextcloud.ts @@ -1,7 +1,7 @@ import { interpolate } from "@pulumi/pulumi"; import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; const valkeyNextcloudService = new ContainerService("valkey-nextcloud", { image: "valkey/valkey", diff --git a/services/haring/files/nextexplorer.ts b/services/haring/files/nextexplorer.ts index 55700b9..063f809 100644 --- a/services/haring/files/nextexplorer.ts +++ b/services/haring/files/nextexplorer.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const nextexplorerService = new ContainerService("nextexplorer", { image: "nxzai/explorer", diff --git a/services/haring/files/resilio.ts b/services/haring/files/resilio.ts index 775a37d..d4840c9 100644 --- a/services/haring/files/resilio.ts +++ b/services/haring/files/resilio.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const resilioSyncService = new ContainerService("resilio-sync", { subdomain: "sync", diff --git a/services/haring/files/sftpgo.ts b/services/haring/files/sftpgo.ts index b2a6fbe..6e0f859 100644 --- a/services/haring/files/sftpgo.ts +++ b/services/haring/files/sftpgo.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const sftpgoService = new ContainerService("sftpgo", { image: "drakkan/sftpgo:plugins", diff --git a/services/haring/files/sist2.ts b/services/haring/files/sist2.ts index 21a7a2b..b32e014 100644 --- a/services/haring/files/sist2.ts +++ b/services/haring/files/sist2.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const sist2Service = new ContainerService("sist2", { image: "sist2app/sist2:x64-linux", diff --git a/services/haring/files/spacedrive.ts b/services/haring/files/spacedrive.ts index 4a3845e..0590c7d 100644 --- a/services/haring/files/spacedrive.ts +++ b/services/haring/files/spacedrive.ts @@ -1,7 +1,7 @@ import { interpolate } from "@pulumi/pulumi"; import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const spacedriveService = new ContainerService("spacedrive", { image: "ghcr.io/spacedriveapp/spacedrive/server", diff --git a/services/haring/files/stash.ts b/services/haring/files/stash.ts index 9894684..4c29128 100644 --- a/services/haring/files/stash.ts +++ b/services/haring/files/stash.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount, gitMount, mount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const stashService = new ContainerService("stash", { image: "stashapp/stash", @@ -10,6 +10,5 @@ export const stashService = new ContainerService("stash", { gitMount(), mount("/etc/localtime", "/etc/localtime", { readOnly: true }), ], - middlewares: ["auth"], cpuShares: 128, }); diff --git a/services/haring/files/synclounge.ts b/services/haring/files/synclounge.ts index 48c494c..a4cbbd7 100644 --- a/services/haring/files/synclounge.ts +++ b/services/haring/files/synclounge.ts @@ -1,4 +1,4 @@ -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; export const syncloungeService = new ContainerService("synclounge", { servicePort: 8088, diff --git a/services/haring/games/blockheads.ts b/services/haring/games/blockheads.ts index f53885d..1703d3c 100644 --- a/services/haring/games/blockheads.ts +++ b/services/haring/games/blockheads.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const blockheadsService = new ContainerService("blockheads", { image: "theblockheads/server:development", diff --git a/services/haring/games/hytale.ts b/services/haring/games/hytale.ts index 00a4e8d..eeebeb5 100644 --- a/services/haring/games/hytale.ts +++ b/services/haring/games/hytale.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { mount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const hytaleService = new ContainerService("hytale", { image: "hybrowse/hytale-server", diff --git a/services/haring/games/minecraft/servers/akio.ts b/services/haring/games/minecraft/servers/akio.ts index 312ae5b..60f8a7b 100644 --- a/services/haring/games/minecraft/servers/akio.ts +++ b/services/haring/games/minecraft/servers/akio.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { nvmeMount, mount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const rconService = new ContainerService("rcon", { image: "itzg/rcon", diff --git a/services/haring/games/minecraft/servers/frog.ts b/services/haring/games/minecraft/servers/frog.ts index 2fe7b9c..403d976 100644 --- a/services/haring/games/minecraft/servers/frog.ts +++ b/services/haring/games/minecraft/servers/frog.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { nvmeMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const minecraftService = new ContainerService( "minecraft", diff --git a/services/haring/games/minecraft/servers/mau.ts b/services/haring/games/minecraft/servers/mau.ts index 2603725..d89d05c 100644 --- a/services/haring/games/minecraft/servers/mau.ts +++ b/services/haring/games/minecraft/servers/mau.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { nvmeMount, mount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const minecraftMauService = new ContainerService( "minecraft-mau", diff --git a/services/haring/games/minecraft/servers/meow.ts b/services/haring/games/minecraft/servers/meow.ts index d78f596..8be519c 100644 --- a/services/haring/games/minecraft/servers/meow.ts +++ b/services/haring/games/minecraft/servers/meow.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { nvmeMount, mount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const minecraftMeow = new ContainerService( "minecraft-meow", diff --git a/services/haring/games/minecraft/servers/rengoku.ts b/services/haring/games/minecraft/servers/rengoku.ts index a1f87ed..d381732 100644 --- a/services/haring/games/minecraft/servers/rengoku.ts +++ b/services/haring/games/minecraft/servers/rengoku.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { nvmeMount, mount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; import { mcHasOnlinePlayers } from "../util"; @@ -77,10 +77,10 @@ export const minecraftRengokuService = new ContainerService( // server TYPE: "FABRIC", - FABRIC_LOADER_VERSION: "0.18.6", + // FABRIC_LOADER_VERSION: "0.18.6", EULA: true, VERSION: "1.21.11", - MOTD: "yeet", + MOTD: " \u00A74♥ \u00A76Rengoku \u00A74♥", DIFFICULTY: "normal", ICON: "https://i.bas.sh/rengoku.jpg", OVERRIDE_ICON: true, @@ -93,7 +93,6 @@ export const minecraftRengokuService = new ContainerService( ENABLE_WHITELIST: false, ENFORCE_WHITELIST: false, WHITELIST: ["basw"], - ENABLE_SSH: true, RCON_PASSWORD: getEnv("RCON_PASSWORD"), BROADCAST_RCON_TO_OPS: false, BROADCAST_CONSOLE_TO_OPS: false, @@ -124,11 +123,8 @@ export const minecraftRengokuService = new ContainerService( // "https://cdn.modrinth.com/data/izSO2Rn2/versions/vwYeKHZy/cabbage-substances-1.3.0.2-0.11.1.zip", ], MODS: [ - "https://github.com/DrexHD/remove-dialog-warning/releases/download/1.2.0/remove-dialog-warning-1.2.0.jar", // "https://cdn.modrinth.com/data/5OyO3XKw/versions/lOxOcQ5K/ultimate-roleplay-kit-urk-hats-v3.0.0-beta.jar", // "https://cdn.modrinth.com/data/tpBja9mt/versions/ifAYWMMc/ultimate-roleplay-kit-mail-urk-mail-v3.0.0beta.jar", - "https://cdn.modrinth.com/data/EltpO5cN/versions/NKsNpTwe/lootr-fabric-1.21.11-1.19.33.100.jar", - "https://cdn.modrinth.com/data/mhlzUYFC/versions/FqHMeEkR/LootrPolymer-1.1.jar", ], MODRINTH_PROJECTS: [ // libraries @@ -202,7 +198,7 @@ export const minecraftRengokuService = new ContainerService( // "melius-worldmanager", "simple-registry-aliases", "ledger", - "command-maker", + // "command-maker", "melius-commands", "offlinecommands", // "modify-player-data", @@ -210,6 +206,7 @@ export const minecraftRengokuService = new ContainerService( "stdrdc", "fabricexporter", "otel-instrumentation-extension", + "nice-admin-tools", // networking "no-chat-reports", @@ -260,8 +257,8 @@ export const minecraftRengokuService = new ContainerService( // "morecatvariants", "friends-and-foes-polymer", // "mini-vfx", - // "lootr-polymer-patch", - // "lootr:NKsNpTwe", + "lootr-polymer-patch", + "lootr", "more-tools", "polynutrition", // "notenoughminecraft", @@ -297,7 +294,7 @@ export const minecraftRengokuService = new ContainerService( // "view-distance-fix", "rail-placement-fix", "disconnect-packet-fix", - "whiteout", + // "whiteout", // "no-kebab", "dragon-movement-fix", "shieldstun", @@ -312,9 +309,9 @@ export const minecraftRengokuService = new ContainerService( "ghast-direction", "attribute-swapping-fix", "elytraportalfix", - "thiocyanate", + // "thiocyanate", "always-shield", - // "packet-fixer", + "packet-fixer", "fence-gate-fix", // fun @@ -363,7 +360,7 @@ export const minecraftRengokuService = new ContainerService( // "linkart-refabricated", "rail-destinations", // "audaki-cart-engine", - "express-carts", + "express-carts:nLatRTOc", "move-minecarts", "move-boats", "warping-wonders", @@ -395,7 +392,8 @@ export const minecraftRengokuService = new ContainerService( "faewufs-diversity", // useful - "inventory-sorting", + // "inventory-sorting", + "sort-it-out", // replacement for inventory-sorting cuz it's broken on 1.21.11 (fixed for 26.1) "kleeslabs", // break only half of the slab you're looking at // "villager-death-messages", @@ -421,6 +419,7 @@ export const minecraftRengokuService = new ContainerService( // "enhanced-groups", // "simple-voice-chat-group-msg", "audioplayer", + "sound-physics-remastered", // QoL "a-minor-convenience", @@ -466,7 +465,8 @@ export const minecraftRengokuService = new ContainerService( // "saplanting", "ppetp", "rail-recipe-rebalance", - "command-feedback", + // "command-feedback", // no longer exists. replace with https://modrinth.com/mod/unjank/versions once available for 1.21.11 + "remove-dialog-warning", // decorative/aesthetic // "boids", @@ -489,11 +489,14 @@ export const minecraftRengokuService = new ContainerService( // "better-stats", "skinshuffle", "skinrestorer", + "xaeros-minimap", + "xaeros-world-map", "xaeros-map-server-utils", "do-a-barrel-roll", "wthit", "jade", "servux", + "polymer_patch_for_servux", "inventory-management", "inventory-essentials", "crafting-tweaks", diff --git a/services/haring/games/minecraft/servers/teena.ts b/services/haring/games/minecraft/servers/teena.ts index 81d82a9..efaefcc 100644 --- a/services/haring/games/minecraft/servers/teena.ts +++ b/services/haring/games/minecraft/servers/teena.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { nvmeMount, ssdcacheMount, mount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; const minecraftTeenaService = new ContainerService( "minecraft-teena", diff --git a/services/haring/games/minecraft/util.ts b/services/haring/games/minecraft/util.ts index 153a6ab..a958926 100644 --- a/services/haring/games/minecraft/util.ts +++ b/services/haring/games/minecraft/util.ts @@ -1,4 +1,4 @@ -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; export async function mcHasOnlinePlayers(container: string) { let listPlayersCmd; diff --git a/services/haring/games/minecraft/web.ts b/services/haring/games/minecraft/web.ts index 691dd66..176062a 100644 --- a/services/haring/games/minecraft/web.ts +++ b/services/haring/games/minecraft/web.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; const mcWebService = new ContainerService("mc-web", { image: "caddy", diff --git a/services/haring/games/terraria.ts b/services/haring/games/terraria.ts index cad266b..04da9e9 100644 --- a/services/haring/games/terraria.ts +++ b/services/haring/games/terraria.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { nvmeMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const terrariaService = new ContainerService("terraria", { image: "passivelemon/terraria-docker:terraria-1.4.5", diff --git a/services/haring/index.ts b/services/haring/index.ts index 76eb2a6..fbdafa0 100644 --- a/services/haring/index.ts +++ b/services/haring/index.ts @@ -6,6 +6,7 @@ export * from "./media/plex"; export * from "./media/tautulli"; export * from "./media/sonarr"; export * from "./media/radarr"; +export * from "./media/reclaimerr"; export * from "./media/jackett"; export * from "./media/prowlarr"; export * from "./media/seerr"; @@ -31,6 +32,7 @@ export * from "./monitoring/grafana"; export * from "./monitoring/prometheus"; export * from "./monitoring/scrutiny"; export * from "./monitoring/uptimekuma"; +export * from "./monitoring/victoriametrics"; // export * from "./networking/dnsmasq"; export * from "./networking/tailscale"; @@ -45,7 +47,7 @@ export * from "./downloaders/qbittorrent-exporter"; // export * from "./downloaders/qbittools"; export * from "./downloaders/sabnzbd"; -export * from "./files/filebrowser"; +// export * from "./files/filebrowser"; export * from "./files/filestash"; export * from "./files/h5ai"; // export * from "./files/nextcloud"; @@ -85,6 +87,7 @@ export * from "./remote/sealskin"; export * from "./other/anki"; // export * from "./other/kopia"; export * from "./other/librespeed"; +export * from "./other/ncps"; export * from "./other/pixiv"; export * from "./other/prunemate"; diff --git a/services/haring/media/agregarr.ts b/services/haring/media/agregarr.ts index 71c9828..04ce35c 100644 --- a/services/haring/media/agregarr.ts +++ b/services/haring/media/agregarr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const agregarrService = new ContainerService("agregarr", { image: "agregarr/agregarr", diff --git a/services/haring/media/autobrr.ts b/services/haring/media/autobrr.ts index ef8dd26..c93a0cc 100644 --- a/services/haring/media/autobrr.ts +++ b/services/haring/media/autobrr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const autobrrService = new ContainerService("autobrr", { image: "ghcr.io/autobrr/autobrr", diff --git a/services/haring/media/autolanguages.ts b/services/haring/media/autolanguages.ts index 904d36c..099252e 100644 --- a/services/haring/media/autolanguages.ts +++ b/services/haring/media/autolanguages.ts @@ -1,5 +1,5 @@ import { getEnv } from "~lib/env"; -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; import { plexService } from "./plex"; diff --git a/services/haring/media/bazarr.ts b/services/haring/media/bazarr.ts index b013776..05eee04 100644 --- a/services/haring/media/bazarr.ts +++ b/services/haring/media/bazarr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const bazarrService = new ContainerService("bazarr", { servicePort: 6767, diff --git a/services/haring/media/dashbrr.ts b/services/haring/media/dashbrr.ts index 2795022..91ede48 100644 --- a/services/haring/media/dashbrr.ts +++ b/services/haring/media/dashbrr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const dashbrrService = new ContainerService("dashbrr", { image: "ghcr.io/autobrr/dashbrr", diff --git a/services/haring/media/jackett.ts b/services/haring/media/jackett.ts index 3a242a2..d839874 100644 --- a/services/haring/media/jackett.ts +++ b/services/haring/media/jackett.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const jackettService = new ContainerService("jackett", { servicePort: 9117, diff --git a/services/haring/media/kitana.ts b/services/haring/media/kitana.ts index 7450eeb..027ea28 100644 --- a/services/haring/media/kitana.ts +++ b/services/haring/media/kitana.ts @@ -1,4 +1,4 @@ -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; export const kitanaService = new ContainerService("kitana", { image: "pannal/kitana", diff --git a/services/haring/media/maintainerr.ts b/services/haring/media/maintainerr.ts index 6264723..bc51c44 100644 --- a/services/haring/media/maintainerr.ts +++ b/services/haring/media/maintainerr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const maintainerrService = new ContainerService("maintainerr", { image: "ghcr.io/jorenn92/maintainerr", diff --git a/services/haring/media/medialytics.ts b/services/haring/media/medialytics.ts index 7e01475..1b1c220 100644 --- a/services/haring/media/medialytics.ts +++ b/services/haring/media/medialytics.ts @@ -1,5 +1,5 @@ import { getEnv } from "~lib/env"; -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; import { plexService } from "./plex"; diff --git a/services/haring/media/plex.ts b/services/haring/media/plex.ts index 7f61c6d..1f7dee7 100644 --- a/services/haring/media/plex.ts +++ b/services/haring/media/plex.ts @@ -1,6 +1,6 @@ import { interpolate } from "@pulumi/pulumi"; +import { ContainerService } from "~lib/service"; import { confMount, dataMount, gitMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; import { wireguardProtonService } from "../networking/wireguard"; diff --git a/services/haring/media/plexanibridge.ts b/services/haring/media/plexanibridge.ts index 78ddff9..01768e0 100644 --- a/services/haring/media/plexanibridge.ts +++ b/services/haring/media/plexanibridge.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; import { plexService } from "./plex"; @@ -15,15 +15,19 @@ export const plexAniBridgeService = new ContainerService("plexanibridge", { PAB_PLEX_SECTIONS: JSON.stringify(["TV Anime", "Movies Anime"]), // PAB_PROFILES__1__ANILIST_TOKEN: getEnv("ANILIST_TOKEN_1"), // PAB_PROFILES__1__PLEX_USER: getEnv("PLEX_USER_1"), + // PAB_PROFILES__1__SYNC_MODES: JSON.stringify(["periodic", "webhook"]), PAB_PROFILES__2__ANILIST_TOKEN: getEnv("ANILIST_TOKEN_2"), PAB_PROFILES__2__PLEX_USER: getEnv("PLEX_USER_2"), PAB_PROFILES__2__EXCLUDED_SYNC_FIELDS: JSON.stringify([]), + PAB_PROFILES__2__SYNC_MODES: JSON.stringify(["periodic", "webhook"]), PAB_PROFILES__3__ANILIST_TOKEN: getEnv("ANILIST_TOKEN_3"), PAB_PROFILES__3__PLEX_USER: getEnv("PLEX_USER_3"), PAB_PROFILES__3__EXCLUDED_SYNC_FIELDS: JSON.stringify([]), + PAB_PROFILES__3__SYNC_MODES: JSON.stringify(["periodic", "webhook"]), PAB_PROFILES__4__ANILIST_TOKEN: getEnv("ANILIST_TOKEN_4"), PAB_PROFILES__4__PLEX_USER: getEnv("PLEX_USER_4"), PAB_PROFILES__4__EXCLUDED_SYNC_FIELDS: JSON.stringify([]), + PAB_PROFILES__4__SYNC_MODES: JSON.stringify(["periodic", "webhook"]), }, middlewares: ["auth"], }); diff --git a/services/haring/media/prowlarr.ts b/services/haring/media/prowlarr.ts index 412dc24..c3add89 100644 --- a/services/haring/media/prowlarr.ts +++ b/services/haring/media/prowlarr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const prowlarrService = new ContainerService("prowlarr", { servicePort: 9696, diff --git a/services/haring/media/radarr.ts b/services/haring/media/radarr.ts index 2f3fef4..f1a9060 100644 --- a/services/haring/media/radarr.ts +++ b/services/haring/media/radarr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, dataMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const radarrService = new ContainerService("radarr", { servicePort: 7878, diff --git a/services/haring/media/reclaimerr.ts b/services/haring/media/reclaimerr.ts new file mode 100644 index 0000000..70db12d --- /dev/null +++ b/services/haring/media/reclaimerr.ts @@ -0,0 +1,11 @@ +import { ContainerService } from "~lib/service"; +import { confMount, ssdcacheMount } from "~lib/service/mounts"; + +export const reclaimerrService = new ContainerService("reclaimerr", { + image: "ghcr.io/jessielw/reclaimerr", + servicePort: 8000, + mounts: [confMount("reclaimerr", "/app/data"), ssdcacheMount("plex")], + envs: { + CORS_ORIGINS: "https://reclaimerr.bas.sh", + }, +}); diff --git a/services/haring/media/recyclarr.ts b/services/haring/media/recyclarr.ts index adca712..788df3e 100644 --- a/services/haring/media/recyclarr.ts +++ b/services/haring/media/recyclarr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const recyclarrService = new ContainerService("recyclarr", { image: "recyclarr/recyclarr", diff --git a/services/haring/media/seerr.ts b/services/haring/media/seerr.ts index 3a1d9c5..8340428 100644 --- a/services/haring/media/seerr.ts +++ b/services/haring/media/seerr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const seerrService = new ContainerService("seerr", { image: "ghcr.io/seerr-team/seerr", diff --git a/services/haring/media/sonarr.ts b/services/haring/media/sonarr.ts index 9f6f76b..d75d65f 100644 --- a/services/haring/media/sonarr.ts +++ b/services/haring/media/sonarr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, dataMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const sonarrService = new ContainerService("sonarr", { servicePort: 8989, diff --git a/services/haring/media/spotarr.ts b/services/haring/media/spotarr.ts index da4baff..fd53610 100644 --- a/services/haring/media/spotarr.ts +++ b/services/haring/media/spotarr.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const spottarrService = new ContainerService("spottarr", { image: "ghcr.io/spottarr/spottarr", diff --git a/services/haring/media/spotweb.ts b/services/haring/media/spotweb.ts index c19829b..b8d30bf 100644 --- a/services/haring/media/spotweb.ts +++ b/services/haring/media/spotweb.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const spotwebService = new ContainerService("spotweb", { image: "erikdevries/spotweb", diff --git a/services/haring/media/tautulli.ts b/services/haring/media/tautulli.ts index e903432..944d724 100644 --- a/services/haring/media/tautulli.ts +++ b/services/haring/media/tautulli.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, gitMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const tautulliService = new ContainerService("tautulli", { servicePort: 8181, diff --git a/services/haring/media/tracearr.ts b/services/haring/media/tracearr.ts index aa2e845..47bfacb 100644 --- a/services/haring/media/tracearr.ts +++ b/services/haring/media/tracearr.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; const tracearrService = new ContainerService("tracearr", { image: "ghcr.io/connorgallopo/tracearr:supervised", diff --git a/services/haring/monitoring/beszel.ts b/services/haring/monitoring/beszel.ts index b3a0d2b..3987d7d 100644 --- a/services/haring/monitoring/beszel.ts +++ b/services/haring/monitoring/beszel.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { mount, confMount, dockerSocket } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; const beszelSocket = mount("/var/run/beszel_socket", "/beszel_socket"); diff --git a/services/haring/monitoring/certstream.ts b/services/haring/monitoring/certstream.ts index 1e70154..95bc131 100644 --- a/services/haring/monitoring/certstream.ts +++ b/services/haring/monitoring/certstream.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const certstreamService = new ContainerService("certstream", { image: "ghcr.io/reloading01/certstream-server-rust", diff --git a/services/haring/monitoring/glances.ts b/services/haring/monitoring/glances.ts index b997422..2d4a753 100644 --- a/services/haring/monitoring/glances.ts +++ b/services/haring/monitoring/glances.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { dockerSocket } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const glancesService = new ContainerService("glances", { image: "nicolargo/glances", diff --git a/services/haring/monitoring/grafana.ts b/services/haring/monitoring/grafana.ts index 298354e..8252448 100644 --- a/services/haring/monitoring/grafana.ts +++ b/services/haring/monitoring/grafana.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const grafanaService = new ContainerService("grafana", { image: "grafana/grafana-oss", diff --git a/services/haring/monitoring/netdata.ts b/services/haring/monitoring/netdata.ts index f8996c7..ff710d7 100644 --- a/services/haring/monitoring/netdata.ts +++ b/services/haring/monitoring/netdata.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, mount, dockerSocket } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const netdataService = new ContainerService("netdata", { image: "netdata/netdata", @@ -20,6 +20,6 @@ export const netdataService = new ContainerService("netdata", { dockerSocket, ], capabilities: ["SYS_PTRACE", "SYS_ADMIN"], - securityOpts: ["apparmor:unconfined"], + securityOpts: ["apparmor=unconfined"], networkMode: "host", }); diff --git a/services/haring/monitoring/prometheus.ts b/services/haring/monitoring/prometheus.ts index 5b83088..5dd1178 100644 --- a/services/haring/monitoring/prometheus.ts +++ b/services/haring/monitoring/prometheus.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const prometheusService = new ContainerService("prometheus", { image: "prom/prometheus", diff --git a/services/haring/monitoring/scrutiny.ts b/services/haring/monitoring/scrutiny.ts index 04f181c..7fdca05 100644 --- a/services/haring/monitoring/scrutiny.ts +++ b/services/haring/monitoring/scrutiny.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, mount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const scrutinyService = new ContainerService("scrutiny", { image: "ghcr.io/analogj/scrutiny:master-omnibus", diff --git a/services/haring/monitoring/uptimekuma.ts b/services/haring/monitoring/uptimekuma.ts index 32448f6..2a6b46d 100644 --- a/services/haring/monitoring/uptimekuma.ts +++ b/services/haring/monitoring/uptimekuma.ts @@ -1,13 +1,11 @@ -import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, dockerSocket } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const uptimekumaService = new ContainerService("uptimekuma", { image: "louislam/uptime-kuma:2", servicePort: 3001, subdomain: "status", - mounts: [confMount("uptimekuma", "/app/data")], - middlewares: ["auth"], + mounts: [confMount("uptimekuma", "/app/data"), dockerSocket], }); // export const autokumaService = new ContainerService("autokuma", { diff --git a/services/haring/monitoring/victoriametrics.ts b/services/haring/monitoring/victoriametrics.ts new file mode 100644 index 0000000..a45871e --- /dev/null +++ b/services/haring/monitoring/victoriametrics.ts @@ -0,0 +1,9 @@ +import { ContainerService } from "~lib/service"; +import { confMount } from "~lib/service/mounts"; + +export const victoriametricsService = new ContainerService("victoriametrics", { + image: "victoriametrics/victoria-metrics", + servicePort: 8428, + mounts: [confMount("victoriametrics", "/victoria-metrics-data")], + middlewares: ["auth"], +}); diff --git a/services/haring/networking/dnsmasq.ts b/services/haring/networking/dnsmasq.ts index 076e4af..495e7be 100644 --- a/services/haring/networking/dnsmasq.ts +++ b/services/haring/networking/dnsmasq.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const dnsmasqService = new ContainerService("dnsmasq", { image: "jpillora/dnsmasq", diff --git a/services/haring/networking/tailscale.ts b/services/haring/networking/tailscale.ts index aecfed6..d8273f0 100644 --- a/services/haring/networking/tailscale.ts +++ b/services/haring/networking/tailscale.ts @@ -1,8 +1,8 @@ import { Volume } from "@pulumi/docker"; import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { mount } from "~lib/service/mounts"; import { haringDockerProvider } from "~lib/service/providers"; -import { ContainerService } from "~lib/service/service"; const tailscaleVolume = new Volume( "tailscale", diff --git a/services/haring/networking/tinyproxy.ts b/services/haring/networking/tinyproxy.ts index 5d6c3f2..c867a57 100644 --- a/services/haring/networking/tinyproxy.ts +++ b/services/haring/networking/tinyproxy.ts @@ -1,5 +1,5 @@ import { interpolate } from "@pulumi/pulumi"; -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; import { wireguardProtonService } from "./wireguard"; diff --git a/services/haring/networking/unbound/unbound.ts b/services/haring/networking/unbound/unbound.ts index 646f85c..74a1935 100644 --- a/services/haring/networking/unbound/unbound.ts +++ b/services/haring/networking/unbound/unbound.ts @@ -3,9 +3,9 @@ import path from "path"; import { remote } from "@pulumi/command"; import { asset, ResourceHook } from "@pulumi/pulumi"; +import { ContainerService, defaultConnection } from "~lib/service"; import { confMount } from "~lib/service/mounts"; import { defaultNetwork } from "~lib/service/networks"; -import { ContainerService, defaultConnection } from "~lib/service/service"; import { STATIC_IPS } from "../../ips"; diff --git a/services/haring/networking/wireguard.ts b/services/haring/networking/wireguard.ts index b9ea1c5..b2ba9e5 100644 --- a/services/haring/networking/wireguard.ts +++ b/services/haring/networking/wireguard.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, mount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const wireguardProtonService = new ContainerService("wireguard-proton", { image: "lscr.io/linuxserver/wireguard", diff --git a/services/haring/other/anki.ts b/services/haring/other/anki.ts index f40b209..e3fc761 100644 --- a/services/haring/other/anki.ts +++ b/services/haring/other/anki.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const ankiService = new ContainerService("anki", { image: "ankicommunity/anki-sync-server:latest-develop", diff --git a/services/haring/other/kopia.ts b/services/haring/other/kopia.ts index 2349962..3799b26 100644 --- a/services/haring/other/kopia.ts +++ b/services/haring/other/kopia.ts @@ -1,7 +1,7 @@ import { interpolate } from "@pulumi/pulumi"; import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, dataMount, mount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const kopiaService = new ContainerService("kopia", { image: "kopia/kopia", diff --git a/services/haring/other/librespeed.ts b/services/haring/other/librespeed.ts index a2882ff..46b70f3 100644 --- a/services/haring/other/librespeed.ts +++ b/services/haring/other/librespeed.ts @@ -1,13 +1,10 @@ import { getEnv } from "~lib/env"; -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; export const librespeedService = new ContainerService("librespeed", { image: "ghcr.io/librespeed/speedtest", servicePort: 8080, - subdomain: "speedtest", - otherServicePorts: { - speed: 8080, - }, + hostRule: "Host(`speedtest.bas.sh`) || Host(`speed.bas.sh`)", envs: { TITLE: "Speedtest | Bas", TELEMETRY: true, diff --git a/services/haring/other/ncps.ts b/services/haring/other/ncps.ts new file mode 100644 index 0000000..8a72e5a --- /dev/null +++ b/services/haring/other/ncps.ts @@ -0,0 +1,51 @@ +import { ContainerService } from "~lib/service"; +import { confMount } from "~lib/service/mounts"; + +export const ncpsMigrateDbService = new ContainerService("ncps-migratedb", { + image: "ghcr.io/kalbasit/ncps:sha-ed423d6", + mounts: [confMount("ncps", "/storage"), confMount("ncps/var/ncps/db", "/storage/var/ncps/db")], + command: [ + "/bin/ncps", + "migrate", + "up", + "--cache-database-url=sqlite:/storage/var/ncps/db/db.sqlite", + ], + restart: "no", + attach: true, +}); + +export const ncpsService = new ContainerService( + "ncps", + { + image: "ghcr.io/kalbasit/ncps:sha-ed423d6", + servicePort: 8501, + subdomain: "cache", + mounts: [confMount("ncps", "/storage")], + entrypoints: [ + "/bin/ncps", + "serve", + "--cache-hostname=cache.bas.sh", + "--cache-storage-local=/storage", + "--cache-database-url=sqlite:/storage/var/ncps/db/db.sqlite", + "--cache-upstream-url=https://cache.nixos.org", + "--cache-upstream-url=https://nix-community.cachix.org", + "--cache-upstream-url=https://watersucks.cachix.org", + "--cache-upstream-url=https://nix-gaming.cachix.org", + "--cache-upstream-url=https://cache.numtide.com", + "--cache-upstream-url=https://cache.thalheim.io", + "--cache-upstream-url=https://attic.xuyh0120.win/lantian", + "--cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=", + "--cache-upstream-public-key=nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=", + "--cache-upstream-public-key=cache.lix.systems:aBnZUw8zA7H35Cz2RyKFVs3H4PlGTLawyY5KRbvJR8o=", + "--cache-upstream-public-key=bas.cachix.org-1:LblbDYEqJwBSbBnM4y+uFbBXItBUuvOIYFnr23MYtBk=", + "--cache-upstream-public-key=nixbuild.net/5WVSYG-1:5B/h8LjKqcxNnNU4fYpWPoDjhEffgeVRzi24UIUjhxs=", + "--cache-upstream-public-key=watersucks.cachix.org-1:6gadPC5R8iLWQ3EUtfu3GFrVY7X6I4Fwz/ihW25Jbv8=", + "--cache-upstream-public-key=nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=", + "--cache-upstream-public-key=nix.bas.sh:ufdeOGRzoAuOUJ7kV+A5xkKZ71dB3PgmmOfFjWwL9mI=", + "--cache-upstream-public-key=niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g=", + "--cache-upstream-public-key=cache.thalheim.io-1:R7msbosLEZKrxk/lKxf9BTjOOH7Ax3H0Qj0/6wiHOgc=", + "--cache-upstream-public-key=lantian:EeAUQ+W+6r7EtwnmYjeVwx5kOGEBpjlBfPlzGlTNvHc=", + ], + }, + { dependsOn: [ncpsMigrateDbService] }, +); diff --git a/services/haring/other/pixiv.ts b/services/haring/other/pixiv.ts index a90481b..dcaacf4 100644 --- a/services/haring/other/pixiv.ts +++ b/services/haring/other/pixiv.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const pixivPublicToPrivateService = new ContainerService("pixiv-public-to-private", { image: "ghcr.io/tomacheese/pixiv-public-to-private", diff --git a/services/haring/other/prunemate.ts b/services/haring/other/prunemate.ts index 3335a4b..581a077 100644 --- a/services/haring/other/prunemate.ts +++ b/services/haring/other/prunemate.ts @@ -1,5 +1,5 @@ -import { confMount, dockerSocketRw } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; +import { confMount, dockerSocket } from "~lib/service/mounts"; export const prunemateService = new ContainerService("prunemate", { image: "anoniemerd/prunemate", @@ -7,7 +7,7 @@ export const prunemateService = new ContainerService("prunemate", { mounts: [ confMount("prunemate/logs", "/var/log"), confMount("prunemate/config", "/config"), - dockerSocketRw, + dockerSocket, ], envs: { PRUNEMATE_TZ: "Europe/Amsterdam", diff --git a/services/haring/other/sccache.ts b/services/haring/other/sccache.ts index 78d557e..155194f 100644 --- a/services/haring/other/sccache.ts +++ b/services/haring/other/sccache.ts @@ -3,8 +3,8 @@ import path from "path"; import { Image } from "@pulumi/docker-build"; import { interpolate } from "@pulumi/pulumi"; import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { defaultNetwork } from "~lib/service/networks"; -import { ContainerService } from "~lib/service/service"; import { getLatestGithubTag } from "~lib/util"; import { STATIC_IPS } from "../ips"; diff --git a/services/haring/remote/czkawka.ts b/services/haring/remote/czkawka.ts index e7e3a46..f11c505 100644 --- a/services/haring/remote/czkawka.ts +++ b/services/haring/remote/czkawka.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const czkawkaService = new ContainerService("czkawka", { image: "jlesage/czkawka", diff --git a/services/haring/remote/mkv-muxing-batch.ts b/services/haring/remote/mkv-muxing-batch.ts index 45bf56e..5c75a9f 100644 --- a/services/haring/remote/mkv-muxing-batch.ts +++ b/services/haring/remote/mkv-muxing-batch.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const mkvMuxingBatchService = new ContainerService("mkv-batch", { image: "jlesage/mkv-muxing-batch-gui", diff --git a/services/haring/remote/mkvtoolnix.ts b/services/haring/remote/mkvtoolnix.ts index 317baa1..4af7466 100644 --- a/services/haring/remote/mkvtoolnix.ts +++ b/services/haring/remote/mkvtoolnix.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const mkvtoolnixService = new ContainerService("mkvtoolnix", { image: "jlesage/mkvtoolnix", diff --git a/services/haring/remote/redroid.ts b/services/haring/remote/redroid.ts index eac746c..e8119ef 100644 --- a/services/haring/remote/redroid.ts +++ b/services/haring/remote/redroid.ts @@ -1,5 +1,5 @@ +import { ContainerService } from "~lib/service"; import { confMount, ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; export const redroidService = new ContainerService("redroid", { image: "redroid/redroid:12.0.0_64only-latest", diff --git a/services/haring/remote/sealskin.ts b/services/haring/remote/sealskin.ts index 265b930..89d6150 100644 --- a/services/haring/remote/sealskin.ts +++ b/services/haring/remote/sealskin.ts @@ -1,8 +1,8 @@ -import { confMount, ssdcacheMount, dockerSocketRw } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; +import { confMount, ssdcacheMount, dockerSocket } from "~lib/service/mounts"; export const sealskinService = new ContainerService("sealskin", { ports: [8000, 8443], - mounts: [confMount("sealskin"), ssdcacheMount("sealskin", "/storage"), dockerSocketRw], + mounts: [confMount("sealskin"), ssdcacheMount("sealskin", "/storage"), dockerSocket], networkMode: "bridge", }); diff --git a/services/haring/web/caddy.ts b/services/haring/web/caddy.ts index 40219cf..a2e764f 100644 --- a/services/haring/web/caddy.ts +++ b/services/haring/web/caddy.ts @@ -1,6 +1,6 @@ import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; const SUBDOMAINS = ["get", "static", "files", "f", "i"]; @@ -10,12 +10,14 @@ const CADDYFILE = ` } header X-Robots-Tag "noindex" basic_auth /plex/* { - ${getEnv("CADDY_USERNAME")} ${Buffer.from(getEnv("CADDY_PASSWORD")).toString("base64")} + ${getEnv("CADDY_USERNAME_1")} ${getEnv("CADDY_PASSWORD_1")} + ${getEnv("CADDY_USERNAME_2")} ${getEnv("CADDY_PASSWORD_2")} + ${getEnv("CADDY_USERNAME_3")} ${getEnv("CADDY_PASSWORD_3")} } } `; -export const caddyFileserverService = new ContainerService(`caddy-fileserver`, { +export const caddyFileserverService = new ContainerService("caddy-fileserver", { image: "caddy", servicePort: 80, hostRule: SUBDOMAINS.map((sub) => `Host(\`${sub}.bas.sh\`)`).join(" || "), diff --git a/services/haring/web/dani/dani.ts b/services/haring/web/dani/dani.ts index 40bb0f1..d105afc 100644 --- a/services/haring/web/dani/dani.ts +++ b/services/haring/web/dani/dani.ts @@ -1,11 +1,11 @@ +import { ContainerService } from "~lib/service"; import { ssdcacheMount } from "~lib/service/mounts"; -import { ContainerService } from "~lib/service/service"; const CADDYFILE = ` :80 {} `; -export const caddyFileserverService = new ContainerService(`caddy-dani`, { +export const caddyFileserverService = new ContainerService("caddy-dani", { image: "caddy", servicePort: 80, subdomain: "dani", diff --git a/services/haring/web/traefik.ts b/services/haring/web/traefik.ts index e6f1151..a368619 100644 --- a/services/haring/web/traefik.ts +++ b/services/haring/web/traefik.ts @@ -1,8 +1,8 @@ import { Volume } from "@pulumi/docker"; import { getEnv } from "~lib/env"; +import { ContainerService } from "~lib/service"; import { dockerSocket } from "~lib/service/mounts"; import { haringDockerProvider } from "~lib/service/providers"; -import { ContainerService } from "~lib/service/service"; import { SECRET_ARGS, SECRET_LABELS } from "./traefik-secrets"; @@ -58,8 +58,6 @@ export const traefikService = new ContainerService( "--entrypoints.https.http.tls.domains[0].sans=*.bas.sh,*.tranquil.bas.sh,*.pegasus.bas.sh,*.on.bas.sh,*.t.bas.sh,*.of.bas.sh,*.pds.bas.sh", "--entrypoints.https.http.tls.domains[1].main=danimutiara.nl", "--entrypoints.https.http.tls.domains[1].sans=*.danimutiara.nl", - "--entrypoints.https.http.tls.domains[2].main=vod.watch", - "--entrypoints.https.http.tls.domains[2].sans=*.vod.watch", "--certificatesresolvers.cloudflare.acme.dnschallenge=true", "--certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare", @@ -88,6 +86,9 @@ export const traefikService = new ContainerService( ...SECRET_ARGS, ], labels: { + "traefik.http.routers.traefik.service": "api@internal", + "traefik.http.routers.traefik.middlewares": "cloudflare,auth", + "traefik.http.middlewares.httpsredirect.redirectscheme.scheme": "https", "traefik.http.middlewares.httpsredirect.redirectscheme.permanent": "true", "traefik.http.routers.httpsredirect.rule": "HostRegexp(`.+`)", @@ -116,6 +117,11 @@ export const traefikService = new ContainerService( "traefik.http.routers.atproto-did.entrypoints": "https", "traefik.http.routers.atproto-did.middlewares": "cloudflare,cors,atproto-did", + "traefik.http.middlewares.bsky-user-redirect.redirectregex.regex": + "^https://(.+?)(?:/|(/.+))$", + "traefik.http.middlewares.bsky-user-redirect.redirectregex.replacement": + "https://bsky.app/profile/${1}${2}", + "traefik.http.middlewares.vod.plugin.staticresponse.statuscode": "200", "traefik.http.middlewares.vod.plugin.staticresponse.body": "poggers", "traefik.http.routers.vod.rule": "Host(`vod.watch`)", @@ -124,9 +130,6 @@ export const traefikService = new ContainerService( "traefik.http.middlewares.relay.headers.customrequestheaders.Origin": "", - "traefik.http.routers.traefik-bas-sh.service": "api@internal", - "traefik.http.routers.traefik-bas-sh.middlewares": "cloudflare,auth", - "traefik.http.routers.metrics.service": "prometheus@internal", "traefik.http.routers.metrics.rule": "Host(`metrics.bas.sh`)", "traefik.http.routers.metrics.entrypoints": "https", diff --git a/services/haring/web/whoami.ts b/services/haring/web/whoami.ts index 0691e48..2fb0634 100644 --- a/services/haring/web/whoami.ts +++ b/services/haring/web/whoami.ts @@ -1,4 +1,4 @@ -import { ContainerService } from "~lib/service/service"; +import { ContainerService } from "~lib/service"; export const whoamiService = new ContainerService("whoami", { image: "ghcr.io/traefik/whoami",