79405709

Date: 2025-02-01 21:34:09
Score: 0.5
Natty:
Report link

Well thank you to everybody who answered! In the end I came up with a dirty but efficient solution. The whole problem is that during build time the environment variables are not accessible (unless you use the ARG and ENV parameters in your Dockerfile file, but I don't like to bloat it), therefore all the database initialization, for example Stripe initialization or whatever other services that you may have that require those environmental variables, are gonna fail in build time. The idea is, try to adapt the code so instead of throwing an error, it accepts and manages situations where those env variables are null or not defined. For example in the database(postgres) initialization file (db/index.ts):

import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';

import * as users from '$lib/server/db/schemas/users'
import * as normalized from '$lib/server/db/schemas/normalized'
import * as availability from '$lib/server/db/schemas/availability';
import * as lessons from '$lib/server/db/schemas/lessons';
import * as bookings from '$lib/server/db/schemas/bookings';
import { env } from 'process';


function createDb() {
    const databaseUrl = env.DATABASE_URL;
    console.log('DATABASEURL: ', databaseUrl)
    if (!databaseUrl) throw new Error('DATABASE_URL is not set');
    
    // Skip DB connection during build
    if (process.env.NODE_ENV === 'build') {
        console.log('Build mode - skipping database connection');
        return null;
    }

    if (process.env.NODE_ENV === 'production') {
        console.log('Production mode - skipping database connection');
    }

    const client = postgres(databaseUrl);
    return drizzle(client, {
        schema: { ...users, ...normalized, ...availability, ...lessons, ...bookings }
    });
}

export const db = createDb();

Adn then wherever this db needs to be used, just handle the scenario where it might not be initialized properly:

import { eq } from "drizzle-orm";
import { db } from ".";
import { ageGroups, countries, currencies, languages, pricingModes, resorts, skillLevels, sports, timeUnits } from "./schemas/normalized";


export async function getAllSkiResorts() {
    if (!db){
        console.error('Database Not Initialized')
        return [];
    } 
    return await db.select().from(resorts);
}

export async function getSkiResortsByCountry(countryId: number) {
    if (!db){
        console.error('Database Not Initialized')
        return [];
    } 
    return await db.select().from(resorts).where(eq(countries.id, countryId))
}

export async function getAllCountries() {
    if (!db){
        console.error('Database Not Initialized')
        return [];
    } 
    return await db.select().from(countries);
}

Also in the Dockerfile, you could set the "build" environment var just to perform cleaner logic:

# Build stage
FROM node:22-alpine AS builder
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install
COPY . .
# Set build environment
ENV NODE_ENV=build
RUN pnpm build

# Production stage
FROM node:22-alpine
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --production
COPY --from=builder /app/build ./build
# Set production environment
ENV NODE_ENV=production
CMD ["node", "build/index.js"]
EXPOSE 3000

you just need to test and try to see where in your app, there is code that might create conflict during build and then adapt the logic to handle non existing values during buildtime. I hope this does the trick for someone in the same situation that I was!!

Reasons:
  • Blacklisted phrase (0.5): thank you
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: Erosique