Contents

Jak konteneryzować aplikacje Nest.js przy użyciu Docker i Docker Compose

“Ale to działa na moim komputerze…” żart deweloperów doskonale podkreśla wyzwania związane z wdrażaniem i uruchamianiem aplikacji w różnych systemach.

Poruszanie się po złożoności konfiguracji zależności i zgodności wersji może być zniechęcającym zadaniem dla programistów. Istnieje jednak skuteczne podejście, które może złagodzić te wyzwania, wykorzystując technologie konteneryzacji, takie jak Docker. Podejście to upraszcza proces poprzez hermetyzację wszystkich niezbędnych komponentów w samodzielnym środowisku, zmniejszając w ten sposób potencjalne konflikty i usprawniając procesy wdrażania.

Platforma umożliwia użytkownikom płynne wdrażanie i uruchamianie aplikacji, wraz z ich wymaganymi komponentami, w środowisku konteneryzowanym; eliminując w ten sposób konieczność skomplikowanych procedur konfiguracji w ustawieniach produkcyjnych.

Zrozumienie Docker i Docker Compose

Docker to platforma programistyczna typu open source, która zapewnia technologię konteneryzacji wykorzystywaną do tworzenia i pakowania aplikacji wraz z ich zależnościami w postaci przenośnych obrazów.

Wspomniane wcześniej wizualizacje są następnie wykonywane w postaci wykonywalnych modułów w ramach samodzielnych ustawień statku. Wdrożenie aplikacji w takich warunkach zapewnia jednolitość pod względem wydajności dla różnych platform produkcyjnych, pozbawionych potencjalnych rozbieżności lub przeszkód w interoperacyjności.

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

Docker Compose służy jako instrument pomocniczy w połączeniu z Dockerem, ułatwiając usprawnienie procesów konfiguracji i zarządzania aplikacjami wielokontenerowymi.

Docker Compose rozszerza funkcjonalność Dockera, umożliwiając zarządzanie wieloma kontenerami, które wspólnie tworzą pojedynczą aplikację.

Podejście to okazuje się szczególnie korzystne w scenariuszach, w których aplikacja obejmuje wiele współzależnych usług, w tym między innymi różne systemy baz danych, a także wiele usług API o wzajemnych zależnościach.

Zanim zagłębisz się w kod, musisz zainstalować Docker Desktop na swoim komputerze lokalnym. Zapoznaj się z wymaganiami systemowymi i krokami instalacji z oficjalnej dokumentacji.

Kod źródłowy tego oprogramowania można znaleźć w jego repozytorium GitHub, które służy jako cyfrowy system archiwizacji i wersjonowania do śledzenia zmian w programie w czasie.

Konfiguracja projektu Nest.js

Niniejszy samouczek opisuje procedurę wdrażania dwóch kontenerów Docker w tandemie, aby działały jako ujednolicona aplikacja Nest.js. Początkowy kontener będzie hostował instancję obrazu Docker serwera WWW Nest.js, a kolejny kontener będzie uruchamiał obraz bazy danych PostgreSQL Dockera.

Aby zainicjować proces, konieczne jest zainstalowanie narzędzia Nest.js Command Line Interface (CLI). Zapewni to wygodny sposób interakcji z projektem i wykonywania różnych poleceń z terminala.

 npm i -g @nestjs/cli 

Aby utworzyć nowy projekt Nest.js za pomocą Terminala, wykonaj następujące polecenie w oknie Terminala:

 nest new docker-nest-app 

Po wybraniu opcji “Utwórz projekt” zostanie wyświetlona lista dostępnych menedżerów pakietów. W tym momencie należy wybrać żądany. Dla przykładu wybierzmy “npm”, który jest menedżerem pakietów Node.

Na koniec można przejść do katalogu projektu i uruchomić serwer deweloperski.

 cd docker-nest-app
npm run start 

Utwórz moduł bazy danych

Najpierw zainstaluj te zależności:

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

W katalogu głównym projektu utwórz w nim plik “.env” i wstaw kolejne konfiguracje połączenia z bazą danych:

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

Na koniec przystąp do tworzenia modułu bazy danych.

 nest g module database 

Po utworzeniu nowego modułu w Visual Studio Code, uzyskaj dostęp do pliku “database/database.module.ts” i włącz kolejny kod ustawień bazy danych w następujący sposób:

 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 {} 

Po wdrożeniu określonej konfiguracji Docker PostgreSQL w konfiguracji TypeORM aplikacja Nest.js powinna pomyślnie połączyć się z bazą danych.

Zaktualizuj plik app.module.ts

Na koniec zmodyfikuj główny plik modułu aplikacji, aby zintegrować ustawienia modułu bazy danych.

 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 {} 

Konfiguracja pliku Dockerfile

Plik Dockerfile służy jako plan określający niezbędne kroki do skonstruowania obrazu Docker, który zawiera kod źródłowy aplikacji wraz ze wszystkimi wymaganymi zależnościami.

W głównym folderze projektu zainicjuj tworzenie nowego dokumentu i przypisz mu nazwę “Dockerfile”. Następnie włącz kolejne składniki do jego zakresu:

 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" ] 

Oto, co reprezentuje każde polecenie:

Powyższa dyrektywa określa podstawę, na której Docker ma skonstruować wizualną reprezentację oprogramowania, znaną jako obraz.

Powyższa dyrektywa nakazuje, aby folder /app został wyznaczony jako aktywny obszar roboczy dla operacji aplikacji w ramach kontenera Docker.

Plik package.json automatycznie kopiuje wszystkie pliki w określonym formacie z bieżącego katalogu projektu do folderu “app” w ramach procesu konfiguracji.

Wspomniany krok obejmuje wykonanie polecenia “npm install”, które ułatwia instalację wszystkich niezbędnych pakietów i zależności wymaganych do prawidłowego funkcjonowania aplikacji w ramach kontenera Docker.

Docker jest poinstruowany, aby replikować całą zawartość pliku źródłowego aplikacji obecnego katalogu roboczego w wyznaczonym podkatalogu “/app” za pomocą tej dyrektywy.

Aby uruchomić aplikację Nest.js, sugerowanym krokiem jest najpierw zainicjowanie procesu kompilacji poprzez uruchomienie polecenia npm run build . Czynność ta polega na transpilacji kodu źródłowego TypeScript do odpowiadającego mu odpowiednika JavaScript przy użyciu określonych ustawień wstępnych i wtyczek. Jednocześnie tworzy zoptymalizowany pakiet w folderze dist do dalszego wdrażania lub wykonywania.

Podany tekst opisuje instrukcję pliku Dockerfile, która określa polecenie do wykonania po uruchomieniu kontenera. W szczególności kieruje wykonaniem polecenia npm run start:dev, które inicjuje serwer w stanie rozwojowym.

Wyżej wymieniona konfiguracja umożliwia aplikacji pilne obserwowanie zmian w jej kodzie źródłowym. Po zidentyfikowaniu jakichkolwiek modyfikacji, kontener jest zaprogramowany do zainicjowania automatycznego procesu rekonstrukcji.

Utwórz plik Docker Compose

W katalogu głównym obszaru roboczego projektu zainicjuj tworzenie nowego dokumentu docker-compose.yml w tym katalogu. Następnie dołącz kolejne postanowienia do tego nowo utworzonego pliku:

 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: 

Docker Compose wykorzysta dostarczone wytyczne do skonstruowania i wykonania dwóch obrazów Docker w dwóch oddzielnych kontenerach Docker. Początkowy kontener, oznaczony jako “serwer”, będzie służył jako platforma do hostowania obrazu aplikacji i będzie dostępny przez port 3000.

Drugi kontener będzie zawierał obraz bazy danych PostgreSQL, który zostanie skonstruowany przy użyciu istniejącego obrazu PostgreSQL z repozytorium obrazów Docker. Nie jest wymagany osobny plik Dockerfile, ponieważ niezbędne instrukcje są już zawarte we wstępnie zbudowanym obrazie.

Start the Docker Containers

Podsumowując, w celu skonstruowania obrazów i uruchomienia kontenerów należy wykonać poniższe polecenie:

 docker compose up 

Po pomyślnym wykonaniu procesu oczekuje się, że porównywalny zestaw danych dziennika zostanie wyświetlony na wyjściu terminala systemu.

83514143428

Rzeczywiście, po uruchomieniu zarówno serwera WWW, jak i kontenera bazy danych, nadszedł czas na dalsze rozszerzenie możliwości naszej aplikacji Nest.js. Jednym z takich ulepszeń może być stworzenie przyjaznego dla użytkownika interfejsu do interakcji z danymi przechowywanymi w bazie danych PostgreSQL przy użyciu interfejsu API CRUD (Create, Read, Update, Delete) RESTful opartego na frameworku Nest.js.

Przesyłanie obrazów Docker do Docker Hub

Przesyłanie obrazów Docker do Docker Hub bardzo przypomina przesyłanie projektów do GitHub. Aby przesłać obraz Docker aplikacji Nest.js, wykonaj poniższy proces:

⭐ Przejdź do Docker Hub , zarejestruj się i zaloguj na stronie przeglądu swojego konta.

⭐ Kliknij przycisk Utwórz repozytorium, wpisz nazwę repozytorium, określ jego widoczność, wybierając opcję Publiczny lub Prywatny , a następnie kliknij Utwórz . /pl/images/docker-hub-1.jpg

⭐ Teraz musisz zalogować się na swoje konto za pośrednictwem terminala, uruchamiając poniższe polecenie, a następnie podaj swoją nazwę użytkownika i hasło Docker.

 docker login 

⭐ Następnie zaktualizuj nazwę obrazu Dockera, aby pasowała do tego formatu: / , uruchamiając poniższe polecenie.

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

⭐ Na koniec wypchnij obraz Docker.

 docker push <image>/<repo name> 

Wykorzystanie technologii konteneryzacji Docker w rozwoju

Możliwości konteneryzacji Docker pozwalają na łączenie aplikacji, wraz z ich wymaganymi zależnościami, w obrazy Docker. Gwarantuje to, że obrazy te działają płynnie w różnych ustawieniach programistycznych i produkcyjnych, nie napotykając żadnych komplikacji ani problemów z kompatybilnością.