twitter-backend-node icon indicating copy to clipboard operation
twitter-backend-node copied to clipboard

Dockerization Support and Externalised Configs

Open subhatanay opened this issue 4 years ago • 10 comments

Added externalised configuration with @nestjs/config. Added Dockerfile to create image for twitter-node-backend project Added docker-compose.yml file to run the project and postgres database in one run. Updated README.MD file for docker instruction,

subhatanay avatar Jul 15 '21 20:07 subhatanay

@championswimmer @ohbus @subhatanay

Here's one way of how we could dockerize the entire application and keep track of different environments easily.

  • [x] Dockerfile
# Specify the base image
FROM node:14-alpine

# Create app directory, this is in our container/in our image
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./

# If you are building your code for production
# RUN npm ci --only=production
RUN npm install

# Bundle app source
COPY . .

# Build the app
RUN npm run build

# Set the node env to production
ENV NODE_ENV=production

# Expose the necessary port
EXPOSE 3000

# * This is a wait script which you're
# * required to execute before you run
# * your app

# ? Reason:
# * Even if your db instance starts up,
# * it still takes some time to get
# * ready to accept connections from
# * your API, so this wait script takes
# * care of it by applying a retry logic
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.5.0/wait /wait
RUN chmod +x /wait

# Finally, run your app
CMD /wait && npm run start:prod


  • [x] docker-compose.yml
version: '3'
services:
  api:
    build: .
    ports:
      - '3000:3000'
    depends_on:
      - db
    environment:
      WAIT_HOSTS: db:5432

  db:
    image: postgres:13-alpine
    ports:
      - '5432:5432'
    volumes:
      - './db-data:/var/lib/postgresql/data'
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}


  • [x] .dockerignore
.dockerignore
.git
.gitignore
node_modules
.env*
.vscode
npm-debug.log
Dockerfile*
docker-compose*
README.md
LICENSE
dist


  • [x] .env.dev
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=mooadmin
POSTGRES_PASSWORD=moopass
POSTGRES_DB=moodb
PORT=3000
ADDRESS=127.0.0.1


  • [x] .env.production
POSTGRES_HOST=db
POSTGRES_PORT=5432
POSTGRES_USER=mooadmin
POSTGRES_PASSWORD=moopass
POSTGRES_DB=moodb
PORT=3000
ADDRESS=0.0.0.0


  • [x] app.module.ts
@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: process.env.NODE_ENV
        ? `.env.${process.env.NODE_ENV}`
        : '.env.dev',
    }),
    TypeOrmModule.forRoot({
      type: 'postgres',
      host: process.env.POSTGRES_HOST,
      port: process.env.POSTGRES_PORT as unknown as number,
      username: process.env.POSTGRES_USER,
      password: process.env.POSTGRES_PASSWORD,
      database: process.env.POSTGRES_DB,
      synchronize: true,
      logger: 'advanced-console',
      logging: 'all',
      entities: [UserEntity, PostEntity, PasswordEntity, SessionsEntity],
    }),
    UsersModule,
    PostsModule,
    HashtagsModule,
    AuthModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}


  • [x] main.ts
  await app.listen(process.env.PORT, process.env.ADDRESS);


  • [x] package.json
{
  "name": "twitter-backend-node",
  "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/src/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest --config ./jest-e2e.json",
    "test:watch": "jest --watch",
    "test:cov": "jest --config ./jest-e2e.json --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": "^7.6.15",
    "@nestjs/config": "^1.0.0",
    "@nestjs/core": "^7.6.15",
    "@nestjs/platform-fastify": "^7.6.18",
    "@nestjs/swagger": "^4.8.1",
    "@nestjs/typeorm": "^7.1.5",
    "bcrypt": "^5.0.1",
    "fastify-compress": "^3.6.0",
    "fastify-swagger": "^4.8.0",
    "pg": "^8.6.0",
    "pg-hstore": "^2.3.4",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^6.6.6",
    "typeorm": "^0.2.34"
  },
  "devDependencies": {
    "@nestjs/cli": "^7.6.0",
    "@nestjs/schematics": "^7.3.0",
    "@nestjs/testing": "^7.6.15",
    "@types/bcrypt": "^5.0.0",
    "@types/jest": "^26.0.22",
    "@types/node": "^14.14.36",
    "@types/supertest": "^2.0.10",
    "@typescript-eslint/eslint-plugin": "^4.19.0",
    "@typescript-eslint/parser": "^4.19.0",
    "eslint": "^7.22.0",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-prettier": "^3.3.1",
    "jest": "^26.6.3",
    "prettier": "^2.2.1",
    "supertest": "^6.1.3",
    "ts-jest": "^26.5.4",
    "ts-loader": "^8.0.18",
    "ts-node": "^9.1.1",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^4.2.3"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}



after docker compose after-docker-compose


after health check after-health-check


after create-user request after-create-user

alpha037 avatar Jul 17 '21 16:07 alpha037

The dockerfile @alpha037 suggested is better, it takes care of the pg spinup time

championswimmer avatar Jul 25 '21 13:07 championswimmer

@alpha037 @ohbus any updates on this ?

championswimmer avatar Aug 04 '21 15:08 championswimmer

@alpha037 @ohbus any updates on this ?

Haven't heard back from @subhatanay yet. Let's wait for a couple of days and see if he modifies his PR accordingly, otherwise I'll raise one, if that's okay.

alpha037 avatar Aug 04 '21 16:08 alpha037

Sorry for late reply ... I will push this by tomorrow

subhatanay avatar Aug 04 '21 20:08 subhatanay

Hi @alpha037 I have used the suggestion you provided. please check and let me know any issue.

subhatanay avatar Aug 05 '21 21:08 subhatanay

Please check now.

subhatanay avatar Aug 05 '21 21:08 subhatanay

Hi @alpha037 addressed your comment. Please check now thanks

subhatanay avatar Aug 06 '21 15:08 subhatanay

Hi @ohbus can this PR be merged? or do you want more changes?

let me know thanks

subhatanay avatar Aug 09 '21 19:08 subhatanay

Hi @ohbus can this PR be merged? or do you want more changes?

let me know thanks

@championswimmer you may merge this.

ohbus avatar Aug 11 '21 11:08 ohbus