🐈

Dockerを利用してNestJS+TypeORM+MySQLの環境構築する

2021/10/31に公開

こんにちは、新人エンジニアのtakuです。
わかりやすさだけを追求して記事を書いていきます。

Githubを載せておくので、ご自由にご利用ください。
すぐに環境構築が完了できるようにしています
https://github.com/takuya-mashimo/nest-sample


目次

  1. NestJSとはなにか?
  2. docker上でNestJSを起動する
  3. TypeORMを利用してMySQLと接続する

NestJSとはなにか?


Nest (NestJS) は効率的でスケーラブルなNode.jsサーバーサイドアプリケーションを構築する為のフレームワークです。

最新のJavascriptで構築され、Typescriptを完全にサポートしています。

中身を見れば、Nestは(デフォルトでは)Expressのような堅牢なHTTPサーバーフレームワークを利用していて、オプションでFastifyを使用する事も可能です。

もし、NestJSのアーキテクチャの全体感を掴みたい方はpotato4dさんの以下の記事が参考になると思います
触って覚えるNestJSのアーキテクチャ


また、公式ドキュメント等は以下です


docker上でNestJSを起動する

ファイル構成

project-path
    |- docker-compose.yml
    |- Dockerfile
    |- .dockerignore
    |- nestのmodule達

Dockerfileとdocker-compose.ymlの作成



それぞれのファイルを作成して、以下の内容を追記します。

Dockerfile
FROM node:16.13.1-alpine
RUN npm i -g @nestjs/cli
WORKDIR /api
docker-compose.yml
version: "3.8"
services:
  api:
    container_name: api
    build: .
    tty: true
    ports:
      - "3000:3000"
    volumes:
      - type: bind
        source: .
        target: /api
.dockerignore
node_modules

nodeイメージをベースにして、nestjs/cliをインストールをしています。


イメージを構築し、コンテナを起動するために以下のコマンドを入力します。

docker compose up -d --build

コンテナが起動しているか、確認します。

docker compose ps


こんな表示になっていればOKです。

NAME                COMMAND                  SERVICE             STATUS              PORTS
api                 "docker-entrypoint.s…"   api                 running             0.0.0.0:3000->3000/tcp

以下のコマンドを入力して、Nestプロジェクトをdockerコンテナ内のカレントディレクトリに作成します。

docker compose exec api nest new .

どのパッケージマネージャーを使用しますか?

と聞かれるので、npmを選択します。

これで、サーバーを起動する準備はできました。
以下のコマンドを入力して、サーバーを起動しましょう。

docker compose exec api npm run start:dev

にアクセスすると、Hello World!と表示されたら、起動成功です!

毎回、npm run start:devと打つのはめんどくさいので、Dockerfileに以下を追記しておきましょう。

Dockerfile
FROM node:latest
RUN npm i -g @nestjs/cli
WORKDIR /api
+ CMD ["npm", "run", "start:dev"]

イメージの構築をし直して、コンテナを立ち上げ直します

docker compose up -d --build


TypeORMを利用してMySQLと接続する

docker-compose.ymlに追記して、MySQLコンテナを立ち上げる

以下のように、追記します

docker-compose.yml
version: "3.7"
services:
  api:
    container_name: api
    build: .
    tty: true
    ports:
      - "3000:3000"
    volumes:
      - type: bind
        source: .
        target: /api
+ mysql:
+   image: mysql/mysql-server:5.7
+   command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
+   ports:
+     - '3306:3306'
+   environment:
+     MYSQL_ROOT_PASSWORD: password
+     MYSQL_DATABASE: develop
+     MYSQL_USER: user
+     MYSQL_PASSWORD: password
+   volumes:
+     - /var/lib/mysql

typeORMはMySQLの5系しか対応していなかったはずです。。。

では、コンテナを立ち上げ直しましょう。

docker compose up -d

正常に立ち上がっているかの確認です。

docker compose ps

以下のようになっていればOKです

NAME                COMMAND                  SERVICE             STATUS              PORTS
mysql   "/entrypoint.sh --ch…"   mysql               running (healthy)   0.0.0.0:3306->3306/tcp
api                 "docker-entrypoint.s…"   api                 running             0.0.0.0:3000->3000/tcp

これでコンテナの立ち上げは終了です。

TypeORMをインストールして、NestJS内でTypeORMを有効化する

参照先はこちら

以下のコマンドを入力して、TypeORMをインストールします。

docker compose exec api npm install --save @nestjs/typeorm typeorm mysql2

もし、エラーみたいなものがでても大丈夫です。(npmのバージョンによるものです。)
気になるようでしたら、以下のコマンドを入力し、再度TypeORMをインストールしていただければ大丈夫です。参照先

docker compose exec api npm i -g npm@6

(1月時点ではnpmエラーがでなくなりました MacOS Monterey Ver12.1)

次に、ルートモジュールと呼ばれるapp.module.tsに以下を追記します。

app.module.ts
import { Module } from '@nestjs/common';
+ import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
+   TypeOrmModule.forRoot(),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

さらに、ルートディレクトリにormconfig.jsonファイルを追加し、以下の内容を加えます。

ormconfig.json
[
  {
    "type": "mysql",
    "host": "mysql",
    "port": 3306,
    "username": "user",
    "password": "password",
    "database": "develop",
    "synchronize": true,
    "entities": ["src/entity/*.entity.{ts,js}"],
    "migrations": ["src/migration/*.ts"],
    "cli": {
      "migrationsDir": "src/migration/"
    }
  }
]



ormconfig.ts
import { MysqlConnectionOptions } from 'typeorm/driver/mysql/MysqlConnectionOptions';

const options: MysqlConnectionOptions = {
  type: 'mysql',
  host: 'mysql',
  port: 3306,
  username: 'user',
  password: 'password',
  database: 'mysql', //dockerのdb名
  entities: ['dist/src/**/*.entity.js'],
  migrations: ['dist/migration/**/*.migration.js'],
  cli: {
    migrationsDir: 'migration',
  },
};

module.exports = options;



entitiesの参照先とmigrationsの参照先を直接jsを参照することによって、typeormのimport statement エラーがでなくなったの変更しました

app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import * as ormConfig from '../ormconfig';
import { PostsModule } from './posts/posts.module';

@Module({
  imports: [TypeOrmModule.forRoot(ormConfig)],
  controllers: [],
  providers: [],
})
export class AppModule {}

これで、環境構築は終了です! お疲れ様でした!!😄

Discussion