PrismaのマイグレーションをLambda(AWS SAM)でやってみる
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.
推奨されないが、PRISMA_CLI_BINARY_TARGETS
を書けばできるっぽい
とりあえず次の手順で進める
- sam initで環境を構築する
- ローカルでLambdaを動かして、
prisma -v
のコマンドを実行する - ローカルにDBを立ち上げる
-
npx prisma init
する - prismaのスキーマファイルを作成し、モデルを定義する
-
npx prisma migrate dev
してマイグレーションファイルを作成する - ローカルでLambdaを動かして、
prisma migrate deploy
する - AWSでRDSを起動する
-
sam deploy
して、AWS上でmigrationできるか確かめる
- sam initで環境を構築する
とりあえず環境を構築し、最初のcommitをした
sam initすると命名がhello worldな感じなので、リネームする
- ローカルで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)
...
というエラーも発生する、、
とりあえず、こんな感じの変更となった
prismaのengineがないということかもしれないので、とりあえず進めてみるか
- ローカルにDBを立ち上げる
起動用のdocker composeファイルを作成
npx prisma init
する
prisma init
した
.envファイルも書き換えた
DATABASE_URL="postgresql://postgres:postgrespassword@localpostgres:5432/mydb?schema=public"
npx prisma migrate dev
してマイグレーションファイルを作成する
でやった
DBにつながらない問題があったので、docker-compose.ymlでDBの設定を変更した
.envファイルも書き換えた
DATABASE_URL="postgresql://postgres:postgrespassword@localhost:5432/postgres?schema=public"
- ローカルでLambdaを動かして、
prisma migrate deploy
する
をやってみた。
が、実行するとエラー
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がないっぽい
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/engines
に schema-engine-rhel-openssl-3.0.x
というファイルができていた!
このやり方でいけそう
ちなみに .env
に
PRISMA_CLI_BINARY_TARGETS="rhel-openssl-3.0.x"
と書いても、上記のようなことにはならなかった
# 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/engines
に schema-engine-rhel-openssl-3.0.x
が生成された
sam build
するときにcontainer上でビルドすると、勝手にrhel-openssl-3.0.x向けのschema engineがダウンロードされそう
再度
- ローカルで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秒にしてみる
Globals:
Function:
Timeout: 30
再度実行してみるとタイムアウトのエラーは出なくなったが、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`.
postgresのコンテナについて、独自のdocker network設定の追加
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
やっと実行できた!