Skip to content

Instantly share code, notes, and snippets.

@leopoldodonnell
Last active July 15, 2021 19:43
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save leopoldodonnell/6a6eedbdaa314f76f6a1349665dca698 to your computer and use it in GitHub Desktop.
Nestjs Startup

Nestjs In Under 15 Minutes

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

  1. Adding a Config Service
  2. Validating request Data
  3. Swagger Documentation
# Documentation
# https://docs.docker.com/compose/compose-file
version: '3'
services:
app:
image: node:dubnium-alpine
restart: always
working_dir: /app
command:
- yarn
- start:debug
env_file:
- "./.env"
ports:
- 3000:3000
- 9229:9229
volumes:
- $PWD:/app
networks:
- backend
networks:
backend:
driver: bridge
{
"watch": ["src"],
"ext": "ts",
"ignore": ["src/**/*.spec.ts"],
"exec": "node --inspect-brk -r ts-node/register -r tsconfig-paths/register src/main.ts"
}
{
"watch": ["dist"],
"ext": "js",
"exec": "node dist/main"
}
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Docker: Attach to Node",
"remoteRoot": "/app",
"port": 9229,
"localRoot": "${workspaceFolder}",
"protocol": "inspector",
"restart": true,
}
]
}
@lynsei
Copy link

lynsei commented Nov 29, 2020

Mounting the app:

    volumes:
      - $PWD:/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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment