Open13

PrismaのマイグレーションをLambda(AWS SAM)でやってみる

mongolyymongolyy

While we do not recommend running migrations within AWS Lambda, some applications will require it. In these cases, you can use the PRISMA_CLI_BINARY_TARGETS environment variable to make sure that Prisma CLI commands, including prisma migrate, have access to the correct schema engine.

https://www.prisma.io/docs/orm/prisma-client/deployment/serverless/deploy-to-aws-lambda#prisma-cli-binary-targets

推奨されないが、PRISMA_CLI_BINARY_TARGETS を書けばできるっぽい

mongolyymongolyy

とりあえず次の手順で進める

  1. sam initで環境を構築する
  2. ローカルでLambdaを動かして、prisma -vのコマンドを実行する
  3. ローカルにDBを立ち上げる
  4. npx prisma init する
  5. prismaのスキーマファイルを作成し、モデルを定義する
  6. npx prisma migrate dev してマイグレーションファイルを作成する
  7. ローカルでLambdaを動かして、prisma migrate deploy する
  8. AWSでRDSを起動する
  9. sam deploy して、AWS上でmigrationできるか確かめる
mongolyymongolyy
  1. ローカルでLambdaを動かして、prisma -vのコマンドを実行する

npm install prisma して、

https://qiita.com/tmokmss/items/cd8c7ecb7101b1d137d1 を参考にコードを書く

ReferenceError: execFile is not defined というエラーが出たので

import { execFile } from "child_process";
import path from "path";

のimportを付け加えた

ローカルで実行してみると、consoleには

2025-01-22T14:58:03.054Z        09fdb19e-438e-4b22-9d4b-a1c3cbb09336    INFO    prisma                  : 6.2.1
@prisma/client          : Not found
Computed binaryTarget   : rhel-openssl-3.0.x
Operating System        : linux
Architecture            : x64
Node.js                 : v20.18.0
TypeScript              : 5.4.5
Query Engine (Node-API) : E_CANNOT_RESOLVE_VERSION (at E_CANNOT_RESOLVE_PATH)
Schema Engine           : E_CANNOT_RESOLVE_VERSION (at E_CANNOT_RESOLVE_PATH)
Schema Wasm             : @prisma/prisma-schema-wasm 6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69
Default Engines Hash    : 4123509d24aa4dede1e864b46351bf2790323b69
Studio                  : 0.503.0

が表示された!

が、

Error: Could not find libquery-engine binary. Searched in:
- /var/task/node_modules/@prisma/engines/libquery_engine-rhel-openssl-3.0.x.so.node
- /var/task/node_modules/prisma/libquery_engine-rhel-openssl-3.0.x.so.node
- /var/task/node_modules/libquery_engine-rhel-openssl-3.0.x.so.node
- /var/task/node_modules/prisma/runtime/libquery_engine-rhel-openssl-3.0.x.so.node
    at O5 (/var/task/node_modules/prisma/build/index.js:665:10116)
Error: Could not find libquery-engine binary. Searched in:
- /var/task/node_modules/@prisma/engines/libquery_engine-rhel-openssl-3.0.x.so.node
- /var/task/node_modules/prisma/libquery_engine-rhel-openssl-3.0.x.so.node
- /var/task/node_modules/libquery_engine-rhel-openssl-3.0.x.so.node
- /var/task/node_modules/prisma/runtime/libquery_engine-rhel-openssl-3.0.x.so.node
    at O5 (/var/task/node_modules/prisma/build/index.js:665:10116)
...

というエラーも発生する、、

とりあえず、こんな感じの変更となった
https://github.com/mongolyy/prisma-migrate-on-sam-lambda/commit/883c3e086869df587e62a0abc07d5ef6212f0958

mongolyymongolyy
  1. ローカルでLambdaを動かして、prisma migrate deploy する

をやってみた。
https://github.com/mongolyy/prisma-migrate-on-sam-lambda/commit/f7f9443b2ebc138f80e0213689600794c8884e29

が、実行するとエラー

2025-01-22T22:25:38.550Z        240dc6e2-cddf-4f0c-a28c-48a5a2da28a9    INFO    prisma migrate deploy exited with error Command failed: /var/task/node_modules/prisma/build/index.js migrate deploy
Error: Schema engine exited. Error: Could not find schema-engine binary. Searched in:
- /var/task/node_modules/@prisma/engines/schema-engine-rhel-openssl-3.0.x
- /var/task/node_modules/prisma/schema-engine-rhel-openssl-3.0.x
- /var/task/node_modules/schema-engine-rhel-openssl-3.0.x
- /var/task/node_modules/prisma/runtime/schema-engine-rhel-openssl-3.0.x

schema engineがないっぽい

mongolyymongolyy

https://www.prisma.io/docs/orm/reference/environment-variables-reference#cli-binary-targets を参考に、npm install時に環境変数を適用した

PRISMA_CLI_BINARY_TARGETS=rhel-openssl-3.0.x npm install

すると、 node_modules/@prisma/enginesschema-engine-rhel-openssl-3.0.x というファイルができていた!

このやり方でいけそう

ちなみに .env

PRISMA_CLI_BINARY_TARGETS="rhel-openssl-3.0.x"

と書いても、上記のようなことにはならなかった

mongolyymongolyy
samconfig.toml
# More information about the configuration file can be found here:
# https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
version = 0.1
[default.global.parameters]
stack_name = "prisma-migrate-on-sam-lambda"
[default.build.parameters]
use_container = true

を追加して、sam build すると.aws-sam/build/PrismaMigrateFunction/node_modules/@prisma/enginesschema-engine-rhel-openssl-3.0.x が生成された

sam build するときにcontainer上でビルドすると、勝手にrhel-openssl-3.0.x向けのschema engineがダウンロードされそう

https://github.com/mongolyy/prisma-migrate-on-sam-lambda/commit/4f728c6721fdb9590247c4a05c196451824570a8

mongolyymongolyy

再度

  1. ローカルでLambdaを動かして、prisma migrate deploy する

をやってみる

$ sam local invoke PrismaMigrateFunction --event events/event.json
...省略
Function 'PrismaMigrateFunction' timed out after 3 seconds
No response from invoke container for PrismaMigrateFunction

タイムアウトのエラーが出たので、30秒にしてみる

template.yaml
Globals:
  Function:
    Timeout: 30

https://github.com/mongolyy/prisma-migrate-on-sam-lambda/commit/9ebc29b21d721072b9b319a1e9a86813bf4a0727

再度実行してみるとタイムアウトのエラーは出なくなったが、DBに接続できていない模様

$ sam local invoke PrismaMigrateFunction --event events/event.json
...省略
Error: P1001: Can't reach database server at `postgres:5432`

Please make sure your database server is running at `postgres:5432`.
mongolyymongolyy

postgresのコンテナについて、独自のdocker network設定の追加

docker-compose.yml
services:
  postgres:
    image: postgres:17
    restart: always
    networks:
      - postgres-network
    ports:
      - "5432:5432"
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgrespassword
volumes:
  db_data:
networks:
  postgres-network:
    name: postgres-network

.env ファイルにおいて、コンテナ名?を指定するようにする

DATABASE_URL="postgresql://postgres:postgrespassword@postgres:5432/postgres?schema=public"

sam local invoke のコンテナから独自のdocker networkにつなげられるようにする

$ sam local invoke PrismaMigrateFunction --event events/event.json --docker-network postgres-network
...省略
START RequestId: d8e3be77-183c-49df-a6a0-2532898264a4 Version: $LATEST
2025-02-03T15:49:36.356Z        3190ab87-9e36-4952-909c-0b67079789f8    INFO    Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "postgres:5432"

1 migration found in prisma/migrations

Applying migration `20250122220940_initial_migrate`

The following migration(s) have been applied:

migrations/
  └─ 20250122220940_initial_migrate/
    └─ migration.sql

All migrations have been successfully applied.

END RequestId: 3190ab87-9e36-4952-909c-0b67079789f8

やっと実行できた!

https://github.com/mongolyy/prisma-migrate-on-sam-lambda/commit/8e8a4dd58736c936acde5e2461affb8304f80aa4