DockerとDocker Composeを利用してNest.jsアプリケーションをコンテナ化する

「自分のコンピュータでは動作するのに...」という開発者のジョークは、さまざまなシステムでアプリケーションをデプロイして実行する際の課題を完璧に言い表しています。

面倒なのは、必要な依存関係を設定し、ソフトウェアのバージョンがアプリケーションと互換性があることを確認することです。この問題を解決する優れた回避策は、Dockerなどのコンテナ化技術を使用することです。

コンテナイメージ内に、必要な依存関係をすべて備えたアプリケーションを簡単にデプロイして実行できるため、本番システムで広範囲にわたる設定を行う必要がなくなります。

DockerとDocker Composeについて

Dockerは、コンテナ化技術を提供するオープンソースの開発プラットフォームで、アプリケーションとその依存関係をポータブルなイメージとして構築してパッケージ化するために使用されます。

これらのイメージは、その後、分離されたコンテナ環境内で実行可能なコンポーネントとして実行されます。これらのコンテナ内でアプリケーションを実行すると、互換性の問題が発生することなく、さまざまな本番システムで一貫したアプリケーションのパフォーマンスが保証されます。

一方、Docker Composeは、マルチコンテナアプリケーションの定義と管理のプロセスを簡素化するためにDockerと一緒に使用されるツールです。

Dockerは主に個々のコンテナの管理に使用されますが、Docker Composeを使用すると、1つのアプリケーションとして実行する必要がある複数のコンテナの設定を管理できます。

これは、複数の依存APIサービスやデータベースなど、連携する必要がある複数のサービスで構成されるアプリケーションの場合に特に便利です。

コードに進む前に、ローカルマシンにDocker Desktopをインストールする必要があります。公式ドキュメントからシステム固有の要件とインストール手順を確認してください。

このアプリケーションのコードはGitHubリポジトリで見つけることができます。

Nest.jsプロジェクトの設定

このガイドでは、単一のNest.jsアプリケーションとしてシームレスに機能する2つのDockerコンテナを立ち上げるプロセスについて説明します。最初のコンテナにはNest.js WebサーバーDockerイメージのインスタンスが保持され、2番目のコンテナではDockerのPostgreSQLデータベースイメージが実行されます。

まず、Nest.jsコマンドラインツールをインストールします。

npm i -g @nestjs/cli

次に、ターミナルで以下のコマンドを実行して、新しいNest.jsプロジェクトを作成します。

nest new docker-nest-app

次に、CLIツールは、プロジェクトを作成するために選択できる複数のパッケージマネージャーを表示します。お好みのオプションを選択します。この例では、Node Package Managerであるnpmを使用します。

最後に、プロジェクトディレクトリに移動して開発サーバーを起動できます。

cd docker-nest-appnpm run start

データベースモジュールの作成

最初に、以下の依存関係をインストールします。

npm install pg typeorm @nestjs/typeorm @nestjs/config

次に、プロジェクトのルートディレクトリに.envファイルを作成し、以下のデータベース接続設定値を追加します。

DATABASE_HOST="db"DATABASE_PORT=5432DATABASE_USER="testUser"DATABASE_PASSWORD="mypassword123"

最後に、進んでデータベースモジュールを作成します。

nest g module database

モジュールが作成されたら、database/database.module.tsファイルを開き、以下のデータベース設定コードを含めます。

import { Module } from '@nestjs/common';import { TypeOrmModule } from '@nestjs/typeorm';import { ConfigModule, ConfigService } from '@nestjs/config';@Module({imports: [ConfigModule.forRoot(),TypeOrmModule.forRootAsync({imports: [ConfigModule],useFactory: async (configService: ConfigService) => ({type: 'postgres',host: configService.get('DATABASE_HOST'),port: configService.get('DATABASE_PORT'),username: configService.get('DATABASE_USER'),password: configService.get('DATABASE_PASSWORD'),synchronize: true,}),inject: [ConfigService],}),],})export class DatabaseModule {}

このTypeORM設定を使用してDocker PostgreSQLイメージを設定すると、Nest.jsアプリケーションはデータベースへの接続を確立します。

app.module.tsファイルの更新

最後に、メインのアプリケーションモジュールファイルを更新して、データベースモジュールの設定を組み込みます。

import { Module } from '@nestjs/common';import { ConfigModule } from '@nestjs/config';import { AppController } from './app.controller';import { AppService } from './app.service';import { DatabaseModule } from './database/database.module';@Module({imports: [ConfigModule.forRoot({envFilePath: '.env',}),DatabaseModule,],controllers: [AppController],providers: [AppService],})export class AppModule {}

Dockerfileの設定

Dockerfileは、Dockerイメージを作成するためにDockerエンジンに必要な命令セットをキャプチャします。このイメージには、アプリケーションのソースコードとそのすべての依存関係が含まれます。

プロジェクトのルートディレクトリで新しいファイルを作成し、Dockerfileという名前を付けます。次に、以下の内容を追加します。

各コマンドの意味は次のとおりです。

  1. FROM:この命令は、Dockerがアプリケーションのイメージを構築するために使用するベースイメージを指定します。
  2. WORKDIR:このコマンドは、Dockerに/appディレクトリをコンテナ内のアプリの作業ディレクトリとして設定するように指示します。
  3. COPYpackage*.json./:現在のディレクトリにあるそのファイル名の形式のすべてのファイルをアプリケーションからappフォルダにコピーします。
  4. RUN npm install:このコマンドは、Dockerコンテナ内でアプリケーションに必要なパッケージと依存関係をインストールします。
  5. COPY. .: Dockerに、現在のディレクトリから/appフォルダにアプリケーションのすべてのソースコードファイルをコピーするように指示します。
  6. RUN npm run build:このコマンドは、Dockerイメージを作成する前にNest.jsアプリケーションを構築します。TypeScriptコードをJavaScriptにコンパイルし、ビルドプロセスの出力をdistディレクトリに格納します。
  7. CMD:コンテナが起動したときに実行するコマンドを定義します。この場合、npm run start:devコマンドを実行します。これにより、開発モードでサーバーが起動します。

この設定により、アプリケーションはコードの変更を積極的に監視できるようになります。変更が検出されると、コンテナは自動的に再構築されます。

Docker Composeファイルの作成

プロジェクトフォルダのルートディレクトリで、新しいdocker-compose.ymlファイルを作成し、次のコンテンツを追加します。

version: '3.9'services:server:build: .ports:- '3000:3000'depends_on:- dbdb:image: 'postgres'ports:- '5432:5432'environment:POSTGRES_PASSWORD: 'mypassword123'POSTGRES_USER: 'testUser'volumes:- data:/var/lib/postgresql/datavolumes:data:

Docker Composeは、これらの指示を使用して、2つのDockerコンテナで2つのイメージを構築して実行します。最初のコンテナであるサーバーは、アプリケーションのイメージをホストします。ポート3000で実行されます。

2番目のコンテナは、PostgreSQLデータベースイメージをホストします。このイメージのDockerfileを指定する必要はありません。Dockerは、Dockerのイメージレジストリにある既存のPostgreSQLイメージを使用してイメージを構築します。

Dockerコンテナの起動

最後に、次のコマンドを実行してイメージを構築し、コンテナを起動します。

docker compose up

プロセスが正常に完了すると、ターミナルに同様のログ情報が表示されます。

これで、Webサーバーとデータベースコンテナの両方が起動して実行されているので、Nest.jsアプリケーションにさらに機能を追加することができます。たとえば、Nest.js CRUD REST APIを構築できます。

Docker HubへのDockerイメージのプッシュ

Docker HubにDockerイメージをプッシュする方法は、GitHubにプロジェクトをプッシュする方法とほぼ同じです。次の手順に従って、Nest.jsアプリケーションのDockerイメージをDocker Hubにプッシュします。

  1. Docker Hubにアクセスし、サインアップして、アカウントの概要ページにログインします。
  2. リポジトリの作成ボタンをクリックし、リポジトリの名前を入力し、公開または非公開を選択して表示を指定し、作成をクリックします。
  3. 次に、以下のコマンドを実行してターミナルからアカウントにログインし、Dockerのユーザー名とパスワードを入力する必要があります。
    docker login
  4. 次に、次のコマンドを実行して、Dockerのイメージ名をこの形式に一致させる必要があります。/
    docker tag  /
  5. 最後に、Dockerイメージをプッシュします。
    docker push /

開発でDockerのコンテナ化技術を利用する

Dockerのコンテナ化技術を使用すると、アプリケーションとそのすべての依存関係をDockerイメージにバンドルできます。これらのイメージは、さまざまな開発環境や本番環境のコンテナ内で、問題なくスムーズに実行できます。