If you've got 15 minutes to spare and have docker installed, this Gist will get you started with a working debuggable Nestjs application using Docker with additional settings for vscode
. Clearly you'll want to dig deeper, but this is a start...
Nestjs is a popular nodejs
for typescript
framework for building microservices. It enjoys a large active community, has many extensions and is easily extended. Documentation can be found here
Create the basic file structure from the Github Gist
> mkdir my-proj
> cd my-proj
> mkdir .vscode
> touch .env
> curl -LO https://gist.github.com/leopoldodonnell/6a6eedbdaa314f76f6a1349665dca698/raw/APlaceToStart.md
> curl -LO https://gist.github.com/leopoldodonnell/6a6eedbdaa314f76f6a1349665dca698/raw/docker-compose.yml
> curl -LO https://gist.github.com/leopoldodonnell/6a6eedbdaa314f76f6a1349665dca698/raw/nodemon-debug.json
> curl -LO https://gist.github.com/leopoldodonnell/6a6eedbdaa314f76f6a1349665dca698/raw/nodemon.json
> curl -L -o .vscode/launch.json https://gist.github.com/leopoldodonnell/6a6eedbdaa314f76f6a1349665dca698/raw/vscode-launch.json
Initialize the project
> docker-compose run app /bin/sh
/app # yarn add --global-folder node_modules @nestjs/cli
Lots of output
/app # rm package.json
/app # npx nest generate application ./
CREATE /.prettierrc (51 bytes)
CREATE /README.md (3370 bytes)
CREATE /nest-cli.json (64 bytes)
CREATE /package.json (1687 bytes)
CREATE /tsconfig.build.json (97 bytes)
CREATE /tsconfig.json (336 bytes)
CREATE /tslint.json (426 bytes)
CREATE /src/app.controller.spec.ts (617 bytes)
CREATE /src/app.controller.ts (274 bytes)
CREATE /src/app.module.ts (249 bytes)
CREATE /src/app.service.ts (142 bytes)
CREATE /src/main.ts (208 bytes)
CREATE /test/app.e2e-spec.ts (630 bytes)
CREATE /test/jest-e2e.json (183 bytes)
/app # yarn install
Output from the install
/app # exit
Start the application
> docker-compose up
2:30:28 PM - Starting compilation in watch mode...
app_1 | yarn run v1.19.1
app_1 | $ nest start --debug --watch
app_1 |
app_1 |
app_1 | 2:32:14 PM - Found 0 errors. Watching for file changes.
app_1 | Debugger listening on ws://127.0.0.1:9229/ce9b0bf7-9a8c-4751-94c7-1ff292bf3478
app_1 | For help, see: https://nodejs.org/en/docs/inspector
app_1 | [Nest] 38 - 12/20/2019, 2:32:25 PM [NestFactory] Starting Nest application...
app_1 | [Nest] 38 - 12/20/2019, 2:32:25 PM [InstanceLoader] AppModule dependencies initialized +69ms
app_1 | [Nest] 38 - 12/20/2019, 2:32:25 PM [RoutesResolver] AppController {/}: +74ms
app_1 | [Nest] 38 - 12/20/2019, 2:32:25 PM [RouterExplorer] Mapped {/, GET} route +15ms
app_1 | [Nest] 38 - 12/20/2019, 2:32:25 PM [NestApplication] Nest application successfully started +11ms
Note: Startup is initially slow as all of your source will be compiled and the debugger started.
Test It!
> curl http://localhost:3000
Hello World!>
> docker-compose run app npm run test
> docker-compose run app npm run test:e2e
> docker-compose run app npn run test:cov
Debug It!
Update package.json
to export the debug port out of Docker by updating the start:debug
script.
"start:debug": "nest start --debug=0.0.0.0 --watch",
Restart the service with ^c
and docker-compose up
Once it has started you can swith to debug mode in .vscode
or your chrome browser and set a break point. Set one in the default controller action getHello()
in src/app.controller.ts
then curl the end point curl http://localhost:3000
and your breakpoint will be triggered.
Make a Change
Update src/app.controller.ts
to look as follows...
import { Controller, Get, Logger } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
Logger.log('At getHello()');
return this.appService.getHello();
}
}
Once you saved this change, your service should restart and you are ready to debug your updated code!
That's It Start building on your application.
Nest Steps
- Adding a Config Service
- Validating request Data
- Swagger Documentation
Mounting the app:
... This goes against the immutable nature of Docker images and is actually an opportunity for a security risk (i.e.- if you escape a container or bridge the same network it is possible to inject whatever you want into that volume). You would be better off providing a Dockerfile and publishing a build on Dockerhub.
Then if the user wants to add customizations to the app, they can always create a new Dockerfile using the FROM directive.