Dockerを利用してNestJS+TypeORM+MySQLの環境構築する
こんにちは、新人エンジニアのtakuです。
わかりやすさだけを追求して記事を書いていきます。
Githubを載せておくので、ご自由にご利用ください。
すぐに環境構築が完了できるようにしています
目次
- NestJSとはなにか?
- docker上でNestJSを起動する
- 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の作成
それぞれのファイルを作成して、以下の内容を追記します。
FROM node:16.13.1-alpine
RUN npm i -g @nestjs/cli
WORKDIR /api
version: "3.8"
services:
api:
container_name: api
build: .
tty: true
ports:
- "3000:3000"
volumes:
- type: bind
source: .
target: /api
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に以下を追記しておきましょう。
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コンテナを立ち上げる
以下のように、追記します
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
に以下を追記します。
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
ファイルを追加し、以下の内容を加えます。
[
{
"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/"
}
}
]
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 エラーがでなくなったの変更しました
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