はじめに
NestJS の環境を Docker コンテナを使って作成しようとしたところ、NestJS とTypeORM の最新バージョンが上がっていました。
せっかくなので、最新のバージョンを使いましたが、断片的な情報しかなくて結構苦労しました。
これから触る方に参考となればと思い、一通り全ての作業記録を載せておきます。
指定した主なバージョンは次のとおりです。
mac を使用していますが windows でも基本的には変わらないと思います。
ライブラリ | バージョン |
---|---|
Node.js | 16.17.0 |
NestJS | 9.1.2 |
TypeORM | 0.3.9 |
MySQL | 8.0 |
<参考記事>
・TypeORM 0.3系のマイグレーション
・NestJSをTypeORM 0.3 で使う
・NestJS公式 - Database
・Dockerを利用してNestJS+TypeORM+MySQLの環境構築する
・NestJSとDockerコンテナで立ち上げたMySQLサーバーを接続する
・NestJS + TypeORM + MySQL を使ってテーブルを作ってみる
・NestJS 入門コース3 DBとCRUD
1. 準備
1-1. NestJS のインストール
Node.js がインストールされていることが前提です(Node のインストールは省略します)。
手元のバージョンは次のとおりです(現在の LTS)。
$ node -v
v16.17.0
バージョンアップなどは次の記事を参照ください。
・n (Node.js管理) のインストール手順
NestJS は次のコマンドでインストール(またはアップグレード)します。バージョンは 9.1.2
を指定しています(エラーが出たら sudo を付けて実行してみてください)。
$ npm i -g @nestjs/cli@9.1.2
なお、これを書いている時点では、$ npm i -g @nestjs/cli
で v9.1.2 がインストールされます。
nest -v
でバージョンの確認ができます。
$ nest -v
9.1.2
1-2. NestJS プロジェクト作成
適当なフォルダを選んで NestJS のプロジェクトを1つ作ります。
プロジェクト名を nest-docker-sample として次のコマンドを実行します。
$ nest new nest-docker-sample
コマンドを実行すると、どの package manager を使用するか聞かれますので、ここでは npm を選びます。
しばらくすると、プロジェクトが作成されます。
2. Dockerfile と docker-compose.yml の作成
プロジェクトが作成されたら、ルートディレクトリ直下に3つのファイル(Dockerfile
, docker-compose.yml
, .dockerignore
)を作成します(下図)。
nest-docker-sample
├──Dockerfile # 作成
├──docker-compose.yml # 作成
├──.dockerignore # 作成
├──package.json
├──package-lock.json
└──(...先に作成したその他の nest のファイル)
<参考記事>
・いまさらだけどDockerに入門したので分かりやすくまとめてみた
2-1. Dockerfile
2-1-1. 基本的な記載事項(最小限の内容)
Dockerfile に記載する基本的な内容は次のとおりです。
なお、この内容では、コンテナ内で git を使用することはできません。
FROM node:16-alpine3.16
WORKDIR /api
COPY package*.json ./
RUN npm ci
COPY . .
指定している内容は、ざっと次のとおりです。
コマンド(命令) | 概要 | 備考 |
---|---|---|
FROM | ベースイメージを指定します。 | ここでは、Node.js の公式 Docker イメージを使用しています(OS は alpine※)。 |
WORKDIR | コンテナ内での「コマンドの実行場所」を指定します。 | ここでは /api と指定しています。 |
COPY | 左側にコピー元(ホスト側) 右側にコピー先(コンテナ側) のディレクトリを指定します。 |
① COPY package*.json ./ コピー元の package*.json は、package.json と package-lock.json の2つのファイルです。コピー先の ./ は上記の WORKDIR の直下(つまり /api/ )です。② COPY . . ホスト側に作成したファイルをコンテナにコピーしています。 |
RUN | 実行するコマンドを指定します。 | コンテナに COPY された package.json と package-lock.json を元にライブラリをインストールします。 |
※ alpine は厳密には OS そのものではないですが、ここでは OS と呼んでおきます(参考: Linuxディストリビューション)。
2-1-2. git をインストールする場合
コンテナ内でも git を使用する場合は、次のように記載してください(詳細は「5. Git について」参照)。
FROM node:16-alpine3.16
RUN apk update && \
apk add bash git make && \
apk add --upgrade grep
RUN git clone https://github.com/awslabs/git-secrets /home/alpine/git-secrets
WORKDIR /home/alpine/git-secrets
RUN make && make install
WORKDIR /api
COPY package*.json ./
RUN npm ci
COPY . .
2-1-3. Nest CLI をインストールする場合
コンテナ内で nest g module
などの nest のコマンドを実行する必要がある場合は、Nest CLI もインストールしておきます。
以下のように、npm ci && npm i -g @nestjs/cli@9.1.2
とすれば、Nest CLI もインストールされます。
FROM node:16-alpine3.16
RUN apk update && \
apk add bash git make && \
apk add --upgrade grep
RUN git clone https://github.com/awslabs/git-secrets /home/alpine/git-secrets
WORKDIR /home/alpine/git-secrets
RUN make && make install
WORKDIR /api
COPY package*.json ./
RUN npm ci && \
npm i -g @nestjs/cli@9.1.2
COPY . .
2-2. docker-compose.yml
docker-compose.yml には次のように記載します。
version: '3.8'
services:
api:
build:
context: .
dockerfile: Dockerfile
restart: always
ports:
- 3000:3000
tty: true
volumes:
- type: bind
source: .
target: /api
depends_on:
- db
db:
image: mysql:8.0
restart: always
ports:
- 3306:3306
environment:
MYSQL_DATABASE: sample
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: user
MYSQL_PASSWORD: password
volumes:
- ./db/data:/var/lib/mysql
指定した内容をざっと書き出すと次のとおりです。
項目 | 内容 | 備考 |
---|---|---|
version: | Compose ファイルのバージョン です。 | 今は 3 とか 3.8 で良いようです。 |
service: | 以下に、コンテナの定義を記載します。 | ここでは、service 名をapi と db とした2つのコンテナを作成しています。 |
build: | 指定された Dockerfile から、Docker イメージを作成します。 |
context: ワーキングディレクトリを指定dockerfile: ドッカーファイルのファイル名(ディレクトリ)を指定 |
restart: | コンテナの再起動について指定します。 | |
ports: | 左側にホスト側のポート、右側にコンテナ側のポートを指定します。 | MySQL のホスト側の port を変えたい場合は、3307:3306 のように記載します(ここの修正のみでOKで、後掲の data-source.ts の修正は不要です。参考)。 |
tty: | コンテナを起動させ続けるために記載します | 参考:DockerのTTYって何? |
volumes: | ホスト側のデータと、docker コンテナ側のデータをバインドさせます。 |
① long syntaxtype: マウントの種類を指定source: ホスト側ディレクトリを指定target: コンテナ側ディレクトリを指定② short syntax 左側: ホスト側のディレクトリを指定 右側: コンテナ側のディレクトリを指定 |
environment: | 環境変数を指定します。 |
MYSQL_DATABASE: DB 名MYSQL_ROOT_PASSWORD: root のパスワードMYSQL_USER: ユーザー名MYSQL_PASSWORD: ユーザーのパスワード |
depends_on: | サービス間の依存関係を指定します。 |
api: depends_on: - db この例では api より前に db が起動することになります。 |
コンテナが消えても DB の内容を保持できるように、ホスト側に /db
というディレクトリを作成して、MySQL のデータを保存するようにしています。
保存場所については、Docker の volume に保存する方法もありますので、そのあたりは他のサイトなどで確認してみてください(ここでは行いません)。
volumes:
- ./db/data:/var/lib/mysql
<参考サイト>
・Compose ファイル・リファレンス
・docker-compose.ymlの書き方について解説してみた
2-3. その他のファイル
2-3-1. .dockerignore
.dockerignore ファイルには、Dockerのビルド時に無視するディレクトリ(ファイル)を指定します。
.git/
node_modules/
db/
先述のとおり db/
には、MySQL のコンテナ内のデータを保存していますので、これを更に api
コンテナ側に保存しないようにしています。
2-3-2. .gitignore に1行追加
.gitignore
ファイルにも、/db
を追加しておきます。
# compiled output
/dist
/node_modules
/db # これを追加
# 以下略
2-4. Docker の起動確認
プロジェクトのルートディレクトリに移動します。
次のコマンドで、docker を起動させます。
$ docker compose up -d
docker ps
コマンドでコンテナが起動しているか確認します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
78918ab18ad4 nest-docker-sample_api "docker-entrypoint.s…" 36 seconds ago Up 33 seconds 0.0.0.0:3000->3000/tcp nest-docker-sample-api-1
3fdc62a476f7 mysql:8.0 "docker-entrypoint.s…" 36 seconds ago Up 35 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp nest-docker-sample-db-1
確認のため、npm run start
コマンドでサーバを起動してみます。
コンテナ内でコマンドを実行するので、頭に docker compose exec api
を付けています(api
は docker-compose.yml ファイルで指定した service名です。)。
$ docker compose exec api npm run start
無事に実行できれば、次のように表示されます。
http://localhost:3000/ にアクセスして「Hello World!」が表示されればコンテナの起動は成功です。
作業を続けるため、一旦、Ctrl + C でサーバを停止します。
3. VSCode Remote-Container
ここでは、VSCode Remote-Container を使用します。
特に必須の内容ではなく、コンテナ内に入ってコマンドが実行できれば良いので、不要な人は「4. TypeORM の導入」に進んでください。
<参考記事>
・VSCode Remote Containerが良い
・VS Code Remote - Containers を Docker Compose で使うのだー!
・みんながきっと1万回は聞いている、VS Code Remoteでコンテナ開発をやる方法
3-1. コンテナでのコマンド実行方法の確認
コンテナでのコマンド実行方法は、いくつかあります。
① コンテナの外からコマンドを実行する場合(参考)
コンテナに対してコマンドを実行するには、実行したいコマンドの前に、docker compose exec <service名>
と付ければ操作できます(servise名は docker-compose.yml で指定した名称となります)。
以下は、npm run start
を実行する例です(ここでは採用しません)。
$ docker compose exec api npm run start
② コンテナに入ってコマンドを実行する場合(参考)
次のコマンドで、コンテナに入れば、docker compose exec api と頭に付けなくとも操作できます(ここでは採用しません)。
$ docker exec -it <コンテナID> sh
OS(Linuxディストリビューション) で ubuntu を使用する場合は、末尾は bash
ですが、ここでは alpine を使用しているので sh
となっています。
③ Remote-Container を使用する
ここでは、手軽にコンテナに入るために、Remote-Container を使用します。
導入方法は、次項以下のとおりです。
3-2. Remote-Container の導入
3-2-1. インストール
VSCode の拡張機能として、以下の Remote-Container をインストールします。
3-2-2. VSCode でコンテナを開く
① Remote-Container の使用
インストールが完了すると、VSCode の左下に緑のアイコンが表示されますので、これをクリックします。
② 操作の選択
選択肢が現れますので、Reopen in Container を選択します。
③ Remote-Container を実行するファイルを選択
From 'docker-compose.yml' を選択します。
④ service名を選択
service 名を聞かれますので、api
を選択します。
この service 名は、docker-compose.yml で指定した service 名となります。
⑤ WorkSpace の選択(※自動で選択されなかった場合)
Workspace が存在しないというメッセージが出てきたら、Open Workspace をクリックします。
(※おそらく、Dockerfile の WORKDIR と、docker-compose.yml のservice 名が同じだとこの事象が生じてしまいます。)
フォルダーは /api
を選択して、OK をクリックします。
この /api
は、Dockerfile の WORKDIR で指定したディレクトリです。
初期設定は以上です。
3-2-3. 状態の確認と若干の補正
コンテナに入ると、次のような画面になっています。
① ターミナル
入力部分が 78918ab18ad4:/api#
というようになっています。
これは <コンテナID>:<service名>#
の形式で、ここで直接コンテナに対してコマンドを打つことができます。
78918ab18ad4:/api#
なお「78918ab18ad4:/workdir#」となる場合もありますが、そちらも正常なので問題はありません。
② 作成されるファイル
Remote-Containerを導入すると、ルートの直下にディレクトリ .devcontainer
と2つのファイルが作成されます。
nest-docker-sample
├─ .devcontainer
│ ├── devcontainer.json
│ └── docker-compose.yml
└──(...その他のファイル)
③ WorkSpace のディレクトリを修正(※自動で選択されなかった場合)
前項の「⑤ WorkSpace の選択(※自動で選択されなかった場合)」に当てはまった場合は、次のように修正しておきます(自動でディレクトリが選択される場合は不要です)。
devcontainer.json ファイルに "workspaceFolder" を指定するプロパティがあるので、ここを "/workspace" から "/api" に書き換えます。
# 書き換え前
"workspaceFolder": "/workspace"
# 書き換え後
"workspaceFolder": "/api"
/api
は、Dockerfile の WORKDIR で指定したディレクトリです。
3-2-4. Remote-Container の終了と再実行
Remote-Container を終了するには、左下の緑の部分をクリックして、Close Remote Connection
を選択します。
再度コンテナの中に入るには、左下の緑のアイコンをクリックして、Reopen in Container を選択します。
3-3. 拡張機能(ESLint, Prettier)をコンテナに追加する
コンテナ内に拡張機能を追加するには、次のように devcontainer.json ファイルの extensions
に拡張機能の識別子を追加します。
{
// 略
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
// 略
}
拡張機能の識別子は、それぞれの拡張機能の画面の右下(下図赤枠のところ)に表示されていますので、それを使用します。
<一度コンテナを立ち上げた後に拡張機能を追加した場合>
私の場合、ESLint の警告(赤い波線)が表示されず不便であったため、後から extensions を追加しました。
その際に、ファイルを書き換えただけでは反映されなかったため、次のことを試すことで VSCode に反映されました(2つのうちどちらか不要かもしれません)。
①docker compose down
で一回コンテナを削除して、再度 Reopen in Container に入る。
②VSCode の Reload Window(Cmmand + shift + P で検索)で画面を再読み込みする。
<参考>
今回の設定を行うと、devcontainer.json の全体は次のようになります。
{
"name": "Existing Docker Compose (Extend)",
"dockerComposeFile": [
"../docker-compose.yml",
"docker-compose.yml"
],
"service": "api",
"workspaceFolder": "/api",
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
4. TypeORM の導入
これから行う作業が完了した後の src
ディレクトリは、おおよそ次のようにります。
📦src
┣ 📂entities
┃ ┗ 📜comment.entity.ts
┣ 📂migration
┃ ┗ 📜1663429464503-CommentMigration.ts
┣ 📜app.controller.ts
┣ 📜app.module.ts
┣ 📜app.service.ts
┣ 📜data-source.ts
┗ 📜main.ts
追加していくファイルは、①comment.entity.ts
、②1663429464503-CommentMigration.ts
(ファイル名は毎回異なる)、③data-source.ts
の3つです。
また、app.module.ts
を一部修正することになります。
4-1. TypeORM のインストール
次のコマンドで TypeORM のバージョンを指定してインストールします。
# npm install --save @nestjs/typeorm typeorm@0.3.9 mysql2
これを書いている時点では、typeorm@0.3.9
のところを typeorm
というようにバージョンを指定しなくとも、同じバージョンの TypeORM がインストールされます。
次のコマンドで、インストールされた TypeORM のバージョンが確認できます。
# npm info typeorm version
0.3.9
参考までに、設定が完了した後の package.json
を貼っておきます。
package.json
{
"name": "nest-docker-sample",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/typeorm": "^9.0.1",
"mysql2": "^2.3.3",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
"typeorm": "^0.3.9"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@types/express": "^4.17.13",
"@types/jest": "28.1.8",
"@types/node": "^16.0.0",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "28.1.3",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "28.0.8",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.1.0",
"typescript": "^4.7.4"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
4-2. Entity の作成
テーブル定義として、テスト用の Entity クラスを作成します。
以下のように、src/entities/
ディレクトリに comment.entity.ts
というファイルを作成しました(中身は適当です)。
これを元に、DB にテーブルが作成されることになります。
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
@Entity()
export class Comment {
@PrimaryGeneratedColumn()
id?: number;
@Column()
body: string;
@CreateDateColumn()
createdAt?: Date;
@UpdateDateColumn()
updatedAt?: Date;
constructor(body: string) {
this.body = body;
}
}
4-3. DataSource の作成
TypeORM v0.3 では、データベースの接続を定義する DataSource ファイルを作成します。
TypeORM v0.2 においては、ormconfig.js
のようなファイルを作成していました(現在は非推奨のようです。)。
src/
ディレクトリの直下に以下のように data-source.ts
ファイルを作成します。
設定内容は、コード中のコメントのとおりです。
import { Comment } from './entities/comment.entity';
import { DataSource } from 'typeorm';
export const AppDataSource = new DataSource({
type: 'mysql', // MySQL の場合
host: 'db', // docker-compose.yml で指定したコンテナの service 名
port: 3306, // ポート番号
username: 'user', // docker-compose.yml の MYSQL_USER
password: 'password', // docker-compose.yml の MYSQL_PASSWORD
database: 'sample', // docker-compose.yml の MYSQL_DATABASE
logging: true, // コンソール画面に実行したSQLが表示される
synchronize: false, // true にすると migration が自動で実行されます。
entities: [Comment], // エンティティクラスを指定する(複数の場合はカンマで区切る)
migrations: ['dist/migration/*.js'], // dist ディレクトリ内の js ファイルを指定する
});
<参考サイト>
・npm - TypeORM
4-4. app.module.ts の修正
DataSource ファイルを読み込むために src/app.module.ts
を編集します。
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm'; // 追加
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AppDataSource } from './data-source'; // 追加
@Module({
imports: [TypeOrmModule.forRoot(AppDataSource.options)], // 修正
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
TypeOrmModule.forRoot() の引数には、DataSource から import した AppDataSource の option プロパティを指定します(AppDataSource.options
)。
4-5. マイグレーションファイルの生成(migration:generate)
マイグレーションファイルの生成コマンド(migration:generate)も書き方が変わっています。
# npx typeorm-ts-node-commonjs migration:generate src/migration/CommentMigration -d src/data-source.ts
冒頭の npx typeorm-ts-node-commonjs migration:generate
は共通です。
次の src/migration/CommentMigration
は、マイグレーションファイルを作成するディレクトリ/ファイル名を指定しています。
最後の -d src/data-source.ts
には、接続情報となる DataSource ファイルを指定しています。
この辺りは、冒頭にも紹介したこの記事を参考とさせていただいています。
コマンドを実行すると、ターミナルに次のような表示がされます。
無事に成功すれば、指定した src/migration/
フォルダに以下のようなマイグレーションファイルができていると思います。
import { MigrationInterface, QueryRunner } from "typeorm";
export class CommentMigration1663489067218 implements MigrationInterface {
name = 'CommentMigration1663489067218'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE \`comment\` (\`id\` int NOT NULL AUTO_INCREMENT, \`body\` varchar(255) NOT NULL, \`createdAt\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), \`updatedAt\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE \`comment\``);
}
}
4-6. マイグレーションの実行(migration:run)
4-6-1. 先にアプリをビルドする
dist の中身を書き換えないと、マイグレーションが実行されないので、実行前に一度ビルドします。
次のコマンドを実行します。
# npm run build
なお、ここではしませんが、npm run start
などでサーバを立ち上げても、dist が更新されます(つまり、dist が更新できれば何でも良いです)。
4-6-2. migration:run
さて、いよいよ migration:run を実行します。
コマンドは、次のとおりです。
# npx typeorm-ts-node-commonjs migration:run -d src/data-source.ts
npx typeorm-ts-node-commonjs migration:run
はコマンド実行時の共通部分です。
-d src/data-source.ts
には、DataSource ファイルを指定します。
コマンドを実行すると、次のようにコンソール画面に表示されます。
無事に実行できたら、サーバを立ち上げてみます。
エラーが起きなければ成功です。
# npm run start
4-7. DB を確認する
4-7-1. MySQL のコンテナに入る
テーブルが作成されているかの確認をしておきます。
Docker コンテナ内のターミナルでは実行できませんので、別途、新しいターミナルを起動させます。
docker ps コマンドで、実行中の MySQL のコンテナ ID を確認します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
78918ab18ad4 nest-docker-sample_api "docker-entrypoint.s…" 4 hours ago Up 29 minutes 0.0.0.0:3000->3000/tcp nest-docker-sample-api-1
3fdc62a476f7 mysql:8.0 "docker-entrypoint.s…" 4 hours ago Up 30 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp nest-docker-sample-db-1
私の手元では、MySQL のコンテナIDは 3fdc62a476f7
なので、次のようにコマンドを実行することで、コンテナの中に入れます。
$ docker exec -it 3fdc62a476f7 sh
4-7-2. DB の内容を確認する
コンテナに入ったら、次のコマンドを実行して、MySQL の操作を開始します。
# mysql -u root -p
パスワードが求められるので、password
と入力します。
いうまでもないですが、このパスワードは、docker-compose.yml の MYSQL_ROOT_PASSWORD
で指定したものです。
無事に、MySQL に入れたら、show databases
コマンドでデータベースの一覧を確認してみます。
次のように sample とあれば OK です。
> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sample |
| sys |
+--------------------+
5 rows in set (0.01 sec)
use コマンドで、sample データベースを選択します。
> use sample;
show tables;
コマンドで、テーブル一覧を確認します。
comment というテーブルがあれば OK です。
> show tables;
+------------------+
| Tables_in_sample |
+------------------+
| comment |
| migrations |
+------------------+
2 rows in set (0.01 sec)
最後に、comment テーブルの定義を確認します。
show create table <テーブル名>
コマンドを実行します。
コマンドの末尾は、;
ではなく \G
とした方が見やすいです。
> show create table comment\G
*************************** 1. row ***************************
Table: comment
Create Table: CREATE TABLE `comment` (
`id` int NOT NULL AUTO_INCREMENT,
`body` varchar(255) NOT NULL,
`createdAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
`updatedAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
以上の感じで、テーブルが作成されていれば成功です。
5. Git について
git をコンテナ内で動作させるのに苦労したため、作業記録を残しておきます。
5-1. git のみインストールした場合
次のように、apk update && apk add bash git
として、git と bash をインストールするだけで、git の使用はできます。
bash をインストールするのは、これがないと git を動作させることができないためです。
FROM node:16-alpine3.16
RUN apk update && \
apk add bash git
WORKDIR /api
COPY package*.json ./
RUN npm ci
COPY . .
ただ、この場合、コンテナ内で git commit を実行しようとすると、次のようなエラーが生じます。
# git commit -m "test commit"
git: 'secrets' is not a git command. See 'git --help'.
これは、git-secrets がコンテナ内にインストールされていないためです。
※暫定処置
リスクが生じますが、コンテナ内で以下のコマンドを実行すれば commit 時に git-secrets を呼び出さないようにすることができます。
# rm -r .git/hooks
git-secrets は、AWS アクセスキーの遺漏を防ぐなどセキュリティ上、大事な役割を果たすものですので、この方法はあまり好ましくないと思われます。
5-2. git と git-secrets をインストールする場合
git と git-secrets をインストールする場合の Dockerfile です。
試行錯誤しましたが、これで git commit や git push などのコマンドを正常に実行することができます。
FROM node:16-alpine3.16
RUN apk update && \
apk add bash git make && \
apk add --upgrade grep
RUN git clone https://github.com/awslabs/git-secrets /home/alpine/git-secrets
WORKDIR /home/alpine/git-secrets
RUN make && make install
WORKDIR /api
COPY package*.json ./
RUN npm ci
COPY . .
① git-secrets をインストールするために make のインストールが必要となります。
② git commit 時に grep でエラーを吐くので、grep のアップグレードも必要となります。
<参考記事>
・moduscreate/alpine-git-secrets
・[alpine] sh: make: not found
・UbuntuからAlpineにイメージを移行して容量を減らす例
・[RFC] Make it work with Alpine Linux / BusyBox grep
さいごに
NestJS と TypeORM v0.3 については、記事があまり見当たらないところなので、備忘として残しておきました。
Docker など、詳しい分野ではないので、間違い等があるかもしれません。
お気づきのことなどあれば、ご教示いただけると幸いです。