如何在 Dockerized GraphQL + Postgres 设置中运行 Prisma 迁移?
Posted
技术标签:
【中文标题】如何在 Dockerized GraphQL + Postgres 设置中运行 Prisma 迁移?【英文标题】:How do I run Prisma migrations in a Dockerized GraphQL + Postgres setup? 【发布时间】:2021-06-13 05:13:31 【问题描述】:我不熟悉使用 Prisma 以及 Dockerizing 我的设置。我想使用 Prisma 指定我的数据模型,将 Postgres 作为我的数据库并在 GraphQL API(我当前的 API 使用 apollo-server-express
)中使用它,该 API 还处理身份验证和角色等。
我现在拥有的是我的 GraphQL API 的一个简单的 docker-compose.yml
和一个 Dockerfile
:
docker-compose.yml
services:
api:
build: ./api
env_file:
- .env
volumes:
- ./api:/usr/src/app
ports:
- $API_PORT:$API_PORT
command: npm start
Dockerfile
# Latest LTS version
FROM node:14
# Set default values for environment variables
ENV API_PORT=3001
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package*.json ./
RUN npm install
# Bundle app source
COPY . .
# Bind port
EXPOSE $API_PORT
# Start server
CMD ["npm", "start"]
我将如何在此设置中使用 Prisma 和 Postgres,迁移以某种容器化方式发生,而不是我在 CLI 中手动执行 Prisma 命令?
感谢指出我的误解、提示或反馈!谢谢
【问题讨论】:
【参考方案1】:我自己的问题的最新答案:就像@Athir 建议的那样,我现在将两个进程分开并创建了两个 docker-compose.yml 文件:一个名为 docker-compose.migrate.yml
的文件负责运行迁移,另一个名为 docker-compose.yml
是主应用程序。
我的docker-compose.migrate.yml
:
version: '3'
services:
prisma-migrate:
container_name: prisma-migrate
build: ./api/prisma
env_file:
- .env
environment:
DB_HOST: <secret>
depends_on:
- db
db:
image: postgres:13
container_name: db
restart: always
env_file:
- .env
environment:
DB_PORT: 5432
ports:
- $DB_PORT:5432
volumes:
- $POSTGRES_VOLUME_DIR:/var/lib/postgresql/data
使用以下 Prisma Dockerfile:
FROM node:14
RUN echo $DATABASE_URL
WORKDIR /app
COPY ./package.json ./
COPY . ./prisma/
RUN chmod +x ./prisma/wait-for-postgres.sh
RUN npm install
RUN npx prisma generate
RUN apt update
RUN apt --assume-yes install postgresql-client
# Git will replace the LF line-endings with CRLF, causing issues while executing the wait-for-postgres shell script
# Install dos2unix and replace CRLF (\r\n) newlines with LF (\n)
RUN apt --assume-yes install dos2unix
RUN dos2unix ./prisma/wait-for-postgres.sh
CMD sh ./prisma/wait-for-postgres.sh $DB_HOST $POSTGRES_USER npx prisma migrate deploy && npx prisma db seed --preview-feature
和wait-for-postgres.sh
:
#!/bin/sh
# wait-for-postgres.sh
set -e
host="$1"
user="$2"
shift
shift
cmd="$@"
until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$host" -U "$user" -c '\q'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - executing command"
exec $cmd
【讨论】:
能否请您也显示wait-for-postgres.sh
脚本?
@mrodo 完成,我现在已经编辑了答案并添加了 wait-for-postgres.sh
脚本。【参考方案2】:
您需要在启动 nextjs 应用程序之前运行迁移。有几种方法可以做到这一点。有些人将此作为此 CI/CD 脚本的一部分。在您使用 docker compose 的情况下,您可以更改启动命令以在启动应用程序之前运行运行迁移的脚本。
首先,创建你的 bash 脚本
npx prisma migrate deploy
npm start
然后更改您的 Dockerfile
以运行脚本
CMD ["startup.sh"]
【讨论】:
谢谢@Athir!我最终创建了第二个撰写文件:docker-compose.migrate.yml
,并且现在确实将其作为我的 CI/CD 的一部分运行。这是一个可行的替代方案。
@MaxdeKrieger 您能否分享有关您的新 docker compose 的更多详细信息?
@igo 我现在在下面发布了我的答案,如果您需要更多详细信息,请告诉我以上是关于如何在 Dockerized GraphQL + Postgres 设置中运行 Prisma 迁移?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 gitlab CI 中访问被测试的 dockerized 应用程序
如何设置 Dockerized 应用程序与 Elastic Beanstalk 的持续集成?
AWS Elastic Beanstalk 上的 Dockerized 节点。错误 502 BadGateway
如何将 -mem 传递给 dockerized Play 应用程序