You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Docker Compose中通过npm包自动创建PostgreSQL数据库表?

问题描述

我有一个使用Prisma和PostgreSQL进行数据库管理的项目,为实现集中管理并供多个项目复用,将其封装为npm包project-db,通过npm i <project-db>安装。目前需要配置docker-compose文件,在部署依赖该数据库的新项目(如Project A)的全新实例时自动创建所需数据表,但由于数据库/Prisma均由npm包间接管理,不确定如何实现运行docker-compose时执行project-db中的脚本创建表。当前Project A的Docker镜像构建时因缺少数据库表报错,相关配置如下:

结构示意图

Project A(Node项目,配置为Docker服务)
     - package.json中包含`project-db`作为依赖

project-db(发布至npm registry的独立仓库)
     - 包含prisma schema
     - 拥有用于初始化Prisma和部署数据库的安装脚本

postgres(配置为Docker服务)
     - Prisma使用的数据库服务

Dockerfile(Project A)

ARG OWNER
FROM node:20-buster-slim
ENV NODE_ENV 'development'
ENV OWNER "username"

RUN apt-get update && apt-get install libssl-dev ca-certificates -y

# Create app directory
WORKDIR /usr/src/app

# Copy package.json and package-lock.json
COPY package*.json .

# Setup npmrc
RUN --mount=type=secret,id=TOKEN \
    TOKEN=$(cat /run/secrets/TOKEN) && \
    echo //npm.pkg.github.com/:_authToken=${TOKEN} >> ~/.npmrc
RUN echo @${OWNER}:registry=https://npm.pkg.github.com/ >> ~/.npmrc

# Copy src files
COPY src/ src/

# Install packages
RUN npm ci
# ^ installs "project-db" as a dependency

# remove github token from npmrc
RUN echo > ~/.npmrc

# Build the project
RUN npm run build

# Run the start script in package.json
CMD ["npm", "run", "start"]

docker-compose脚本

services:
  postgres:
        image: postgres:16.2
        container_name: postgres
        hostname: postgres
        environment:
            POSTGRES_USER: ${PSQL_USER}
            POSTGRES_PASSWORD: ${PSQL_PASS}
            POSTGRES_DB: ${PSQL_DB_NAME}
        ports:
            - ${PSQL_PORT}:${PSQL_PORT}
        restart: 'unless-stopped'
        volumes:
            - 'pg-data:/var/lib/postgresql/data'
        healthcheck:
            test: ['CMD-SHELL', 'pg_isready -q -d $$POSTGRES_DB -U $$POSTGRES_USER']
            interval: 10s
            timeout: 5s
            retries: 5
  projectA:
        build: 
            context: .
            secrets:
                - TOKEN
        container_name: projectA
        depends_on:
            postgres:
                condition: service_healthy
        tty: true
        env_file:
            - src/.env
volumes:
  pg-data:
    driver: local
secrets:
    TOKEN:
        environment: "TOKEN"
解决方案

核心思路

构建阶段报错的原因是:镜像构建时PostgreSQL服务尚未启动,若构建流程中包含访问数据库的操作(如运行数据库查询、执行迁移)必然失败。因此需要将数据库初始化操作从构建阶段移至容器启动阶段,或通过独立服务完成初始化后再启动主应用。

方案1:修改Project A启动流程,前置数据库初始化

修改Project A的package.json启动脚本,在启动应用前执行project-db提供的数据库初始化/迁移脚本:

// Project A package.json
{
  "scripts": {
    "start": "npx project-db-run-migrations && node dist/index.js"
  }
}

若project-db未提供封装好的脚本,可直接调用Prisma命令(需指定schema路径):

"start": "npx prisma migrate deploy --schema=node_modules/project-db/prisma/schema.prisma && node dist/index.js"

也可直接修改Dockerfile的CMD命令:

CMD ["sh", "-c", "npx prisma migrate deploy --schema=node_modules/project-db/prisma/schema.prisma && npm run start"]

方案2:新增独立数据库初始化服务(推荐,解耦架构)

在docker-compose中添加一个一次性的db-init服务,专门执行数据库迁移,完成后自动退出。Project A等待该服务执行成功后再启动:

services:
  postgres:
    # 保持原有配置不变
  db-init:
    build:
      context: .
      secrets:
        - TOKEN
    container_name: db-init
    depends_on:
      postgres:
        condition: service_healthy
    env_file:
      - src/.env
    # 执行project-db的迁移脚本,或直接调用Prisma命令
    command: ["npx", "prisma", "migrate", "deploy", "--schema=node_modules/project-db/prisma/schema.prisma"]
  projectA:
    build: 
      context: .
      secrets:
          - TOKEN
    container_name: projectA
    depends_on:
      db-init:
        condition: service_completed_successfully
      postgres:
        condition: service_healthy
    # 保持原有配置不变

该方案的优势是将数据库初始化与应用启动完全解耦,避免主应用容器因初始化失败反复重启。

补充:修复构建阶段报错

若构建阶段(npm run build)包含生成Prisma客户端的操作,需确保仅生成客户端而不访问数据库:

# 在npm ci之后添加以下命令
RUN npx prisma generate --schema=node_modules/project-db/prisma/schema.prisma

此命令仅生成Prisma客户端代码,不会连接数据库,可安全在构建阶段执行。

内容的提问来源于stack exchange,提问作者secondubly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:58:15