Contents

Cách chứa các ứng dụng Nest.js bằng Docker và Docker Compose

“Nhưng nó hoạt động trên máy tính của tôi…” trò đùa của nhà phát triển nhấn mạnh một cách hoàn hảo thách thức của việc triển khai và chạy các ứng dụng trên các hệ thống khác nhau.

Việc giải quyết sự phức tạp của cấu hình phụ thuộc và khả năng tương thích của phiên bản có thể là một nhiệm vụ khó khăn đối với các nhà phát triển. Tuy nhiên, có một cách tiếp cận hiệu quả có thể giảm bớt những thách thức này bằng cách sử dụng các công nghệ container hóa như Docker. Cách tiếp cận này đơn giản hóa quy trình bằng cách đóng gói tất cả các thành phần cần thiết trong một môi trường khép kín, từ đó giảm xung đột tiềm ẩn và hợp lý hóa quy trình triển khai.

Nền tảng này trao quyền cho người dùng triển khai và thực thi các ứng dụng một cách liền mạch, cùng với các thành phần cần thiết của chúng, trong môi trường được đóng gói; do đó loại bỏ sự cần thiết của các quy trình thiết lập phức tạp trong cài đặt sản xuất.

Tìm hiểu về Docker và Docker Compose

Docker là một nền tảng phát triển nguồn mở cung cấp công nghệ container hóa được sử dụng trong việc xây dựng và đóng gói các ứng dụng cùng với các phần phụ thuộc của chúng dưới dạng hình ảnh di động.

Các hình ảnh trực quan nói trên sau đó được thực hiện dưới dạng các mô-đun có thể thực thi được trong cài đặt tàu khép kín. Việc triển khai các ứng dụng trong các giới hạn như vậy đảm bảo tính đồng nhất về hiệu suất nhất quán cho các nền tảng sản xuất đa dạng, không có bất kỳ sự khác biệt tiềm ẩn hoặc trở ngại nào về khả năng tương tác.

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

Docker Compose đóng vai trò như một công cụ phụ trợ khi được sử dụng cùng với Docker, tạo điều kiện hợp lý hóa quy trình quản lý và thiết lập ứng dụng đa vùng chứa.

Docker Compose mở rộng chức năng của Docker bằng cách cho phép quản lý nhiều vùng chứa tạo thành một ứng dụng duy nhất.

Cách tiếp cận này tỏ ra đặc biệt thuận lợi trong các tình huống trong đó ứng dụng phần mềm liên quan đến nhiều dịch vụ phụ thuộc lẫn nhau, bao gồm nhưng không giới hạn ở các hệ thống cơ sở dữ liệu khác nhau, cũng như nhiều dịch vụ API có sự phụ thuộc lẫn nhau.

Trước khi đi sâu vào mã, bạn cần cài đặt Docker Desktop trên máy cục bộ của bạn. Xem qua các yêu cầu dành riêng cho hệ thống và các bước cài đặt từ tài liệu chính thức.

Người ta có thể định vị mã nguồn của phần mềm này trong kho lưu trữ GitHub của nó, đóng vai trò như một hệ thống lưu trữ và lập phiên bản kỹ thuật số để theo dõi các thay đổi của chương trình theo thời gian.

Thiết lập dự án Nest.js

Hướng dẫn này sẽ mô tả quy trình triển khai song song hai vùng chứa Docker để hoạt động như một ứng dụng Nest.js hợp nhất. Vùng chứa ban đầu sẽ lưu trữ bản khởi tạo hình ảnh Docker của máy chủ web Nest.js và vùng chứa tiếp theo sẽ chạy hình ảnh cơ sở dữ liệu PostgreSQL của Docker.

Để bắt đầu quá trình, cần phải cài đặt tiện ích Giao diện dòng lệnh (CLI) Nest.js. Điều này sẽ cung cấp một phương tiện thuận tiện để tương tác với dự án của bạn và thực hiện các lệnh khác nhau từ thiết bị đầu cuối.

 npm i -g @nestjs/cli 

Để thiết lập dự án Nest.js mới bằng Terminal, hãy thực hiện lệnh sau trong cửa sổ Terminal:

 nest new docker-nest-app 

Khi chọn’Tạo dự án’, một danh sách các trình quản lý gói có sẵn sẽ được hiển thị. Vui lòng chọn cái mong muốn vào lúc này. Để làm ví dụ, chúng ta hãy chọn’npm’, đó là Trình quản lý gói nút.

Cuối cùng, người ta có thể điều hướng đến thư mục của dự án và khởi động máy chủ phát triển.

 cd docker-nest-app
npm run start 

Tạo mô-đun cơ sở dữ liệu

Đầu tiên, cài đặt các phụ thuộc này:

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

Trong thư mục chính của dự án của bạn, hãy thiết lập tệp “.env” trong đó và chèn các cấu hình tiếp theo cho kết nối cơ sở dữ liệu:

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

Cuối cùng, tiến hành tạo mô-đun cơ sở dữ liệu.

 nest g module database 

Sau khi tạo một mô-đun mới trong Visual Studio Code, hãy truy cập vào tệp “database/database.module.ts” và kết hợp mã cài đặt cơ sở dữ liệu tiếp theo như sau:

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

Khi triển khai cấu hình Docker PostgreSQL được chỉ định trong quá trình thiết lập TypeORM, ứng dụng Nest.js của bạn sẽ kết nối thành công với cơ sở dữ liệu.

Cập nhật tệp app.module.ts

Cuối cùng, sửa đổi tệp mô-đun ứng dụng chính để tích hợp cài đặt cho mô-đun cơ sở dữ liệu.

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

Thiết lập tệp Docker

Dockerfile đóng vai trò như một bản thiết kế chỉ định các bước cần thiết để xây dựng hình ảnh Docker, bao gồm mã nguồn của ứng dụng cùng với tất cả các phần phụ thuộc cần thiết của nó.

Trong thư mục chính của dự án của bạn, hãy bắt đầu tạo một tài liệu mới và gán cho nó ký hiệu “Dockerfile”. Sau đó, kết hợp các thành phần tiếp theo trong phạm vi của nó:

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

Đây là ý nghĩa của mỗi lệnh:

Chỉ thị nói trên quy định nền tảng mà Docker được hướng dẫn xây dựng phần trình bày trực quan của phần mềm, được gọi là hình ảnh.

Lệnh nói trên chỉ định rằng thư mục /app được chỉ định làm không gian làm việc hoạt động cho các hoạt động của ứng dụng trong giới hạn của vùng chứa Docker.

Tệp pack.json tự động sao chép tất cả các tệp ở định dạng đã chỉ định từ thư mục dự án hiện tại sang thư mục “ứng dụng”, như một phần của quy trình cấu hình của nó.

Bước nói trên liên quan đến việc thực thi lệnh “npm install”, lệnh này tạo điều kiện thuận lợi cho việc cài đặt tất cả các gói và phần phụ thuộc cần thiết cần thiết để ứng dụng hoạt động bình thường trong giới hạn của vùng chứa Docker.

Docker được hướng dẫn sao chép tất cả nội dung tệp nguồn ứng dụng của thư mục làm việc hiện tại trong thư mục con’/app’được chỉ định bằng lệnh này.

Để thực thi ứng dụng Nest.js, bước được đề xuất trước tiên là bắt đầu quá trình xây dựng bằng cách chạy lệnh npm run build. Hành động này liên quan đến việc dịch mã nguồn TypeScript sang mã JavaScript tương ứng bằng cách sử dụng các cài đặt trước và plugin được chỉ định. Đồng thời, nó tạo ra một gói được tối ưu hóa trong thư mục dist cho các mục đích triển khai hoặc thực thi tiếp theo.

Văn bản đã cho mô tả lệnh Dockerfile chỉ định lệnh sẽ được thực thi khi vùng chứa được khởi động. Cụ thể, nó chỉ đạo việc thực thi lệnh npm run start:dev, khởi tạo máy chủ ở trạng thái phát triển.

Cấu hình nói trên cho phép ứng dụng phần mềm giám sát chặt chẽ các thay đổi trong mã nguồn của nó. Sau khi xác định bất kỳ sửa đổi nào, vùng chứa được lập trình để bắt đầu quá trình xây dựng lại tự động.

Tạo tệp soạn thảo Docker

Trong thư mục chính của không gian làm việc dự án của bạn, hãy bắt đầu tạo tài liệu docker-compose.yml mới trong thư mục đã nói. Sau đó, thêm các quy định tiếp theo vào tệp mới được thành lập này:

 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 sẽ sử dụng các nguyên tắc được cung cấp để xây dựng và thực thi hai hình ảnh Docker trong hai vùng chứa Docker riêng biệt. Vùng chứa ban đầu, được chỉ định là “máy chủ”, sẽ đóng vai trò là nền tảng để lưu trữ hình ảnh của ứng dụng và có thể truy cập được qua cổng 3000.

Vùng chứa thứ hai sẽ chứa hình ảnh cơ sở dữ liệu PostgreSQL, hình ảnh này sẽ được xây dựng bằng hình ảnh PostgreSQL hiện có từ kho hình ảnh của Docker. Không cần Dockerfile riêng biệt vì các hướng dẫn cần thiết đã được cung cấp trong hình ảnh dựng sẵn.

Khởi động Docker Container

Tóm lại, để xây dựng hình ảnh và khởi chạy các thùng chứa, hãy thực hiện lệnh tiếp theo:

 docker compose up 

Sau khi thực hiện thành công quy trình, dự kiến ​​một tập hợp dữ liệu nhật ký có thể so sánh sẽ được hiển thị ở đầu ra cuối của hệ thống của bạn.

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

Thật vậy, khi cả máy chủ web và vùng chứa cơ sở dữ liệu đều hoạt động, đã đến lúc mở rộng hơn nữa khả năng của ứng dụng Nest.js của chúng tôi. Một cải tiến như vậy có thể là xây dựng giao diện thân thiện với người dùng để tương tác với dữ liệu được lưu trữ trong cơ sở dữ liệu PostgreSQL bằng API RESTful CRUD (Tạo, Đọc, Cập nhật, Xóa) được xây dựng trên khung Nest.js.

Đẩy Docker Image vào Docker Hub

Việc chuyển hình ảnh Docker sang Docker Hub gần giống với việc gửi dự án lên GitHub. Để tải hình ảnh Docker của ứng dụng Nest.js lên, vui lòng làm theo quy trình sau:

⭐ Truy cập Docker Hub, đăng ký và đăng nhập vào trang tổng quan về tài khoản của bạn.

⭐ Nhấp vào nút Tạo kho lưu trữ, điền tên kho lưu trữ của bạn, chỉ định mức độ hiển thị của nó bằng cách chọn Công khai hoặc Riêng tư , sau đó nhấp vào Tạo. /vi/images/docker-hub-1.jpg

⭐ Bây giờ, bạn cần đăng nhập vào tài khoản của mình qua thiết bị đầu cuối bằng cách chạy lệnh bên dưới, sau đó cung cấp tên người dùng và mật khẩu Docker của bạn.

 docker login 

⭐ Tiếp theo, cập nhật tên hình ảnh của Docker để phù hợp với định dạng này:/bằng cách chạy lệnh bên dưới.

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

⭐ Cuối cùng, đẩy hình ảnh Docker.

 docker push <image>/<repo name> 

Sử dụng Công nghệ Containerization của Docker trong quá trình phát triển

Khả năng đóng gói của Docker cho phép đóng gói các ứng dụng cùng với các phần phụ thuộc cần thiết của chúng vào hình ảnh Docker. Điều này đảm bảo rằng những hình ảnh này hoạt động liền mạch trên nhiều cài đặt sản xuất và phát triển khác nhau mà không gặp phải bất kỳ sự phức tạp hoặc vấn đề tương thích nào.