0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Docker Compose】Node.js / TypeScript / PostgreSQL 環境でのマイグレーション

Posted at

はじめに

この記事では、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 を以下のように設定します。

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "CommonJS",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "types": ["node"]
  }
}

.gitignore 設定

.gitignore ファイルを作成して、不要なファイルをバージョン管理から除外します。

.gitignore
node_modules
dist/
.env

ソースコードの実装

HTTP サーバーを起動して、利用ポートのログを出力するコードを実装します。

src/index.ts
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 起動スクリプトを追加します。

package.json
{
  ...
  "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接続可能
  • コンテナ間通信可能
compose.yaml
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.yamlports: - "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 のマイグレーション機能により、データベーススキーマの変更を安全かつ確実に管理できます。

参考

関連

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?