From d589b945805a0b8edd0fe740b3aa50a9f6117c2d Mon Sep 17 00:00:00 2001 From: Sean O'Connor Date: Wed, 1 Jul 2026 14:43:20 -0400 Subject: [PATCH] Make CRON_SECRET optional; fix docker env validation failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CRON_SECRET was required (min 32 chars) in production by env.js, but neither docker-compose.yml nor docker-compose.coolify.yml passed it through. Since the release container isn't covered by SKIP_ENV_VALIDATION (build-stage only), bun run start failed env validation on every docker deploy unless CRON_SECRET was manually configured — even though it only gates the optional recurring-invoice cron endpoint, which already handles being unset gracefully. Co-Authored-By: Claude Sonnet 5 --- docker-compose.coolify.yml | 1 + docker-compose.yml | 1 + src/env.js | 8 ++++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docker-compose.coolify.yml b/docker-compose.coolify.yml index f35b0f5..1e2e942 100644 --- a/docker-compose.coolify.yml +++ b/docker-compose.coolify.yml @@ -32,6 +32,7 @@ services: NEXT_PUBLIC_UMAMI_SCRIPT_URL: ${NEXT_PUBLIC_UMAMI_SCRIPT_URL:-https://analytics.umami.is/script.js} NEXT_PUBLIC_AUTHENTIK_ENABLED: ${NEXT_PUBLIC_AUTHENTIK_ENABLED:-false} DISABLE_SIGNUPS: ${DISABLE_SIGNUPS:-true} + CRON_SECRET: ${CRON_SECRET:-} AUTHENTIK_ISSUER: ${AUTHENTIK_ISSUER:-} AUTHENTIK_CLIENT_ID: ${AUTHENTIK_CLIENT_ID:-} AUTHENTIK_CLIENT_SECRET: ${AUTHENTIK_CLIENT_SECRET:-} diff --git a/docker-compose.yml b/docker-compose.yml index 874e085..a28a5be 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -31,6 +31,7 @@ services: NEXT_PUBLIC_UMAMI_SCRIPT_URL: ${NEXT_PUBLIC_UMAMI_SCRIPT_URL:-https://analytics.umami.is/script.js} NEXT_PUBLIC_AUTHENTIK_ENABLED: ${NEXT_PUBLIC_AUTHENTIK_ENABLED:-false} DISABLE_SIGNUPS: ${DISABLE_SIGNUPS:-true} + CRON_SECRET: ${CRON_SECRET:-} AUTHENTIK_ISSUER: ${AUTHENTIK_ISSUER:-} AUTHENTIK_CLIENT_ID: ${AUTHENTIK_CLIENT_ID:-} AUTHENTIK_CLIENT_SECRET: ${AUTHENTIK_CLIENT_SECRET:-} diff --git a/src/env.js b/src/env.js index 90b6546..df6c726 100644 --- a/src/env.js +++ b/src/env.js @@ -34,10 +34,10 @@ export const env = createEnv({ .default("development"), DB_DISABLE_SSL: optionalEnvBoolean(), DISABLE_SIGNUPS: optionalEnvBoolean().default(true), - CRON_SECRET: - process.env.NODE_ENV === "production" - ? z.string().min(32) - : z.string().optional(), + // Optional — only gates POST /api/cron/generate-recurring; the route itself + // returns a clean error when unset, so deployments that don't use recurring + // invoices don't need to configure it. + CRON_SECRET: z.string().min(32).optional(), // S3-compatible object storage (optional — local .data/receipts/ fallback when unset) S3_ENDPOINT: z.string().url().optional(), S3_BUCKET: z.string().optional(),