はじめに
この記事では、Docker Compose で構築した Node.js / TypeScript / PostgreSQL 環境で、Prisma を使ったマイグレーション実行手順について記載します。
開発環境
開発環境は以下の通りです。
- Windows11
- Docker Engine 27.0.3
- Docker Compose 2
- PostgreSQL 17.5
- Node.js 22.17.1
- npm 11.5.1
- TypeScript 5.8.3
- Express 5.1.0
- Prisma 6.13.0
Node.js / TypeScript の環境構築
プロジェクト初期化
プロジェクトを初期化します。
npm init -y
TypeScript設定
TypeScript 及び以下のパッケージをインストールします。
-
ts-node
: TypeScript を JavaScript へコンパイルせず実行できるようにする -
@types/node
: Node.js の型定義
npm install typescript ts-node @types/node --save-dev
TypeScirpt 設定ファイルを作成します。
npx tsc --init
tsconfig.json
を以下のように設定します。
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"types": ["node"]
}
}
.gitignore 設定
.gitignore
ファイルを作成して、不要なファイルをバージョン管理から除外します。
node_modules
dist/
.env
ソースコードの実装
HTTP サーバーを起動して、利用ポートのログを出力するコードを実装します。
import { createServer } from "http";
const server = createServer();
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Node.js 起動スクリプトの追加
package.json
に Node.js 起動スクリプトを追加します。
{
...
"scripts": {
"start": "ts-node src/index.ts",
...
},
...
}
ここまでできたら一度起動確認をします。
npm start
実装したログが出力されます。
Server is running on port 3000
Docker環境の構築
アプリケーションコンテナとデータベースコンテナを定義します。
Dockerfile の作成
Node.js は Dockerfile からイメージをビルドしたいので、Dockerfile を作成します。
# Use the official Node.js image
FROM node:24-alpine3.20
# Create and set the working directory
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm install
# Expose the application port
EXPOSE 3000
# Run the application
CMD ["npm", "start"]
compose.yaml の作成
以下の要件を満たす compose.yaml
を作成します。
- Node.js
- コンテナ名:
app-container
- ビルド:Dockerfile
- ポート:3000
- ソースコード:ホストマシンで実装
- コンテナ名:
- PostgreSQL
- コンテナ名:`db-container
- ビルド:PostgreSQL 公式イメージ のタグ 17.5-alpine3.22
- ポート:5432
- データはコンテナを削除しても残す
- ホストマシンからDB接続可能
- コンテナ間通信可能
services:
app:
container_name: "app-container"
build: .
ports:
- "3000:3000"
volumes:
- type: bind
source: .
target: /app
environment:
# アプリケーションコンテナからDBへの接続情報
DATABASE_URL: postgresql://user:userpassword@db:5432/sampledb
depends_on:
- db
db:
container_name: "db-container"
image: postgres:17.5-alpine3.22
ports:
- "5432:5432"
volumes:
- type: volume
source: db-volume
target: /var/lib/postgresql/data
environment:
# DBの初期化用環境変数
POSTGRES_USER: user
POSTGRES_PASSWORD: userpassword
POSTGRES_DB: sampledb
volumes:
db-volume:
動作確認
一度動作確認をします。
docker compose up --build
app-container
に実装したログが出力されます。
app-container | Server is running on port 3000
コンテナ一覧を確認します。
docker container ls
compose.yaml
で定義した名前通りのコンテナが作成されています。
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
2286d4d79223 postgres:17.5-alpine3.22 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp db-container
097e29a0059d node-postgres-crud-prisma-app "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:3000->3000/tcp app-container
この時点では、AppコンテナとDBコンテナがそれぞれ起動しているだけで、コンテナ間の通信は発生していません。
DB接続処理の実装
AppコンテナからDBコンテナに接続する処理を実装します。
Prisma のインストール
PrismaのCLIツール(prisma
)とクライアント(@prisma/client
)をインストールします。
npm install prisma --save-dev
npm install @prisma/client
prisma
スキーマ定義、マイグレーション、クライアントコードの生成といった開発作業を行うためのツールです。本番環境でアプリケーションを動かす際には、これらの開発ツールは不要です。そのため、--save-dev
オプションを付けて「開発環境でのみ必要な依存関係」としてインストールします。
一方、@prisma/client
はNode.jsアプリケーションからデータベースにアクセスするためのライブラリで、アプリケーションが本番環境でも動作するために必要です。そのため、--save-dev
を付けずに「本番環境でも必要な依存関係」としてインストールします。
Prismaの初期化
Prismaの設定ファイルを生成します。
npx prisma init
このコマンドを実行すると、以下のファイルが作成されます。
-
prisma/schema.prisma
: Prismaのスキーマ定義ファイル。データベースモデルや接続情報 -
.env
: 環境変数ファイル。データベースの接続情報
スキーマ定義
生成された prisma/schema.prisma
を編集してデータベーススキーマを定義します。
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String
}
環境変数設定
.env
ファイルは、Prismaのコマンドをホストマシン上で実行するために必要です。compose.yaml
で定義したデータベース情報に合わせて、中身を変更します。
DATABASE_URL="postgresql://user:userpassword@localhost:5432/sampledb"
ホスト名を localhost
にしているのは、ホストマシンからDockerコンテナのDBにアクセスするためです。compose.yaml
で ports: - "5432:5432"
と指定しているため、localhost:5432
への接続はコンテナ内のDBに転送されます。
そもそも今回はマイグレーションをコンテナ内で実行するため不要ですが、Prisma Studioなどホストマシンで実行するコマンドのために設定しておきます。
マイグレーション実行
テーブル定義が完了したら、マイグレーションを実行して、DBにテーブルを作成します。
コンテナとボリュームを一度完全に削除してから再起動します。
docker compose down --volumes
docker compose up --build
コンテナ内でマイグレーションを実行します。
docker compose exec app npx prisma migrate dev --name init
docker compose exec app
コマンドで、app-container
の中で npx prisma migrate dev --name init
を実行します。compose.yaml
のバインドマウント設定により、生成されたマイグレーションファイルはホストマシンの prisma/migrations
ディレクトリに同期されます。
このコマンドで以下が実行されます。
- マイグレーションファイルの生成(
prisma/migrations/
ディレクトリ) - データベースへのマイグレーション適用
- Prisma Client の生成
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "sampledb", schema "public" at "db:5432"
Applying migration `20250805055933_init`
The following migration(s) have been created and applied from new schema changes:
prisma/migrations/
└─ 20250805055933_init/
└─ migration.sql
Your database is now in sync with your schema.
✔ Generated Prisma Client (v6.13.0) to ./node_modules/@prisma/client in 383ms
動作確認
db-container
に接続します。
docker compose exec db psql -U user -d sampledb
テーブル一覧を確認します。
\dt
User
テーブルと _prisma_migrations
テーブルが表示されます。
List of relations
Schema | Name | Type | Owner
--------+--------------------+-------+-------
public | User | table | user
public | _prisma_migrations | table | user
(2 rows)
テーブルのカラムを確認します。
\d "User"
prisma/schema.prisma で定義した通り、id, email, name の3つのカラムが表示されます。
Table "public.User"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+------------------------------------
id | integer | | not null | nextval('"User_id_seq"'::regclass)
email | text | | not null |
name | text | | not null |
Indexes:
"User_pkey" PRIMARY KEY, btree (id)
"User_email_key" UNIQUE, btree (email)
まとめ
Docker Compose 環境での Prisma マイグレーション実行手順について説明しました。
ポイントは以下の通りです。
-
prisma migrate dev
で開発環境でのマイグレーション実行 - マイグレーションファイルは自動生成され、バージョン管理可能
-
prisma studio
でデータベース内容をGUIで確認可能 - スキーマ変更時は新しいマイグレーションを作成
Prisma のマイグレーション機能により、データベーススキーマの変更を安全かつ確実に管理できます。
参考
関連