部署到 AWS Lambda
本指南說明如何避免在使用 Prisma ORM 部署專案到 AWS Lambda 時的常見問題。
雖然部署到 AWS Lambda 不需要部署框架,但本指南涵蓋使用以下框架進行部署:
- AWS 無伺服器應用程式模型 (SAM) 是 AWS 的開源框架,可用於建立無伺服器應用程式。AWS SAM 包括 AWS SAM CLI,您可以使用它來建置、測試和部署您的應用程式。
- Serverless Framework 提供 CLI,可協助工作流程自動化和 AWS 資源佈建。雖然 Prisma ORM 與 Serverless Framework 「開箱即用」地運作良好,但在您的專案中可以進行一些改進,以確保順利部署和效能。如果您使用
serverless-webpack
或serverless-bundle
函式庫,則需要額外的配置。 - SST 提供的工具可讓開發人員輕鬆定義、測試、偵錯和部署其應用程式。Prisma ORM 與 SST 運作良好,但必須進行配置,以便 SST 正確封裝您的 schema。
部署到 AWS Lambda 的一般考量
本節涵蓋您需要對應用程式進行的變更,無論使用何種框架。遵循這些步驟後,請依照您的框架的步驟操作。
在 Prisma Schema 中定義二進位目標
根據 Node.js 的版本,您的 Prisma schema 應在 generator
區塊中包含 rhel-openssl-1.0.x
或 rhel-openssl-3.0.x
- Node.js 16 和 18
- Node.js 20+
binaryTargets = ["native", "rhel-openssl-1.0.x"]
binaryTargets = ["native", "rhel-openssl-3.0.x"]
這是必要的,因為開發和部署中使用的執行階段不同。新增 binaryTarget
以提供相容的 Prisma ORM 引擎檔案。
具有 arm64 架構的 Lambda 函式
使用 arm64 架構 (AWS Graviton2 處理器) 的 Lambda 函式必須使用 arm64
預編譯引擎檔案。
在 schema.prisma
檔案的 generator
區塊中,新增以下內容
binaryTargets = ["native", "linux-arm64-openssl-1.0.x"]
Prisma CLI 二進位目標
雖然我們不建議在 AWS Lambda 中執行遷移,但某些應用程式會需要它。在這些情況下,您可以使用 PRISMA_CLI_BINARY_TARGETS 環境變數,以確保 Prisma CLI 命令 (包括 prisma migrate
) 可以存取正確的 schema 引擎。
對於 AWS lambda,您必須新增以下環境變數
PRISMA_CLI_BINARY_TARGETS=native,rhel-openssl-1.0.x
prisma migrate
是 prisma
套件中的命令。通常,此套件會作為開發依賴項安裝。根據您的設定,您可能需要將此套件作為依賴項安裝,以便將其包含在上傳到 Lambda 並執行的捆綁包或封存檔中。
連線集區
一般而言,當您使用函式即服務 (FaaS) 環境與資料庫互動時,每次函式調用都可能導致與資料庫建立新的連線。這對於持續運行的 Node.js 伺服器來說不是問題。因此,將資料庫連線集區化以獲得更好的效能是有益的。您可以使用 Accelerate 來解決此問題。如需其他解決方案,請參閱 無伺服器環境的連線管理指南。
使用 AWS SAM 部署
載入環境變數
AWS SAM 不直接支援從 .env
檔案載入值。您必須使用 AWS 的其中一項服務來儲存和擷取這些參數。本指南 概述了您的選項,以及如何在 Parameters、SSM、Secrets Manager 等中儲存和擷取值。
載入必要的檔案
AWS SAM 使用 esbuild 來捆綁您的 TypeScript 程式碼。但是,未公開完整的 esbuild API,也不支援 esbuild 外掛程式。當在您的應用程式中使用 Prisma ORM 時,這會導致問題,因為某些檔案(例如 schema.prisma
)必須在執行階段可用。
為了繞過這個問題,您需要在程式碼中直接參考所需的檔案,以正確地捆綁它們。在您的應用程式中,您可以將以下程式碼行新增到實例化 Prisma ORM 的位置。
import schema from './prisma/schema.prisma'
import x from './node_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.node'
if (process.env.NODE_ENV !== 'production') {
console.debug(schema, x)
}
使用 Serverless Framework 部署
透過 .env
檔案載入環境變數
您的函式將需要 DATABASE_URL
環境變數才能存取資料庫。serverless-dotenv-plugin
外掛程式可讓您在部署中使用 .env
檔案。
首先,請確保已安裝此外掛程式
npm install -D serverless-dotenv-plugin
然後,將 serverless-dotenv-plugin
新增到 serverless.yml
中的外掛程式清單
plugins:
- serverless-dotenv-plugin
現在,.env
檔案中的環境變數將在封裝或部署時自動載入。
serverless package
僅部署必要的檔案
為了減少您的部署佔用空間,您可以更新您的部署程序,僅上傳您的應用程式需要的檔案。下面的 Serverless 配置檔案 serverless.yml
顯示了一個 package
模式,該模式僅包含與 Lambda 執行階段相關的 Prisma ORM 引擎檔案,並排除其他檔案。這表示當 Serverless Framework 封裝您的應用程式以進行上傳時,它僅包含一個引擎檔案。這確保了封裝的封存檔盡可能小。
package:
patterns:
- '!node_modules/.prisma/client/libquery_engine-*'
- 'node_modules/.prisma/client/libquery_engine-rhel-*'
- '!node_modules/prisma/libquery_engine-*'
- '!node_modules/@prisma/engines/**'
- '!node_modules/.cache/prisma/**' # only required for Windows
如果您要部署到 具有 ARM64 架構的 Lambda 函式,您應該更新 Serverless 配置檔案以封裝 arm64
引擎檔案,如下所示
package:
patterns:
- '!node_modules/.prisma/client/libquery_engine-*'
- 'node_modules/.prisma/client/libquery_engine-linux-arm64-*'
- '!node_modules/prisma/libquery_engine-*'
- '!node_modules/@prisma/engines/**'
如果您使用 serverless-webpack
,請參閱下面的 使用 serverless webpack 部署。
使用 serverless-webpack
部署
如果您使用 serverless-webpack
,您將需要額外的配置,以便正確捆綁您的 schema.prisma
。您將需要
- 使用
copy-webpack-plugin
複製您的schema.prisma
。 - 在您的
serverless.yml
中,透過custom > webpack > packagerOptions > scripts
執行prisma generate
。 - 僅封裝正確的 Prisma ORM 引擎檔案,以節省超過 40mb 的容量。
1. 安裝 webpack 特定依賴項
首先,確保已安裝以下 webpack 依賴項
npm install --save-dev webpack webpack-node-externals copy-webpack-plugin serverless-webpack
2. 更新 webpack.config.js
在您的 webpack.config.js
中,確保您將 externals
設定為 nodeExternals()
,如下所示
const nodeExternals = require('webpack-node-externals')
module.exports = {
// ... other configuration
externals: [nodeExternals()],
// ... other configuration
}
更新 webpack.config.js
檔案中的 plugins
屬性,以包含 copy-webpack-plugin
const nodeExternals = require('webpack-node-externals')
const CopyPlugin = require('copy-webpack-plugin')
module.exports = {
// ... other configuration
externals: [nodeExternals()],
plugins: [
new CopyPlugin({
patterns: [
{ from: './node_modules/.prisma/client/schema.prisma', to: './' }, // you may need to change `to` here.
],
}),
],
// ... other configuration
}
此外掛程式可讓您將 schema.prisma
檔案複製到您的捆綁程式碼中。Prisma ORM 要求您的 schema.prisma
必須存在,以確保根據您的 schema 編碼和解碼查詢。在大多數情況下,捆綁器預設不會包含此檔案,並會導致您的應用程式無法執行。
根據您的應用程式的捆綁方式,您可能需要將 schema 複製到 ./
以外的位置。使用 serverless package
命令在本機封裝您的程式碼,以便您可以查看應放置 schema 的位置。
有關其他配置,請參閱 Serverless Webpack 文件。
3. 更新 serverless.yml
在您的 serverless.yml
檔案中,確保 custom > webpack
區塊在 packagerOptions > scripts
下具有 prisma generate
,如下所示
custom:
webpack:
packagerOptions:
scripts:
- prisma generate
這將確保在 webpack 捆綁您的程式碼後,Prisma Client 會根據您的 schema 產生。沒有此步驟,您的應用程式將無法執行。
最後,您會想要排除與 AWS Lambda 執行階段不符的 Prisma ORM 查詢引擎。透過新增以下指令碼來更新您的 serverless.yml
,以確保最終封裝的封存檔中僅包含所需的查詢引擎 rhel-openssl-1.0.x
。
custom:
webpack:
packagerOptions:
scripts:
- prisma generate
-- find . -name "libquery_engine-*" -not -name "libquery_engine-rhel-openssl-*" | xargs rm
如果您要部署到 具有 ARM64 架構的 Lambda 函式,您應該將 find
命令更新為以下內容
custom:
webpack:
packagerOptions:
scripts:
- prisma generate
-- find . -name "libquery_engine-*" -not -name "libquery_engine-arm64-openssl-*" | xargs rm
4. 總結
您現在可以重新封裝和重新部署您的應用程式。若要執行此操作,請執行 serverless deploy
。Webpack 輸出將顯示使用 copy-webpack-plugin
移動的 schema
serverless package
使用 SST 部署
使用環境變數
雖然 SST 支援 .env
檔案,但 不建議使用。SST 建議使用 Config
以安全的方式存取這些環境變數。
SST 指南 在此處提供 是開始使用 Config
的逐步指南。假設您已建立名為 DATABASE_URL
的新密碼,並已將該密碼 繫結到您的應用程式,您可以使用以下設定 PrismaClient
import { PrismaClient } from '@prisma/client'
import { Config } from 'sst/node/config'
const globalForPrisma = global as unknown as { prisma: PrismaClient }
export const prisma =
globalForPrisma.prisma ||
new PrismaClient({
datasourceUrl: Config.DATABASE_URL,
})
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
export default prisma