Skip to content

Deploy Postgres (render)

En este tutorial vamos a desplegar una aplicación de NestJS con Postgres en render. Además te dejo un video con el paso a paso:

docker-compose.yml

sh
version: "3.8"
services:
  postgresDB:
    image: postgres:14.1-alpine
    restart: always
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=db_crud
    volumes:
      - ./postgres:/var/lib/postgresql/data
    ports:
      - "5436:5432"

Install

sh
yarn add pg
js
TypeOrmModule.forRoot({
  type: 'postgres',
  host: 'localhost',
  port: 5436,
  username: 'postgres',
  password: 'postgres',
  database: 'db_crud',
  autoLoadEntities: true,
  synchronize: true,
}),

Variables de entorno

sh
yarn add @nestjs/config

src\app.module.ts

ts
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
  ],
})
export class AppModule {}

.env

sh
POSTGRES_HOST="localhost"
POSTGRES_PORT=5436
POSTGRES_USERNAME="postgres"
POSTGRES_PASSWORD="postgres"
POSTGRES_DATABASE="db_crud"
POSTGRES_SSL="false"

src\app.module.ts

ts
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { TypeOrmModule } from "@nestjs/typeorm";
import { AuthModule } from "./auth/auth.module";
import { BreedsModule } from "./breeds/breeds.module";
import { CatsModule } from "./cats/cats.module";
import { UsersModule } from "./users/users.module";

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    TypeOrmModule.forRoot({
      type: "postgres",
      host: process.env.POSTGRES_HOST,
      port: parseInt(process.env.POSTGRES_PORT),
      username: process.env.POSTGRES_USERNAME,
      password: process.env.POSTGRES_PASSWORD,
      database: process.env.POSTGRES_DATABASE,
      autoLoadEntities: true,
      synchronize: true,
      ssl: process.env.POSTGRES_SSL === "true",
      extra: {
        ssl:
          process.env.POSTGRES_SSL === "true"
            ? {
                rejectUnauthorized: false,
              }
            : null,
      },
    }),
    CatsModule,
    BreedsModule,
    UsersModule,
    AuthModule,
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

main.ts

ts
await app.listen(parseInt(process.env.PORT) || 3000);

package.json

json
"start:prod": "node dist/main",

Versión de node.js

sh
node -v

JWT secret

.env

sh
JWT_SECRET="no utilizar esta palabra en producción"

JwtModule.registerAsync

jwt#async-options

src\auth\auth.module.ts

ts
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { JwtModule } from "@nestjs/jwt";
import { UsersModule } from "src/users/users.module";
import { AuthController } from "./auth.controller";
import { AuthService } from "./auth.service";

@Module({
  imports: [
    UsersModule,
    ConfigModule,
    JwtModule.registerAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        secret: configService.get<string>("JWT_SECRET"),
        signOptions: { expiresIn: "1d" },
        global: true,
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [AuthController],
  providers: [AuthService],
  exports: [JwtModule],
})
export class AuthModule {}

AuthGuard

src\auth\guard\auth.guard.ts

ts
try {
  const payload = await this.jwtService.verifyAsync(token);
  request.user = payload;
} catch {
  throw new UnauthorizedException();
}

Modules

src\cats\cats.module.ts

ts
imports: [TypeOrmModule.forFeature([Cat]), BreedsModule, AuthModule],

src\breeds\breeds.module.ts

ts
imports: [TypeOrmModule.forFeature([Breed]), AuthModule],

forwarRef

src\users\users.module.ts

ts
imports: [TypeOrmModule.forFeature([User]), forwardRef(() => AuthModule)],

Ahora a tener fe 🙌🏽