FROM node:22 AS builder
# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
# Copy package files first to leverage cache
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
# Copy rest of the files
COPY . .
RUN pnpm build
FROM node:22 AS production
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@latest --activate
# Copy necessary files from builder
COPY --from=builder /app/package.json /app/pnpm-lock.yaml ./
COPY --from=builder /app/build ./build
# Install production dependencies only
RUN pnpm install --prod --frozen-lockfile
# Add a non-root user for security
#RUN addgroup --system --gid 1001 nodejs \
# && adduser --system --uid 1001 nodejs
#USER nodejs
EXPOSE 3000
CMD ["node", "build/index.js"]
services:
app:
build: .
image: pulso_test
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://root:mysecretpassword@db:5432/pulso_dev
- NODE_ENV=production
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres
environment:
- POSTGRES_USER=root
- POSTGRES_PASSWORD=mysecretpassword
- POSTGRES_DB=pulso_dev
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U root -d pulso_dev"]
interval: 10s
timeout: 5s
retries: 5
start_period: 60s
restart: unless-stopped
volumes:
postgres_data:
当我尝试运行命令时:
docker build -t pulsodenieve-vps:latest .
this Log出现:
[+] Building 21.6s (12/17) docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 859B 0.0s
=> [internal] load metadata for docker.io/library/node:22 6.7s
=> [auth] library/node:pull token for registry-1.docker.io 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 143B 0.0s
=> [builder 1/7] FROM docker.io/library/node:22@sha256:ae2f3d4cc65d251352eca01ba668824f651a2ee4d2a37e2efb22649521a483fd 0.0s
=> => resolve docker.io/library/node:22@sha256:ae2f3d4cc65d251352eca01ba668824f651a2ee4d2a37e2efb22649521a483fd 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 29.08kB 0.0s
=> CACHED [builder 2/7] RUN corepack enable && corepack prepare pnpm@latest --activate 0.0s
=> CACHED [builder 3/7] WORKDIR /app 0.0s
=> CACHED [builder 4/7] COPY package.json pnpm-lock.yaml ./ 0.0s
=> CACHED [builder 5/7] RUN pnpm install --frozen-lockfile 0.0s
=> CACHED [builder 6/7] COPY . . 0.0s
=> ERROR [builder 7/7] RUN pnpm build 14.6s
------
> [builder 7/7] RUN pnpm build:
0.329 ! The local project doesn't define a 'packageManager' field. Corepack will now add one referencing [email protected]+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0.
0.329 ! For more details about this field, consult the documentation at https://nodejs.org/api/packages.html#packagemanager
0.329
0.606
0.606 > [email protected] build /app
0.606 > vite build
0.606
2.248 NODE_ENV=production is not supported in the .env file. Only NODE_ENV=development is supported to create a development build of your project. If you need to set process.env.NODE_ENV, you can set it in the Vite config instead.
2.271 vite v6.0.3 building SSR bundle for production...
2.282 Using existing cloned repo
4.403 ℹ [paraglide] Compiling Messages into ./src/lib/paraglide
4.438 transforming...
12.97 "PostgresJsDatabase" is imported from external module "drizzle-orm/postgres-js" but never used in "src/lib/server/db/index.ts".
12.97 ✓ 2483 modules transformed.
13.15 rendering chunks...
14.41
14.41 node:internal/event_target:1101
14.41 process.nextTick(() => { throw err; });
14.41 ^
14.41 Error: connect ECONNREFUSED 127.0.0.1:5432
14.41 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1634:16) {
14.41 errno: -111,
14.41 code: 'ECONNREFUSED',
14.41 syscall: 'connect',
14.41 address: '127.0.0.1',
14.41 port: 5432
14.41 }
14.41
14.41 Node.js v22.13.1
14.56 ELIFECYCLE Command failed with exit code 1.
------
Dockerfile:14
--------------------
12 | # Copy rest of the files
13 | COPY . .
14 | >>> RUN pnpm build
15 |
16 | FROM node:22 AS production
--------------------
ERROR: failed to solve: process "/bin/sh -c pnpm build" did not complete successfully: exit code: 1
View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/k5srk2ca5wbzgursp9v4jsmzk
there是我的服务器/db/dbconfig.ts:
import { env } from '$env/dynamic/private';
export type DbConfig = {
url: string;
maxConnections?: number;
ssl?: boolean;
};
export function getDbConfig(): DbConfig {
const environment = env.NODE_ENV || 'development';
const configs: Record<string, DbConfig> = {
development: {
url: env.DATABASE_URL || 'postgresql://root:mysecretpassword@localhost:5432/pulso_dev',
maxConnections: 10
},
test: {
url: env.TEST_DATABASE_URL || 'postgresql://root:mysecretpassword@localhost:5432/pulso_test',
maxConnections: 5
},
production: {
url: env.DATABASE_URL,
ssl: true,
maxConnections: 20
}
};
const config = configs[environment];
if (!config) throw new Error(`No database configuration for environment: ${environment}`);
if (!config.url) throw new Error(`DATABASE_URL is not set for environment: ${environment}`);
return config;
}
服务器/DB/INDEX.TS:
import { drizzle, PostgresJsDatabase } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { getDbConfig } from './config';
import * as users from './schemas/users';
import * as normalized from './schemas/normalized';
import * as availability from './schemas/availability';
import * as lessons from './schemas/lessons';
import * as bookings from './schemas/bookings';
const schema = {
...users,
...normalized,
...availability,
...lessons,
...bookings
} as const;
type DB = PostgresJsDatabase<typeof schema>;
let _db: DB | null = null;
export function createDb(): DB {
const config = getDbConfig();
const client = postgres(config.url, {
max: config.maxConnections,
ssl: config.ssl
});
return drizzle(client, { schema });
}
export function getDb(): DB {
if (!_db) {
_db = createDb();
}
return _db;
}
export function closeDb() {
_db = null;
}
well感谢您回答的每个人!最后,我提出了一个肮脏但有效的解决方案。整个问题是,在构建时间中,环境变量无法访问(除非您在dockerfile文件中使用arg和env参数,否您可能拥有的其他需要这些环境变量的服务都将在构建时间中失败。这个想法是,尝试调整代码,因此它不再丢弃错误,而是接受并管理这些ENV变量为null或未定义的情况。 例如,在数据库(Postgres)初始化文件(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();
然后,无论需要使用此DB,只需处理可能无法正确初始初始初始初始初始初始初始化的情况:
在Dockerfile中,您可以设置“构建”环境VAR仅能执行清洁逻辑:
# 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
您只需要测试并尝试查看应用程序中的位置,其中有代码可能会在构建过程中造成冲突,然后调整逻辑以处理构建时间期间的非现有值。 我希望这对我处于同一情况的某人有效!