Debugging Nest.js (TypeScript) in a Docker Container

# はじめに
TypeScriptのフルスタックサーバーサイドフレームワークである、知る人ぞ知る [Nest.js](https://docs.nestjs.com/) を Docker で動作させてリモートデバッグする方法をまとめました。

英語の練習したかったので英語で書いてみました。（書き味はほぼ[AWS Amplify](https://aws-amplify.github.io/docs/js/start)のドキュメントのパクリです。）

TypeScript と Docker が重なるといろいろめんどくさかったです。

ソースは → [ここ](https://github.com/rema424/nestjs-docker-vscode-debugging) ← に置いてます。

# Debugging Nest.js in a Docker Container

This recipe shows how to run and debug a VS Code Nest.js, Full Stack TypeScript Framework, project in a Docker container.

The recipe assumes that you have a recent version of Docker installed.

## Step 1. Create a New App

With the following commands, create the directory (`nest-js-app`) and files for the app.

```
$ mkdir nest-js-app && cd nest-js-app
$ touch Dockerfile docker-compose.yml .dockerignore
```

The app directory structure should be:

```
- nest-js-app
    - .dockerignore
    - .gitignore
    - docker-compose.yml
    - Dockerfile
```

Add the following to the `Dockerfile` file:

```docker:Dockerfile
FROM node:8.10.0

RUN mkdir -p /nest
ADD . /nest
WORKDIR /nest

RUN npm i -g @nestjs/cli
```

Add the following to the `docker-compose.yml` file:

```yml:docker-compose.yml
version: "3"

services:
  nest:
    build: .
    volumes:
      - .:/nest
    ports:
      - 3000:3000
      - 9229:9229
    tty: true
```

Add the following to the `.gitignore` file:

```bash:.gitignore
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Coverage directory used by tools like istanbul
coverage

# Dependency directories
node_modules/

# Output files
dist

# dotenv environment variables file
.env
```

Add the following to the `.dockerignore` file:

```bash:.dockerignore
.git
.github
.vscode
coverage
docker-compose.yml
README.md

# Node Files #
node_modules
npm-debug.log
npm-debug.log.*
```

Build docker image:

```
$ docker-compose build
```

Start and login to the container:

```
$ docker-compose up -d
$ docker-compose exec nest bash
```

Scaffold the base project with the `Nest CLI` and install dependencies:

```
# nest new .
# npm install
```

Run the app:

```
# npm start
```

Open a browser and navigate to `http://localhost:3000`.
You should see the `Hello world!` message.

## Step 2. Set up the debugging environment

With the following commands, create the directory (`.vscode`) and files for debugging.

```
# mkdir .vscode && touch .vscode/launch.json nodemon-docker-debug.json
```

The app directory structure should be:

![スクリーンショット 2018-11-11 5.03.17.png](https://qiita-image-store.s3.amazonaws.com/0/237863/a59c4adc-645e-2cdd-1abd-c95a7e00fe68.png)


Add the following to the `launch.json` file:

```json:.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Docker: Attach to Node",
      "type": "node",
      "request": "attach",
      "port": 9229,
      "address": "localhost",
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "/nest",
      "protocol": "inspector",
      "restart": true
    }
  ]
}
```

Add the following to the `nodemon-docker-debug.json` file:

```json:nodemon-docker-debug.json
{
  "watch": ["src"],
  "ext": "ts",
  "ignore": ["src/**/*.spec.ts"],
  "exec": "tsc && node --inspect=0.0.0.0 ./dist/main.js"
}
```

Add the following line into the scripts block of the `package.json` file:

```json:package.json
"scripts": {
  "debug": "nodemon -L --config nodemon-docker-debug.json",

}
```

## Step 3. Debugging

For the test operation, add some codes into the `src/app.service.ts` and set breakpoints as below.

![スクリーンショット 2018-11-11 4.39.50.png](https://qiita-image-store.s3.amazonaws.com/0/237863/a70ddee3-164a-677f-6586-3990e6de6e14.png)

Run the app in debugging mode:

```
# npm run debug
```

![スクリーンショット 2018-11-11 11.52.41.png](https://qiita-image-store.s3.amazonaws.com/0/237863/931c42c5-26a8-2952-4eec-33087b543bae.png)


Start the debug on the VScode.

![スクリーンショット 2018-11-11 4.44.01.png](https://qiita-image-store.s3.amazonaws.com/0/237863/f32fc1ac-8ac5-f301-b4fb-feb01be524a4.png)

Open a browser and navigate to `http://localhost:3000`.
You should see the program stop at the breakpoints.

![スクリーンショット 2018-11-11 4.52.37.png](https://qiita-image-store.s3.amazonaws.com/0/237863/2d02ff7c-ef44-cc32-b204-232c388531b1.png)

Happy coding!

# Reference
[Debugging TypeScript in a Docker Container](https://github.com/Microsoft/vscode-recipes/tree/master/Docker-TypeScript)
[nodemon](https://github.com/remy/nodemon#nodemon)
[npmのコマンドを同時実行する](https://qiita.com/takeo-asai/items/f1099b8bc5046da5e87b)
[Is there a way to use npm scripts to run tsc -watch && nodemon --watch?
](https://stackoverflow.com/questions/38276862/is-there-a-way-to-use-npm-scripts-to-run-tsc-watch-nodemon-watch/38695935#38695935)