From 72a7a4551a708f43f678032993c9bb43205ce1b1 Mon Sep 17 00:00:00 2001 From: Marvin <127591405+Lokowitz@users.noreply.github.com> Date: Wed, 3 Dec 2025 12:46:27 +0100 Subject: [PATCH 01/20] Personal main updates (#480) * Create dev-image.yml * Add test-local target for local testing setup Added test-local target to Makefile for local testing. --- .github/workflows/dev-image.yml | 158 ++++++++++++++++++++++++++++++++ Makefile | 14 +++ 2 files changed, 172 insertions(+) create mode 100644 .github/workflows/dev-image.yml diff --git a/.github/workflows/dev-image.yml b/.github/workflows/dev-image.yml new file mode 100644 index 000000000..a41929660 --- /dev/null +++ b/.github/workflows/dev-image.yml @@ -0,0 +1,158 @@ +name: Create Dev-Image + +on: + pull_request_target: + branches: + - main + - dev + types: + - opened + - synchronize + - reopened + +concurrency: + group: pr-${{ github.event.pull_request.number }} + cancel-in-progress: true + +env: + TAG_URL: https://hub.docker.com/r/${{ vars.DOCKER_HUB_REPO }}/tags + TAG: ${{ vars.DOCKER_HUB_REPO }}:dev-pr${{ github.event.pull_request.number }} + TAG_PG: ${{ vars.DOCKER_HUB_REPO }}:postgresql-dev-pr${{ github.event.pull_request.number }} + +jobs: + build-w: + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + runs-on: ubuntu-latest + environment: build-dev + + steps: + - name: Checkout PR code + uses: actions/checkout@v4 + with: + ref: refs/pull/${{github.event.pull_request.number}}/merge + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Docker image SQLITE + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64 + push: true + tags: ${{ env.TAG }} + build-args: DATABASE=sqlite + cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache + cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache,mode=max + + - name: Build and push Docker image PG + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64 + push: true + tags: ${{ env.TAG_PG }} + build-args: DATABASE=pg + cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg + cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg,mode=max + + - uses: actions/github-script@v8 + with: + script: | + const repoUrl = process.env.TAG_URL; + const tag = process.env.TAG; + const tagPg = process.env.TAG_PG; + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `> [!WARNING] + > This image may contain unchecked and breaking changes. Only use on own risk. + + 👋 Thanks for your PR! + Dev images for this PR are now available on [docker hub](${repoUrl}): + + **SQLITE Image:** + \`\`\` + ${tag} + \`\`\` + + **Postgresql Image:** + \`\`\` + ${tagPg} + \`\`\`` + }) + build-wo: + if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} + runs-on: ubuntu-latest + + steps: + - name: Checkout PR code + uses: actions/checkout@v4 + with: + ref: refs/pull/${{github.event.pull_request.number}}/merge + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Docker image SQLITE + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64 + push: true + tags: ${{ env.TAG }} + build-args: DATABASE=sqlite + cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache + cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache,mode=max + + - name: Build and push Docker image PG + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64 + push: true + tags: ${{ env.TAG_PG }} + build-args: DATABASE=pg + cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg + cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg,mode=max + + - uses: actions/github-script@v8 + with: + script: | + const repoUrl = process.env.TAG_URL; + const tag = process.env.TAG; + const tagPg = process.env.TAG_PG; + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `> [!WARNING] + > This image may contain unchecked and breaking changes. Only use on own risk. + + 👋 Thanks for your PR! + Dev images for this PR are now available on [docker hub](${repoUrl}): + + **SQLITE Image:** + \`\`\` + ${tag} + \`\`\` + + **Postgresql Image:** + \`\`\` + ${tagPg} + \`\`\`` + }) + diff --git a/Makefile b/Makefile index 6c538a477..d690cba3e 100644 --- a/Makefile +++ b/Makefile @@ -91,3 +91,17 @@ test: clean: docker rmi pangolin + +test-local: + cp config/config.example.yml config/config.yml + npm run set:oss + npm run set:sqlite + npm run db:sqlite:generate + npm run db:sqlite:push + - npx tsc --noEmit + - docker build --build-arg DATABASE=pg -t fosrl/pangolin:postgresql-latest . + - docker build --build-arg DATABASE=sqlite -t fosrl/pangolin:latest . + npm run set:saas + - npx tsc --noEmit + - docker build --build-arg DATABASE=pg -t fosrl/pangolin:postgresql-saas-latest . + - docker build --build-arg DATABASE=sqlite -t fosrl/pangolin:saas-latest . From 83875a8e4d98f0b56a29dbb8485331f3379130f0 Mon Sep 17 00:00:00 2001 From: Marvin <127591405+Lokowitz@users.noreply.github.com> Date: Wed, 3 Dec 2025 14:24:29 +0100 Subject: [PATCH 02/20] fix zod error (#481) --- server/private/routers/hybrid.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/private/routers/hybrid.ts b/server/private/routers/hybrid.ts index 89188a1e5..c10f341ad 100644 --- a/server/private/routers/hybrid.ts +++ b/server/private/routers/hybrid.ts @@ -1219,7 +1219,7 @@ hybridRouter.post( ); const geoIpLookupParamsSchema = z.object({ - ip: z.union([z.ipv4(), z.ipv6()]) + ip: z.string().ip() }); hybridRouter.get( "/geoip/:ip", From 21beb8cb866003510b161f5fb61d4e0884a425be Mon Sep 17 00:00:00 2001 From: Marvin <127591405+Lokowitz@users.noreply.github.com> Date: Sun, 25 Jan 2026 21:03:08 +0100 Subject: [PATCH 03/20] Update build args to include BUILD=enterprise --- .github/workflows/dev-image.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dev-image.yml b/.github/workflows/dev-image.yml index a41929660..11ab46ecc 100644 --- a/.github/workflows/dev-image.yml +++ b/.github/workflows/dev-image.yml @@ -47,7 +47,7 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG }} - build-args: DATABASE=sqlite + build-args: DATABASE=sqlite,BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache,mode=max @@ -58,7 +58,7 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG_PG }} - build-args: DATABASE=pg + build-args: DATABASE=pg,BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg,mode=max @@ -114,7 +114,7 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG }} - build-args: DATABASE=sqlite + build-args: DATABASE=sqlite,BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache,mode=max @@ -125,7 +125,7 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG_PG }} - build-args: DATABASE=pg + build-args: DATABASE=pg,BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg,mode=max From c8f265af12f23959e84021d8301e14e47a34869e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 25 Jan 2026 21:03:52 +0100 Subject: [PATCH 04/20] Bump actions/checkout from 4 to 6 (#493) Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Commits](https://github.com/actions/checkout/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dev-image.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dev-image.yml b/.github/workflows/dev-image.yml index 11ab46ecc..c093459c3 100644 --- a/.github/workflows/dev-image.yml +++ b/.github/workflows/dev-image.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Checkout PR code - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: refs/pull/${{github.event.pull_request.number}}/merge @@ -94,7 +94,7 @@ jobs: steps: - name: Checkout PR code - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: refs/pull/${{github.event.pull_request.number}}/merge From e8ac0ddd3ffd77f0b21afbc2c34944336ed0d58a Mon Sep 17 00:00:00 2001 From: Marvin <127591405+Lokowitz@users.noreply.github.com> Date: Mon, 26 Jan 2026 08:05:49 +0100 Subject: [PATCH 05/20] Update hybrid.ts --- server/private/routers/hybrid.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/private/routers/hybrid.ts b/server/private/routers/hybrid.ts index 3e5d76fea..a398dfe68 100644 --- a/server/private/routers/hybrid.ts +++ b/server/private/routers/hybrid.ts @@ -1263,7 +1263,7 @@ hybridRouter.post( ); const geoIpLookupParamsSchema = z.object({ - ip: z.string().ip() + ip: z.union([z.ipv4(), z.ipv6()]) }); hybridRouter.get( "/geoip/:ip", From 593a09ce772bd7240803a26995be74812f02f298 Mon Sep 17 00:00:00 2001 From: Marvin <127591405+Lokowitz@users.noreply.github.com> Date: Mon, 26 Jan 2026 08:41:42 +0100 Subject: [PATCH 06/20] Update dev-image.yml --- .github/workflows/dev-image.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dev-image.yml b/.github/workflows/dev-image.yml index c093459c3..cc70e89e9 100644 --- a/.github/workflows/dev-image.yml +++ b/.github/workflows/dev-image.yml @@ -47,7 +47,7 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG }} - build-args: DATABASE=sqlite,BUILD=enterprise + build-args: DATABASE=sqlite BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache,mode=max @@ -58,7 +58,7 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG_PG }} - build-args: DATABASE=pg,BUILD=enterprise + build-args: DATABASE=pg BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg,mode=max @@ -114,7 +114,7 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG }} - build-args: DATABASE=sqlite,BUILD=enterprise + build-args: DATABASE=sqlite BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache,mode=max @@ -125,7 +125,7 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG_PG }} - build-args: DATABASE=pg,BUILD=enterprise + build-args: DATABASE=pg BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg,mode=max From 3dd6c9bd1e9649f3c7ea3475c557640ec3bebb19 Mon Sep 17 00:00:00 2001 From: Marvin <127591405+Lokowitz@users.noreply.github.com> Date: Mon, 26 Jan 2026 11:18:28 +0100 Subject: [PATCH 07/20] Update dev-image.yml --- .github/workflows/dev-image.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dev-image.yml b/.github/workflows/dev-image.yml index cc70e89e9..48880cb6d 100644 --- a/.github/workflows/dev-image.yml +++ b/.github/workflows/dev-image.yml @@ -47,7 +47,9 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG }} - build-args: DATABASE=sqlite BUILD=enterprise + build-args: | + DATABASE=sqlite + BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache,mode=max @@ -58,7 +60,9 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG_PG }} - build-args: DATABASE=pg BUILD=enterprise + build-args: | + DATABASE=sqlite + BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg,mode=max @@ -114,7 +118,9 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG }} - build-args: DATABASE=sqlite BUILD=enterprise + build-args: | + DATABASE=sqlite + BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache,mode=max @@ -125,7 +131,9 @@ jobs: platforms: linux/amd64 push: true tags: ${{ env.TAG_PG }} - build-args: DATABASE=pg BUILD=enterprise + build-args: | + DATABASE=sqlite + BUILD=enterprise cache-from: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg cache-to: type=registry,ref=${{ vars.DOCKER_HUB_REPO }}:buildcache-pg,mode=max From cb569ff14d02bd07ef30fff57a2aac5772f6b500 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 28 Jan 2026 15:03:31 -0800 Subject: [PATCH 08/20] Properly insert PANGOLIN_SETUP_TOKEN into db Fixes #2361 --- .github/workflows/cicd.yml | 49 ++++++++++++++++++++++++++++++-- server/setup/ensureSetupToken.ts | 22 ++++++++------ 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 715b74c72..0e4d9bc6c 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -504,10 +504,55 @@ jobs: } echo "==> cosign verify (public key) ${REF}" - retry_verify "cosign verify --key env://COSIGN_PUBLIC_KEY '${REF}' -o text" + if retry_verify "cosign verify --key env://COSIGN_PUBLIC_KEY '${REF}' -o text"; then + VERIFIED_INDEX=true + else + VERIFIED_INDEX=false + fi echo "==> cosign verify (keyless policy) ${REF}" - retry_verify "cosign verify --certificate-oidc-issuer '${issuer}' --certificate-identity-regexp '${id_regex}' '${REF}' -o text" + if retry_verify "cosign verify --certificate-oidc-issuer '${issuer}' --certificate-identity-regexp '${id_regex}' '${REF}' -o text"; then + VERIFIED_INDEX_KEYLESS=true + else + VERIFIED_INDEX_KEYLESS=false + fi + + # If index verification fails, attempt to verify child platform manifests + if [ "${VERIFIED_INDEX}" != "true" ] || [ "${VERIFIED_INDEX_KEYLESS}" != "true" ]; then + echo "Index verification not available; attempting child manifest verification for ${BASE_IMAGE}:${IMAGE_TAG}" + CHILD_VERIFIED=false + + for ARCH in arm64 amd64; do + CHILD_TAG="${IMAGE_TAG}-${ARCH}" + echo "Resolving child digest for ${BASE_IMAGE}:${CHILD_TAG}" + CHILD_DIGEST="$(skopeo inspect --retry-times 3 docker://${BASE_IMAGE}:${CHILD_TAG} | jq -r '.Digest' || true)" + if [ -n "${CHILD_DIGEST}" ] && [ "${CHILD_DIGEST}" != "null" ]; then + CHILD_REF="${BASE_IMAGE}@${CHILD_DIGEST}" + echo "==> cosign verify (public key) child ${CHILD_REF}" + if retry_verify "cosign verify --key env://COSIGN_PUBLIC_KEY '${CHILD_REF}' -o text"; then + CHILD_VERIFIED=true + echo "Public key verification succeeded for child ${CHILD_REF}" + else + echo "Public key verification failed for child ${CHILD_REF}" + fi + + echo "==> cosign verify (keyless policy) child ${CHILD_REF}" + if retry_verify "cosign verify --certificate-oidc-issuer '${issuer}' --certificate-identity-regexp '${id_regex}' '${CHILD_REF}' -o text"; then + CHILD_VERIFIED=true + echo "Keyless verification succeeded for child ${CHILD_REF}" + else + echo "Keyless verification failed for child ${CHILD_REF}" + fi + else + echo "No child digest found for ${BASE_IMAGE}:${CHILD_TAG}; skipping" + fi + done + + if [ "${CHILD_VERIFIED}" != "true" ]; then + echo "Failed to verify index and no child manifests verified for ${BASE_IMAGE}:${IMAGE_TAG}" + exit 10 + fi + fi echo "✓ Successfully signed and verified ${BASE_IMAGE}:${IMAGE_TAG}" done diff --git a/server/setup/ensureSetupToken.ts b/server/setup/ensureSetupToken.ts index 5ea9542a6..ff6387f0c 100644 --- a/server/setup/ensureSetupToken.ts +++ b/server/setup/ensureSetupToken.ts @@ -64,16 +64,20 @@ export async function ensureSetupToken() { ); } - if (existingToken?.token !== envSetupToken) { - console.warn( - "Overwriting existing token in DB since PANGOLIN_SETUP_TOKEN is set" - ); - - await db - .update(setupTokens) - .set({ token: envSetupToken }) - .where(eq(setupTokens.tokenId, existingToken.tokenId)); + if (existingToken) { + // Token exists in DB - update it if different + if (existingToken.token !== envSetupToken) { + console.warn( + "Overwriting existing token in DB since PANGOLIN_SETUP_TOKEN is set" + ); + + await db + .update(setupTokens) + .set({ token: envSetupToken }) + .where(eq(setupTokens.tokenId, existingToken.tokenId)); + } } else { + // No existing token - insert new one const tokenId = generateId(15); await db.insert(setupTokens).values({ From 5dda8c384fcd7274d51ebc2f5d4a430d51e4d7ac Mon Sep 17 00:00:00 2001 From: MoweME Date: Thu, 29 Jan 2026 14:28:06 +0100 Subject: [PATCH 09/20] fix(i18n): correct German translation strings Corrects mistranslation of device timestamp labels and fixes product name reference in site tunnel settings. --- messages/de-DE.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/messages/de-DE.json b/messages/de-DE.json index e0c85879d..489519d23 100644 --- a/messages/de-DE.json +++ b/messages/de-DE.json @@ -97,7 +97,7 @@ "siteGeneralDescription": "Allgemeine Einstellungen für diesen Standort konfigurieren", "siteSettingDescription": "Standorteinstellungen konfigurieren", "siteSetting": "{siteName} Einstellungen", - "siteNewtTunnel": "Neuer Standort (empfohlen)", + "siteNewtTunnel": "Newt Standort (empfohlen)", "siteNewtTunnelDescription": "Einfachster Weg, einen Einstiegspunkt in jedes Netzwerk zu erstellen. Keine zusätzliche Einrichtung.", "siteWg": "Einfacher WireGuard Tunnel", "siteWgDescription": "Verwende jeden WireGuard-Client, um einen Tunnel einzurichten. Manuelles NAT-Setup erforderlich.", @@ -2503,7 +2503,7 @@ "deviceModel": "Gerätemodell", "serialNumber": "Seriennummer", "hostname": "Hostname", - "firstSeen": "Erster Blick", + "firstSeen": "Zuerst gesehen", "lastSeen": "Zuletzt gesehen", "biometricsEnabled": "Biometrie aktiviert", "diskEncrypted": "Festplatte verschlüsselt", From b0566d3c6fc0e2a993c8606acc128a68c4e27247 Mon Sep 17 00:00:00 2001 From: MoweME Date: Thu, 29 Jan 2026 14:36:59 +0100 Subject: [PATCH 10/20] fix(i18n): correct German site terminology Updates the German translation to use "Standort" (site) instead of "Seite" (page) for consistency with the site context. --- messages/de-DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/de-DE.json b/messages/de-DE.json index 489519d23..cbf8b4d3f 100644 --- a/messages/de-DE.json +++ b/messages/de-DE.json @@ -107,7 +107,7 @@ "siteSeeAll": "Alle Standorte anzeigen", "siteTunnelDescription": "Legen Sie fest, wie Sie sich mit dem Standort verbinden möchten", "siteNewtCredentials": "Zugangsdaten", - "siteNewtCredentialsDescription": "So wird sich die Seite mit dem Server authentifizieren", + "siteNewtCredentialsDescription": "So wird sich der Standort mit dem Server authentifizieren", "remoteNodeCredentialsDescription": "So wird sich der entfernte Node mit dem Server authentifizieren", "siteCredentialsSave": "Anmeldedaten speichern", "siteCredentialsSaveDescription": "Du kannst das nur einmal sehen. Stelle sicher, dass du es an einen sicheren Ort kopierst.", From 88620abd0aa41bf5a6a141fcd1161c4ade9058a2 Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Sun, 1 Feb 2026 18:47:27 +0000 Subject: [PATCH 11/20] move to dhi --- Dockerfile | 67 +++++++++++++++++++++++++------------------ Dockerfile.bak | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 28 deletions(-) create mode 100644 Dockerfile.bak diff --git a/Dockerfile b/Dockerfile index 487fa0336..4620c47af 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,67 +1,75 @@ -FROM node:24-alpine AS builder +FROM dhi.io/node:24-alpine3.23-dev AS builder WORKDIR /app ARG BUILD=oss ARG DATABASE=sqlite -RUN apk add --no-cache python3 make g++ +# Install build dependencies +RUN apk add --no-cache \ + g++ \ + make \ + python3 -# COPY package.json package-lock.json ./ +# Copy dependency files first for better caching COPY package*.json ./ RUN npm ci +# Copy source files COPY . . +# Build application RUN if [ "$BUILD" = "oss" ]; then rm -rf server/private; fi && \ npm run set:$DATABASE && \ npm run set:$BUILD && \ npm run db:$DATABASE:generate && \ npm run build:$DATABASE && \ - npm run build:cli + npm run build:cli && \ + test -f dist/server.mjs -# test to make sure the build output is there and error if not -RUN test -f dist/server.mjs +FROM dhi.io/node:24-alpine3.23-dev AS runner -# Prune dev dependencies and clean up to prepare for copy to runner -RUN npm prune --omit=dev && npm cache clean --force +# Install runtime dependencies and install production node_modules +RUN apk add --no-cache \ + g++ \ + make \ + python3 \ + tzdata -FROM node:24-alpine AS runner +COPY package*.json ./ +RUN npm ci --omit=dev && \ + npm cache clean --force + +FROM dhi.io/node:24-alpine3.23 # OCI Image Labels - Build Args for dynamic values ARG VERSION="dev" ARG REVISION="" ARG CREATED="" ARG LICENSE="AGPL-3.0" - -# Derive title and description based on BUILD type ARG IMAGE_TITLE="Pangolin" ARG IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" WORKDIR /app -# Only curl and tzdata needed at runtime - no build tools! -RUN apk add --no-cache curl tzdata +# Copy package.json +COPY --chown=node:node package.json ./ -# Copy pre-built node_modules from builder (already pruned to production only) -# This includes the compiled native modules like better-sqlite3 -COPY --from=builder /app/node_modules ./node_modules -COPY --from=builder /app/.next/standalone ./ -COPY --from=builder /app/.next/static ./.next/static -COPY --from=builder /app/dist ./dist -COPY --from=builder /app/server/migrations ./dist/init -COPY --from=builder /app/package.json ./package.json +# Copy pre-built node_modules and timezone data from runner stage +COPY --from=runner /app/node_modules ./node_modules +COPY --from=runner /usr/share/zoneinfo /usr/share/zoneinfo -COPY ./cli/wrapper.sh /usr/local/bin/pangctl -RUN chmod +x /usr/local/bin/pangctl ./dist/cli.mjs +# Copy built artifacts from builder stage +COPY --chown=node:node --from=builder /app/.next/standalone ./ +COPY --chown=node:node --from=builder /app/.next/static ./.next/static +COPY --chown=node:node --from=builder /app/dist ./dist +COPY --chown=node:node --from=builder /app/server/migrations ./dist/init -COPY server/db/names.json ./dist/names.json -COPY server/db/ios_models.json ./dist/ios_models.json -COPY server/db/mac_models.json ./dist/mac_models.json -COPY public ./public +COPY --chown=node:node ./cli/wrapper.sh /usr/local/bin/pangctl +COPY --chown=node:node server/db/names.json server/db/*_models.json ./dist/ +COPY --chown=node:node public ./public # OCI Image Labels -# https://github.com/opencontainers/image-spec/blob/main/annotations.md LABEL org.opencontainers.image.source="https://github.com/fosrl/pangolin" \ org.opencontainers.image.url="https://github.com/fosrl/pangolin" \ org.opencontainers.image.documentation="https://docs.pangolin.net" \ @@ -73,4 +81,7 @@ LABEL org.opencontainers.image.source="https://github.com/fosrl/pangolin" \ org.opencontainers.image.revision="${REVISION}" \ org.opencontainers.image.created="${CREATED}" +# Run as non-root user +USER node + CMD ["npm", "run", "start"] diff --git a/Dockerfile.bak b/Dockerfile.bak new file mode 100644 index 000000000..17cf3ae14 --- /dev/null +++ b/Dockerfile.bak @@ -0,0 +1,77 @@ +FROM dhi.io/node:24-alpine3.23-dev AS builder + +WORKDIR /app + +ARG BUILD=oss +ARG DATABASE=sqlite + +RUN apk add --no-cache python3 make g++ + +# COPY package.json package-lock.json ./ +COPY package*.json ./ +RUN npm ci + +COPY . . + +RUN if [ "$BUILD" = "oss" ]; then rm -rf server/private; fi && \ + npm run set:$DATABASE && \ + npm run set:$BUILD && \ + npm run db:$DATABASE:generate && \ + npm run build:$DATABASE && \ + npm run build:cli + +# test to make sure the build output is there and error if not +RUN test -f dist/server.mjs + +FROM dhi.io/node:24-alpine3.23-dev AS runner + +RUN apk add --no-cache python3 make g++ tzdata + +COPY package*.json ./ +RUN npm ci --omit=dev && npm cache clean --force + +FROM dhi.io/node:24-alpine3.23 + +# OCI Image Labels - Build Args for dynamic values +ARG VERSION="dev" +ARG REVISION="" +ARG CREATED="" +ARG LICENSE="AGPL-3.0" + +# Derive title and description based on BUILD type +ARG IMAGE_TITLE="Pangolin" +ARG IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" + +WORKDIR /app + +COPY --chown=node:node package.json ./ + +# Copy pre-built node_modules from builder (already pruned to production only) +# This includes the compiled native modules like better-sqlite3 +COPY --from=runner /app/node_modules ./node_modules +COPY --from=runner /usr/share/zoneinfo /usr/share/zoneinfo + +COPY --chown=node:node --from=builder /app/.next/standalone ./ +COPY --chown=node:node --from=builder /app/.next/static ./.next/static +COPY --chown=node:node --from=builder --chmod=+x /app/dist ./dist +COPY --chown=node:node --from=builder /app/server/migrations ./dist/init + +COPY --chown=node:node --chmod=+x ./cli/wrapper.sh /usr/local/bin/pangctl + +COPY --chown=node:node server/db/names.json server/db/*_models.json ./dist/ +COPY --chown=node:node public ./public + +# OCI Image Labels +# https://github.com/opencontainers/image-spec/blob/main/annotations.md +LABEL org.opencontainers.image.source="https://github.com/fosrl/pangolin" \ + org.opencontainers.image.url="https://github.com/fosrl/pangolin" \ + org.opencontainers.image.documentation="https://docs.pangolin.net" \ + org.opencontainers.image.vendor="Fossorial" \ + org.opencontainers.image.licenses="${LICENSE}" \ + org.opencontainers.image.title="${IMAGE_TITLE}" \ + org.opencontainers.image.description="${IMAGE_DESCRIPTION}" \ + org.opencontainers.image.version="${VERSION}" \ + org.opencontainers.image.revision="${REVISION}" \ + org.opencontainers.image.created="${CREATED}" + +CMD ["npm", "run", "start"] From 38c3beda823ab21630b79e1b8fc128c5b63d4abf Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Sun, 1 Feb 2026 19:13:34 +0000 Subject: [PATCH 12/20] add entrypoint --- Dockerfile | 8 +++++++- entrypoint.sh | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 4620c47af..3e78fa3c5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,8 @@ RUN if [ "$BUILD" = "oss" ]; then rm -rf server/private; fi && \ FROM dhi.io/node:24-alpine3.23-dev AS runner +WORKDIR /app + # Install runtime dependencies and install production node_modules RUN apk add --no-cache \ g++ \ @@ -50,6 +52,9 @@ ARG LICENSE="AGPL-3.0" ARG IMAGE_TITLE="Pangolin" ARG IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" +ENV ENVIRONMENT=prod +ENV NODE_ENV=development + WORKDIR /app # Copy package.json @@ -68,6 +73,7 @@ COPY --chown=node:node --from=builder /app/server/migrations ./dist/init COPY --chown=node:node ./cli/wrapper.sh /usr/local/bin/pangctl COPY --chown=node:node server/db/names.json server/db/*_models.json ./dist/ COPY --chown=node:node public ./public +COPY --chown=node:node entrypoint.sh /entrypoint.sh # OCI Image Labels LABEL org.opencontainers.image.source="https://github.com/fosrl/pangolin" \ @@ -84,4 +90,4 @@ LABEL org.opencontainers.image.source="https://github.com/fosrl/pangolin" \ # Run as non-root user USER node -CMD ["npm", "run", "start"] +ENTRYPOINT ["/entrypoint.sh"] diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 000000000..5b637596e --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/sh +set -e + +node dist/migrations.mjs +exec node --enable-source-maps dist/server.mjs From 2ce8592818ecaab6725409ce123b492702c25dc6 Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Sun, 1 Feb 2026 19:22:33 +0000 Subject: [PATCH 13/20] make executable --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3e78fa3c5..e653018e0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -70,10 +70,10 @@ COPY --chown=node:node --from=builder /app/.next/static ./.next/static COPY --chown=node:node --from=builder /app/dist ./dist COPY --chown=node:node --from=builder /app/server/migrations ./dist/init -COPY --chown=node:node ./cli/wrapper.sh /usr/local/bin/pangctl +COPY --chown=node:node --chmod=+x ./cli/wrapper.sh /usr/local/bin/pangctl COPY --chown=node:node server/db/names.json server/db/*_models.json ./dist/ COPY --chown=node:node public ./public -COPY --chown=node:node entrypoint.sh /entrypoint.sh +COPY --chown=node:node --chmod=+x entrypoint.sh /entrypoint.sh # OCI Image Labels LABEL org.opencontainers.image.source="https://github.com/fosrl/pangolin" \ From 825bb16ac0bf99df2f3bacfa1a93d35c7b58a19a Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Sun, 1 Feb 2026 19:58:43 +0000 Subject: [PATCH 14/20] fix entrypoint --- Dockerfile | 7 ++---- Dockerfile.bak | 8 ++----- entrypoint.mjs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ entrypoint.sh | 5 ----- 4 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 entrypoint.mjs delete mode 100644 entrypoint.sh diff --git a/Dockerfile b/Dockerfile index e653018e0..2fab80f35 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,9 +57,6 @@ ENV NODE_ENV=development WORKDIR /app -# Copy package.json -COPY --chown=node:node package.json ./ - # Copy pre-built node_modules and timezone data from runner stage COPY --from=runner /app/node_modules ./node_modules COPY --from=runner /usr/share/zoneinfo /usr/share/zoneinfo @@ -73,7 +70,7 @@ COPY --chown=node:node --from=builder /app/server/migrations ./dist/init COPY --chown=node:node --chmod=+x ./cli/wrapper.sh /usr/local/bin/pangctl COPY --chown=node:node server/db/names.json server/db/*_models.json ./dist/ COPY --chown=node:node public ./public -COPY --chown=node:node --chmod=+x entrypoint.sh /entrypoint.sh +COPY --chown=node:node --chmod=+x entrypoint.mjs /entrypoint.mjs # OCI Image Labels LABEL org.opencontainers.image.source="https://github.com/fosrl/pangolin" \ @@ -90,4 +87,4 @@ LABEL org.opencontainers.image.source="https://github.com/fosrl/pangolin" \ # Run as non-root user USER node -ENTRYPOINT ["/entrypoint.sh"] +ENTRYPOINT ["node", "/entrypoint.mjs"] diff --git a/Dockerfile.bak b/Dockerfile.bak index 17cf3ae14..219ef95b4 100644 --- a/Dockerfile.bak +++ b/Dockerfile.bak @@ -18,10 +18,8 @@ RUN if [ "$BUILD" = "oss" ]; then rm -rf server/private; fi && \ npm run set:$BUILD && \ npm run db:$DATABASE:generate && \ npm run build:$DATABASE && \ - npm run build:cli - -# test to make sure the build output is there and error if not -RUN test -f dist/server.mjs + npm run build:cli && \ + test -f dist/server.mjs FROM dhi.io/node:24-alpine3.23-dev AS runner @@ -44,8 +42,6 @@ ARG IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anythin WORKDIR /app -COPY --chown=node:node package.json ./ - # Copy pre-built node_modules from builder (already pruned to production only) # This includes the compiled native modules like better-sqlite3 COPY --from=runner /app/node_modules ./node_modules diff --git a/entrypoint.mjs b/entrypoint.mjs new file mode 100644 index 000000000..5abdce683 --- /dev/null +++ b/entrypoint.mjs @@ -0,0 +1,61 @@ +import { spawn } from 'child_process'; + +// Set environment variables for the application +process.env.ENVIRONMENT = 'prod'; +process.env.NODE_ENV = 'development'; + +async function runMigrations() { + return new Promise((resolve, reject) => { + console.log('Running migrations...'); + const migrations = spawn('node', ['/app/dist/migrations.mjs']); + + migrations.on('exit', (code) => { + if (code === 0) { + console.log('Migrations completed successfully'); + resolve(); + } else { + console.error(`Migrations failed with exit code ${code}`); + reject(new Error(`Migrations exited with code ${code}`)); + } + }); + + migrations.on('error', (err) => { + console.error(`Failed to start migrations: ${err}`); + reject(err); + }); + }); +} + +async function startServer() { + return new Promise((resolve, reject) => { + console.log('Starting server with source maps enabled...'); + const server = spawn('node', ['--enable-source-maps', '/app/dist/server.mjs'], { + stdio: 'inherit' + }); + + server.on('exit', (code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`Server exited with code ${code}`)); + } + }); + + server.on('error', (err) => { + console.error(`Failed to start server: ${err}`); + reject(err); + }); + }); +} + +async function main() { + try { + await runMigrations(); + await startServer(); + } catch (error) { + console.error('Fatal error:', error.message); + process.exit(1); + } +} + +main(); \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100644 index 5b637596e..000000000 --- a/entrypoint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -set -e - -node dist/migrations.mjs -exec node --enable-source-maps dist/server.mjs From 51569ff5286b29d9cf8a021a8c2db696c07bdb07 Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Sun, 1 Feb 2026 20:36:11 +0000 Subject: [PATCH 15/20] added healthcheck --- Dockerfile | 1 + healthcheck.mjs | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 healthcheck.mjs diff --git a/Dockerfile b/Dockerfile index 2fab80f35..30c63f507 100644 --- a/Dockerfile +++ b/Dockerfile @@ -71,6 +71,7 @@ COPY --chown=node:node --chmod=+x ./cli/wrapper.sh /usr/local/bin/pangctl COPY --chown=node:node server/db/names.json server/db/*_models.json ./dist/ COPY --chown=node:node public ./public COPY --chown=node:node --chmod=+x entrypoint.mjs /entrypoint.mjs +COPY --chown=node:node --chmod=+x healthcheck.mjs /healthcheck.mjs # OCI Image Labels LABEL org.opencontainers.image.source="https://github.com/fosrl/pangolin" \ diff --git a/healthcheck.mjs b/healthcheck.mjs new file mode 100644 index 000000000..7f97d14fa --- /dev/null +++ b/healthcheck.mjs @@ -0,0 +1,5 @@ +import http from 'http'; +const req = http.get('http://localhost:3001/api/v1/', (res) => { + process.exit(res.statusCode === 200 ? 0 : 1); +}); +req.on('error', () => process.exit(1)); From 0bc314330ce07cd450cf72dad5210a7b5a15d0ad Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Sun, 1 Feb 2026 20:50:12 +0000 Subject: [PATCH 16/20] try --- Dockerfile | 3 --- entrypoint.mjs | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 30c63f507..d6ad8dd4c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,9 +52,6 @@ ARG LICENSE="AGPL-3.0" ARG IMAGE_TITLE="Pangolin" ARG IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" -ENV ENVIRONMENT=prod -ENV NODE_ENV=development - WORKDIR /app # Copy pre-built node_modules and timezone data from runner stage diff --git a/entrypoint.mjs b/entrypoint.mjs index 5abdce683..63ac84683 100644 --- a/entrypoint.mjs +++ b/entrypoint.mjs @@ -2,7 +2,6 @@ import { spawn } from 'child_process'; // Set environment variables for the application process.env.ENVIRONMENT = 'prod'; -process.env.NODE_ENV = 'development'; async function runMigrations() { return new Promise((resolve, reject) => { @@ -26,6 +25,8 @@ async function runMigrations() { }); } +process.env.NODE_ENV = 'development'; + async function startServer() { return new Promise((resolve, reject) => { console.log('Starting server with source maps enabled...'); From 4aed48e5df33454f36d90521f232829c64c168f7 Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Mon, 2 Feb 2026 09:45:50 +0000 Subject: [PATCH 17/20] update --- .dockerignore | 3 ++- .github/workflows/test.yml | 12 +++--------- .gitignore | 3 ++- Dockerfile | 4 ++-- esbuild.mjs | 10 ++++++++++ package.json | 20 ++++++++------------ 6 files changed, 27 insertions(+), 25 deletions(-) diff --git a/.dockerignore b/.dockerignore index ecd919cd5..efac14f5e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -31,4 +31,5 @@ dist migrations/ config/ build.ts -tsconfig.json \ No newline at end of file +tsconfig.json +drizzle.config.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 58b4662ce..3bb232a4d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,7 @@ jobs: - name: Install Node uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: - node-version: '22' + node-version: '24' - name: Copy config file run: cp config/config.example.yml config/config.yml @@ -34,10 +34,10 @@ jobs: run: npm run set:oss - name: Generate database migrations - run: npm run db:sqlite:generate + run: npm run db:generate - name: Apply database migrations - run: npm run db:sqlite:push + run: npm run db:sqlite - name: Test with tsc run: npx tsc --noEmit @@ -64,9 +64,6 @@ jobs: - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - name: Copy config file - run: cp config/config.example.yml config/config.yml - - name: Build Docker image sqlite run: make dev-build-sqlite @@ -76,8 +73,5 @@ jobs: - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - name: Copy config file - run: cp config/config.example.yml config/config.yml - - name: Build Docker image pg run: make dev-build-pg diff --git a/.gitignore b/.gitignore index df9179a43..1067dc2ce 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,5 @@ dynamic/ scratch/ tsconfig.json hydrateSaas.ts -CLAUDE.md \ No newline at end of file +CLAUDE.md +drizzle.config.ts diff --git a/Dockerfile b/Dockerfile index d6ad8dd4c..215884e48 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,8 +22,8 @@ COPY . . RUN if [ "$BUILD" = "oss" ]; then rm -rf server/private; fi && \ npm run set:$DATABASE && \ npm run set:$BUILD && \ - npm run db:$DATABASE:generate && \ - npm run build:$DATABASE && \ + npm run db:generate && \ + npm run build && \ npm run build:cli && \ test -f dist/server.mjs diff --git a/esbuild.mjs b/esbuild.mjs index 0157c34ac..5cbc8a790 100644 --- a/esbuild.mjs +++ b/esbuild.mjs @@ -6,6 +6,16 @@ import path from "path"; import fs from "fs"; // import { glob } from "glob"; +// Read default build type from server/build.ts (TypeScript file won't import under ESM) +let build = "oss"; +try { + const buildFile = fs.readFileSync(path.resolve("server/build.ts"), "utf8"); + const m = buildFile.match(/export\s+const\s+build\s*=\s*["'](oss|saas|enterprise)["']/); + if (m) build = m[1]; +} catch (err) { + // fallback to "oss" if file missing or unreadable +} + const banner = ` // patch __dirname // import { fileURLToPath } from "url"; diff --git a/package.json b/package.json index 70c9ab321..18c7fca22 100644 --- a/package.json +++ b/package.json @@ -13,22 +13,18 @@ "scripts": { "dev": "NODE_ENV=development ENVIRONMENT=dev tsx watch server/index.ts", "dev:check": "npx tsc --noEmit && npm run format:check", - "dev:setup": "cp config/config.example.yml config/config.yml && npm run set:oss && npm run set:sqlite && npm run db:sqlite:generate && npm run db:sqlite:push", - "db:pg:generate": "drizzle-kit generate --config=./drizzle.pg.config.ts", - "db:sqlite:generate": "drizzle-kit generate --config=./drizzle.sqlite.config.ts", - "db:pg:push": "npx tsx server/db/pg/migrate.ts", - "db:sqlite:push": "npx tsx server/db/sqlite/migrate.ts", - "db:sqlite:studio": "drizzle-kit studio --config=./drizzle.sqlite.config.ts", - "db:pg:studio": "drizzle-kit studio --config=./drizzle.pg.config.ts", + "dev:setup": "cp config/config.example.yml config/config.yml && npm run set:oss && npm run set:sqlite && npm run db:sqlite", + "db:pg": "drizzle-kit generate --config=./drizzle.config.ts && npx tsx server/db/pg/migrate.ts", + "db:sqlite": "drizzle-kit generate --config=./drizzle.config.ts && npx tsx server/db/sqlite/migrate.ts", + "db:studio": "drizzle-kit studio --config=./drizzle.config.ts", "db:clear-migrations": "rm -rf server/migrations", "set:oss": "echo 'export const build = \"oss\" as \"saas\" | \"enterprise\" | \"oss\";' > server/build.ts && cp tsconfig.oss.json tsconfig.json", "set:saas": "echo 'export const build = \"saas\" as \"saas\" | \"enterprise\" | \"oss\";' > server/build.ts && cp tsconfig.saas.json tsconfig.json", "set:enterprise": "echo 'export const build = \"enterprise\" as \"saas\" | \"enterprise\" | \"oss\";' > server/build.ts && cp tsconfig.enterprise.json tsconfig.json", - "set:sqlite": "echo 'export * from \"./sqlite\";\nexport const driver: \"pg\" | \"sqlite\" = \"sqlite\";' > server/db/index.ts", - "set:pg": "echo 'export * from \"./pg\";\nexport const driver: \"pg\" | \"sqlite\" = \"pg\";' > server/db/index.ts", - "build:next": "next build", - "build:sqlite": "mkdir -p dist && next build && node esbuild.mjs -e server/index.ts -o dist/server.mjs && node esbuild.mjs -e server/setup/migrationsSqlite.ts -o dist/migrations.mjs", - "build:pg": "mkdir -p dist && next build && node esbuild.mjs -e server/index.ts -o dist/server.mjs && node esbuild.mjs -e server/setup/migrationsPg.ts -o dist/migrations.mjs", + "set:sqlite": "echo 'export * from \"./sqlite\";\nexport const driver: \"pg\" | \"sqlite\" = \"sqlite\";' > server/db/index.ts && cp drizzle.sqlite.config.ts drizzle.config.ts && cp server/setup/migrationsSqlite.ts server/setup/migrations.ts", + "set:pg": "echo 'export * from \"./pg\";\nexport const driver: \"pg\" | \"sqlite\" = \"pg\";' > server/db/index.ts && cp drizzle.pg.config.ts drizzle.config.ts && cp server/setup/migrationsPg.ts server/setup/migrations.ts", + "next:build": "next build", + "build": "mkdir -p dist && next build && node esbuild.mjs -e server/index.ts -o dist/server.mjs && node esbuild.mjs -e server/setup/migrations.ts -o dist/migrations.mjs", "start": "ENVIRONMENT=prod node dist/migrations.mjs && ENVIRONMENT=prod NODE_ENV=development node --enable-source-maps dist/server.mjs", "email": "email dev --dir server/emails/templates --port 3005", "build:cli": "node esbuild.mjs -e cli/index.ts -o dist/cli.mjs", From 7e637407609b9a36d79519d7d0847ead6dc6fa85 Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Mon, 2 Feb 2026 10:02:47 +0000 Subject: [PATCH 18/20] update --- esbuild.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esbuild.mjs b/esbuild.mjs index 5cbc8a790..f72ee13dd 100644 --- a/esbuild.mjs +++ b/esbuild.mjs @@ -47,7 +47,7 @@ const argv = yargs(hideBin(process.argv)) describe: "Build type (oss, saas, enterprise)", type: "string", choices: ["oss", "saas", "enterprise"], - default: "oss" + default: build }) .help() .alias("help", "h").argv; From 842b54539738f0eca2d6ea54c90c2d736ca18241 Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Mon, 2 Feb 2026 10:19:59 +0000 Subject: [PATCH 19/20] fix build --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 18c7fca22..87b2aefde 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,9 @@ "dev": "NODE_ENV=development ENVIRONMENT=dev tsx watch server/index.ts", "dev:check": "npx tsc --noEmit && npm run format:check", "dev:setup": "cp config/config.example.yml config/config.yml && npm run set:oss && npm run set:sqlite && npm run db:sqlite", - "db:pg": "drizzle-kit generate --config=./drizzle.config.ts && npx tsx server/db/pg/migrate.ts", - "db:sqlite": "drizzle-kit generate --config=./drizzle.config.ts && npx tsx server/db/sqlite/migrate.ts", + "db:generate": "drizzle-kit generate --config=./drizzle.config.ts", + "db:pg": "npx tsx server/db/pg/migrate.ts", + "db:sqlite": "npx tsx server/db/sqlite/migrate.ts", "db:studio": "drizzle-kit studio --config=./drizzle.config.ts", "db:clear-migrations": "rm -rf server/migrations", "set:oss": "echo 'export const build = \"oss\" as \"saas\" | \"enterprise\" | \"oss\";' > server/build.ts && cp tsconfig.oss.json tsconfig.json", From 3f076bfbaccd9d4a399a2cd7f73701188ed9019c Mon Sep 17 00:00:00 2001 From: Lokowitz Date: Mon, 2 Feb 2026 10:24:14 +0000 Subject: [PATCH 20/20] update node --- esbuild.mjs | 2 +- package.json | 2 +- tsconfig.enterprise.json | 2 +- tsconfig.oss.json | 2 +- tsconfig.saas.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/esbuild.mjs b/esbuild.mjs index f72ee13dd..ce613bd96 100644 --- a/esbuild.mjs +++ b/esbuild.mjs @@ -285,7 +285,7 @@ esbuild }) ], sourcemap: "inline", - target: "node22" + target: "node24" }) .then((result) => { // Check if there were any errors in the build result diff --git a/package.json b/package.json index 87b2aefde..2458616cb 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "scripts": { "dev": "NODE_ENV=development ENVIRONMENT=dev tsx watch server/index.ts", "dev:check": "npx tsc --noEmit && npm run format:check", - "dev:setup": "cp config/config.example.yml config/config.yml && npm run set:oss && npm run set:sqlite && npm run db:sqlite", + "dev:setup": "cp config/config.example.yml config/config.yml && npm run set:oss && npm run set:sqlite && npm run db:generate && npm run db:sqlite", "db:generate": "drizzle-kit generate --config=./drizzle.config.ts", "db:pg": "npx tsx server/db/pg/migrate.ts", "db:sqlite": "npx tsx server/db/sqlite/migrate.ts", diff --git a/tsconfig.enterprise.json b/tsconfig.enterprise.json index 0b856fe08..60ed7c09b 100644 --- a/tsconfig.enterprise.json +++ b/tsconfig.enterprise.json @@ -29,7 +29,7 @@ "name": "next" } ], - "target": "ES2022" + "target": "ES2024" }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"] diff --git a/tsconfig.oss.json b/tsconfig.oss.json index e32eabd3b..f2157b29c 100644 --- a/tsconfig.oss.json +++ b/tsconfig.oss.json @@ -29,7 +29,7 @@ "name": "next" } ], - "target": "ES2022" + "target": "ES2024" }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"] diff --git a/tsconfig.saas.json b/tsconfig.saas.json index 0b856fe08..60ed7c09b 100644 --- a/tsconfig.saas.json +++ b/tsconfig.saas.json @@ -29,7 +29,7 @@ "name": "next" } ], - "target": "ES2022" + "target": "ES2024" }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"]