Contents

Como colocar aplicativos Nest.js em contêineres usando o Docker e o Docker Compose

“Mas funciona no meu computador…” A piada do programador realça na perfeição o desafio de implementar e executar aplicações em diferentes sistemas.

Navegar pelas complexidades da configuração de dependências e da compatibilidade de versões pode ser uma tarefa assustadora para os programadores. No entanto, existe uma abordagem eficaz que pode aliviar esses desafios, utilizando tecnologias de contentorização como o Docker. Esta abordagem simplifica o processo, encapsulando todos os componentes necessários num ambiente autónomo, reduzindo assim potenciais conflitos e agilizando os processos de implementação.

A plataforma permite que os utilizadores implementem e executem aplicações sem problemas, juntamente com os componentes necessários, num ambiente de contentores, evitando assim a necessidade de procedimentos de configuração complexos nas definições de produção.

Compreender o Docker e o Docker Compose

O Docker é uma plataforma de desenvolvimento de código aberto que fornece tecnologia de contentorização utilizada na criação e empacotamento de aplicações juntamente com as suas dependências como imagens portáteis.

As imagens acima mencionadas são subsequentemente executadas sob a forma de módulos executáveis em configurações de contentores autónomos. A implementação de aplicações dentro de tais limites garante uniformidade em termos de consistência de desempenho para diversas plataformas de produção, sem quaisquer discrepâncias potenciais ou obstáculos à interoperabilidade.

/pt/images/ship-with-containers.jpg

O Docker Compose funciona como um instrumento auxiliar quando utilizado em conjunto com o Docker, facilitando a simplificação dos processos de configuração e gestão de aplicações em vários contentores.

O Docker Compose estende a funcionalidade do Docker, permitindo a gestão de vários contentores que formam coletivamente uma aplicação singular.

Esta abordagem revela-se especialmente vantajosa em cenários em que uma aplicação de software envolve vários serviços interdependentes, incluindo, entre outros, vários sistemas de bases de dados, bem como vários serviços API com dependências mútuas.

Antes de mergulhar no código, você precisa instalar o Docker Desktop no seu computador local. Consulte os requisitos específicos do sistema e as etapas de instalação na documentação oficial.

É possível localizar o código-fonte deste software no seu repositórioGitHub, que serve como um sistema de arquivo digital e de controlo de versões para acompanhar as alterações ao programa ao longo do tempo.

Configurar um projeto Nest.js

Este tutorial delineará o procedimento para implantar dois contêineres do Docker em conjunto para funcionar como um aplicativo Nest.js unificado. O contêiner inicial deve hospedar uma instanciação da imagem do Docker do servidor Web Nest.js, e o contêiner subsequente deve executar a imagem do banco de dados PostgreSQL do Docker.

Para iniciar o processo, é necessário instalar o utilitário Nest.js Command Line Interface (CLI). Isto fornecerá um meio conveniente de interagir com o seu projeto e executar vários comandos a partir do terminal.

 npm i -g @nestjs/cli 

Para estabelecer um novo projeto Nest.js utilizando o Terminal, execute o seguinte comando na janela do Terminal:

 nest new docker-nest-app 

Ao selecionar “Criar projeto”, será apresentada uma lista de gestores de pacotes disponíveis. Por favor, seleccione o desejado neste momento. Para fins de exemplo, vamos optar pelo ’npm’, que é o gerenciador de pacotes do Node.

Por último, pode navegar para o diretório do projeto e iniciar o servidor de desenvolvimento.

 cd docker-nest-app
npm run start 

Criar o módulo de base de dados

Primeiro, instalar estas dependências:

 npm install pg typeorm @nestjs/typeorm @nestjs/config 

No diretório primário do seu projeto, crie um ficheiro “.env” no mesmo e insira as configurações subsequentes para a ligação à base de dados:

 DATABASE_HOST="db"
DATABASE_PORT=5432
DATABASE_USER="testUser"
DATABASE_PASSWORD="mypassword123" 

Por fim, proceda à criação do módulo da base de dados.

 nest g module database 

Depois de criar um novo módulo no Visual Studio Code, aceda ao ficheiro “database/database.module.ts” e incorpore o código de configurações da base de dados subsequente, como se segue:

 import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';


 @Module({
  imports: [
    ConfigModule.forRoot(),
     TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
       useFactory: async (configService: ConfigService) => ({
        type: 'postgres',
        host: configService.get<string>('DATABASE_HOST'),
         port: configService.get<number>('DATABASE_PORT'),
        username: configService.get<string>('DATABASE_USER'),
        password: configService.get<string>('DATABASE_PASSWORD'),
        synchronize: true,
      }),
      inject: [ConfigService],
     }),
  ],
})

export class DatabaseModule {} 

Após implementar a configuração especificada do Docker PostgreSQL em sua configuração do TypeORM, seu aplicativo Nest.js se conectará com êxito ao banco de dados.

Atualizar o arquivo app.module.ts

Por fim, modifique o arquivo do módulo principal do aplicativo para integrar as configurações do módulo do banco de dados.

 import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DatabaseModule } from './database/database.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: '.env',
     }),
    DatabaseModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})

export class AppModule {} 

Configurar um Dockerfile

Um Dockerfile serve como um modelo que especifica as etapas necessárias para construir uma imagem do Docker, que incorpora o código-fonte do aplicativo junto com todas as dependências necessárias.

Na pasta principal do seu projeto, inicie a criação de um novo documento e atribua-lhe a designação “Dockerfile”. Posteriormente, incorpore os seguintes constituintes no seu âmbito:

 FROM node:16.3.0-alpine3.13
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD [ "npm", "run", "start:dev" ] 

Eis o que cada comando representa:

A diretiva acima mencionada estipula a base sobre a qual o Docker é instruído a construir a representação visual do software, conhecida como imagem.

A diretiva mencionada anteriormente determina que a pasta /app seja designada como o espaço de trabalho ativo para as operações do aplicativo dentro dos limites do contêiner do Docker.

O arquivo package.json copia automaticamente todos os arquivos dentro do formato especificado do diretório atual do projeto para a pasta “app”, como parte de seu processo de configuração.

O passo acima mencionado envolve a execução do comando “npm install”, que facilita a instalação de todos os pacotes e dependências necessários para o funcionamento correto da aplicação dentro dos limites do contentor Docker.

O Docker é instruído a replicar todo o conteúdo do ficheiro de origem da aplicação do diretório de trabalho atual no subdiretório ‘/app’ designado, através desta diretiva.

Para executar a aplicação Nest.js, o passo sugerido é iniciar primeiro o processo de compilação, executando o comando npm run build . Essa ação envolve a transpilação do código-fonte TypeScript para seu equivalente JavaScript correspondente usando as predefinições e os plug-ins especificados. Ao mesmo tempo, produz um pacote optimizado dentro da pasta dist para fins de implementação ou execução.

O texto fornecido descreve uma instrução Dockerfile que especifica o comando a ser executado quando o contentor é iniciado. Especificamente, ele direciona a execução de um comando npm run start:dev, que inicia o servidor em seu estado de desenvolvimento.

A configuração acima mencionada permite que a aplicação de software observe diligentemente as alterações no seu código-fonte. Ao identificar quaisquer modificações, o contentor é programado para iniciar um processo de reconstrução automática.

Criar o ficheiro Docker Compose

No diretório principal do espaço de trabalho do seu projeto, inicie a criação de um novo documento docker-compose.yml no referido diretório. Depois, anexe as estipulações subsequentes a este ficheiro recém-criado:

 version: '3.9'

services:
  server:
    build: .
    ports:
      - '3000:3000'
    depends_on:
      - db
  db:
    image: 'postgres'
    ports:
      - '5432:5432'
    environment:
      POSTGRES_PASSWORD: 'mypassword123'
      POSTGRES_USER: 'testUser'
    volumes:
      - data:/var/lib/postgresql/data

volumes:
  data: 

O Docker Compose utilizará as diretrizes fornecidas para construir e executar duas imagens Docker em dois contêineres Docker separados. O contentor inicial, designado por “servidor”, servirá de plataforma para alojar a imagem da aplicação e será acessível através da porta 3000.

O segundo contentor alojará a imagem da base de dados PostgreSQL, que será construída utilizando uma imagem PostgreSQL existente a partir do repositório de imagens do Docker. Não é necessário um Dockerfile separado, pois as instruções necessárias já são fornecidas na imagem pré-construída.

Iniciar os contentores Docker

Em conclusão, para construir as imagens e lançar os contentores, execute o comando seguinte:

 docker compose up 

Após a execução bem-sucedida do processo, espera-se que um conjunto comparável de dados de registo seja apresentado na saída do terminal do seu sistema.

/pt/images/started-docker-containers.jpg

De facto, quando os contentores do servidor Web e da base de dados estiverem operacionais, é altura de expandir ainda mais as capacidades da nossa aplicação Nest.js. Uma dessas melhorias poderia ser a construção de uma interface de fácil utilização para interagir com os dados armazenados na base de dados PostgreSQL utilizando uma API RESTful CRUD (Criar, Ler, Atualizar, Eliminar) construída sobre a estrutura Nest.js.

Enviando imagens do Docker para o Docker Hub

A transferência de imagens do Docker para o Docker Hub é muito parecida com o envio de projetos para o GitHub. Para carregar a imagem do Docker do aplicativo Nest.js, siga este processo:

⭐ Vá até Docker Hub , inscreva-se e faça login na página de visão geral da sua conta.

⭐ Clique no botão Criar repositório, preencha o nome do seu repositório, especifique a sua visibilidade seleccionando Público ou Privado e, em seguida, clique em Criar . /pt/images/docker-hub-1.jpg

⭐ Agora, você precisa fazer login na sua conta através do terminal executando o comando abaixo e, em seguida, fornecer seu nome de usuário e senha do Docker.

 docker login 

⭐ Em seguida, atualize o nome da imagem do Docker para corresponder a este formato: / executando o comando abaixo.

 docker tag <image> <your docker username>/<repo name> 

⭐ Por fim, envie a imagem do Docker.

 docker push <image>/<repo name> 

Utilizando a tecnologia de conteinerização do Docker no desenvolvimento

Os recursos de conteinerização do Docker permitem o agrupamento de aplicativos, juntamente com suas dependências necessárias, em imagens do Docker. Isso garante que essas imagens funcionem perfeitamente em várias configurações de desenvolvimento e produção sem encontrar complicações ou problemas de compatibilidade.