0
0
Lập trình
Sơn Tùng Lê
Sơn Tùng Lê103931498422911686980

Hướng Dẫn Docker Hóa Ứng Dụng NestJS Từ A Đến Z: Tối Ưu Hiệu Suất và Bảo Mật

Đăng vào 2 tháng trước

• 5 phút đọc

Chủ đề:

Nextjs

Hướng Dẫn Docker Hóa Ứng Dụng NestJS Từ A Đến Z

Bài viết này sẽ hướng dẫn bạn cách đóng gói ứng dụng NestJS vào một container Docker, giúp ứng dụng chạy ổn định và hiệu quả trong nhiều môi trường khác nhau. Hãy theo dõi qua từng bước chi tiết dưới đây!

Bước 1: Thiết lập Dockerfile

Trước tiên, bạn cần tạo một file Dockerfile trong thư mục gốc của dự án NestJS. File này sẽ chứa các hướng dẫn để xây dựng Docker image. Dưới đây là một mẫu Dockerfile cơ bản:

dockerfile Copy
# Sử dụng Node.js phiên bản 20 làm base image
FROM node:20

# Thiết lập thư mục làm việc trong container
WORKDIR /usr/src/app

# Sao chép package.json và package-lock.json
COPY package*.json ./

# Cài đặt các dependencies
RUN npm install

# Sao chép mã ứng dụng còn lại vào container
COPY . .

# Build ứng dụng
RUN npm run build

# Chạy ứng dụng
CMD ["node", "dist/main.js"]

Dockerfile này thực hiện các tác vụ sau:

  • Sử dụng Node.js phiên bản 20 để làm base image.
  • Thiết lập thư mục làm việc thành /usr/src/app.
  • Sao chép các file package.jsonpackage-lock.json vào thư mục làm việc.
  • Cài đặt các dependencies với lệnh npm install.
  • Sao chép toàn bộ mã ứng dụng vào container.
  • Xây dựng ứng dụng với lệnh npm run build.
  • Chỉ định lệnh chạy ứng dụng bằng node dist/main.js.

Bên cạnh đó, bạn cũng nên tạo một file .dockerignore để loại trừ các file không cần thiết khỏi Docker image:

dockerignore Copy
node_modules
npm-debug.log
dist
.git
.env
*.md
.gitignore

Bước 2: Kiểm tra Docker Container Cục Bộ

Sau khi đã thiết lập Dockerfile, hãy kiểm tra Docker image để đảm bảo mọi thứ hoạt động trơn tru.

Xây dựng Docker Image: Mở terminal tại thư mục gốc của dự án và chạy lệnh:

bash Copy
docker build -t nest-app .

Lệnh này sẽ xây dựng Docker image và gán tag là nest-app cho nó.

Chạy Docker Container: Sau khi hoàn thành quá trình xây dựng image, bạn có thể chạy container bằng lệnh:

bash Copy
docker run -p 3000:3000 nest-app

Lệnh này sẽ khởi động một container mới từ image nest-app và ánh xạ cổng 3000 của container với cổng 3000 trên máy của bạn.

Kiểm tra Ứng Dụng: Mở trình duyệt và truy cập http://localhost:3000. Nếu mọi thứ được thiết lập chính xác, bạn sẽ thấy ứng dụng NestJS của mình đang chạy.

Bước 3: Tối Ưu Hóa cho Môi Trường Production

Để tối ưu hóa Dockerfile cho môi trường production, chúng ta sẽ thực hiện một vài thay đổi nhằm giảm kích thước image và cải thiện bảo mật:

  • Sử dụng Alpine Node Images: Những image này nhẹ hơn và hiệu quả hơn. Cập nhật базe image thành:
    dockerfile Copy
    FROM node:20-alpine
  • Thiết lập biến môi trường NODE_ENV: Đặt NODE_ENV thành production để tối ưu hóa ứng dụng cho sản xuất:
    dockerfile Copy
    ENV NODE_ENV production
  • Sử dụng npm ci thay vì npm install: npm ci đáng tin cậy hơn cho các môi trường tự động cài đặt như Docker. Thay thế RUN npm install bằng:
    dockerfile Copy
    RUN npm ci
  • Thêm hướng dẫn USER: Chạy ứng dụng với tài khoản không phải root để nâng cao bảo mật. Thêm đoạn mã sau khi cài đặt dependencies:
    dockerfile Copy
    USER node
  • Sử dụng Multistage Builds: Giúp bạn tạo image cuối cùng nhỏ hơn bằng cách tách biệt môi trường build và runtime. Dưới đây là ví dụ về một Multistage Dockerfile:
    dockerfile Copy
    # Giai đoạn phát triển
    FROM node:20-alpine AS development
    WORKDIR /usr/src/app
    COPY package*.json ./
    RUN npm ci
    COPY . .
    USER node
    
    # Giai đoạn xây dựng
    FROM node:20-alpine AS build
    WORKDIR /usr/src/app
    COPY package*.json ./
    COPY --from=development /usr/src/app/node_modules ./node_modules
    COPY . .
    RUN npm run build
    ENV NODE_ENV production
    RUN npm ci --only=production && npm cache clean --force
    USER node
    
    # Giai đoạn sản xuất
    FROM node:20-alpine AS production
    WORKDIR /usr/src/app
    COPY --from=build /usr/src/app/node_modules ./node_modules
    COPY --from=build /usr/src/app/dist ./dist
    CMD ["node", "dist/main.js"]

Thiết lập này bao gồm ba giai đoạn:

  • Giai đoạn phát triển: Phục vụ cho việc phát triển cục bộ với tất cả các dependencies.
  • Giai đoạn xây dựng: Xây dựng ứng dụng cho sản xuất.
  • Giai đoạn sản xuất: Chạy phiên bản đã xây dựng cho production.

Bước 4: Xây Dựng lại và Chạy Image Đã Tối Ưu Hóa

Sau khi cập nhật Dockerfile, hãy xây dựng lại image:

bash Copy
docker build -t nest-app .

Sau đó, chạy container đã được tối ưu hóa:

bash Copy
docker run -p 3000:3000 nest-app

Kiểm tra kích thước của image mới bằng lệnh:

bash Copy
docker images

Bạn sẽ nhận thấy kích thước image giảm đáng kể, giúp nó hiệu quả hơn trong môi trường sản xuất.

Khắc Phục Các Sự Cố Thường Gặp

  • Lỗi: Cannot find module 'webpack': Đảm bảo bạn đang sử dụng đúng phiên bản Node.js trong base image. Ví dụ: sử dụng FROM node:20-alpine thay vì FROM node:14-alpine.
  • Lỗi: nest command not found: Nghĩa là Nest CLI chưa được cài đặt. Trong multistage build, hãy chắc chắn rằng bạn đã sao chép thư mục node_modules từ giai đoạn phát triển, nơi mà CLI được cài đặt.

Sử Dụng Các Trình Quản Lý Gói Khác Nhau

Nếu bạn đang sử dụng pnpm thay vì npm, thì Dockerfile của bạn sẽ hơi khác một chút. Dưới đây là ví dụ:

dockerfile Copy
# Giai đoạn phát triển
FROM node:20 AS development
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /usr/src/app
COPY pnpm-lock.yaml ./
RUN pnpm fetch --prod
COPY . .
RUN pnpm install
USER node

# Giai đoạn xây dựng
FROM node:20 AS build
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /usr/src/app
COPY pnpm-lock.yaml ./
COPY --from=development /usr/src/app/node_modules ./node_modules
COPY . .
RUN pnpm build
ENV NODE_ENV production
RUN pnpm install --prod
USER node

# Giai đoạn sản xuất
FROM node:20-alpine AS production
WORKDIR /usr/src/app
COPY --from=build /usr/src/app/node_modules ./node_modules
COPY --from=build /usr/src/app/dist ./dist
CMD ["node", "dist/main.js"]

Sử Dụng Fastify với NestJS

Nếu bạn đang sử dụng Fastify thay vì Express, bạn sẽ cần sửa đổi file main.ts để lắng nghe trên 0.0.0.0:

typescript Copy
import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  await app.listen(process.env.PORT || 3000, '0.0.0.0');
}
bootstrap();

Và như vậy, bạn đã hoàn thành quá trình docker hóa ứng dụng NestJS của mình và tối ưu hóa cho môi trường production. Nếu bạn có ý định triển khai ứng dụng NestJS của mình, hãy tham khảo thêm tại sliplane.io.
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào