Các ứng dụng web hiện đại cần một backend mạnh mẽ và bảo mật để đảm bảo hiệu suất và khả năng mở rộng. Do đó, việc phát triển một hệ thống backend có cấu trúc chặt chẽ, an toàn và dễ quản lý bởi các nhóm lập trình viên, dù lớn hay nhỏ, là một yêu cầu quan trọng trong phát triển phần mềm.
Ngày nay, nhiều lập trình viên ưu tiên sử dụng JavaScript cho cả front-end và back-end, với Express.j
s là một trong những framework phổ biến nhất để xây dựng backend. Tuy nhiên, do kiến trúc tối giản, Express.js có thể gặp hạn chế khi cần mở rộng hoặc bảo trì trong các dự án lớn. Đây chính là lúc NestJS trở thành lựa chọn tối ưu. Với kiến trúc module hóa sẵn có, NestJS giúp việc phát triển ứng dụng backend trở nên dễ dàng hơn, đặc biệt là trong các dự án quy mô lớn. Ngoài ra, sự hỗ trợ gốc cho TypeScript không chỉ giúp nâng cao năng suất lập trình mà còn mang lại mã nguồn rõ ràng, dễ bảo trì hơn so với JavaScript thuần.
Trong hướng dẫn này, bạn sẽ học cách triển khai một ứng dụng NestJS sử dụng máy chủ web Nginx trên một VPS. Bạn sẽ biết cách đưa ứng dụng của mình lên mạng với mức độ bảo mật cần thiết.
Yêu cầu tiên quyết trước khi cài đặt NestJS
Trước khi bắt đầu hướng dẫn, bạn cần đảm bảo các yêu cầu sau:
-
Một VPS chạy Ubuntu 20.04+ hoặc một máy Ubuntu vật lý.
-
Node.js và npm (hoặc yarn) – trình quản lý gói.
Bạn có thể tham khảo hướng dẫn Cách Cài Đặt Node.js trên Ubuntu để cài đặt phiên bản Node.js và npm mới nhất trên máy của bạn. -
Máy chủ web Nginx.
Hãy sử dụng hướng dẫn xuất sắc về Cách Cài Đặt Nginx trên Ubuntu để cài đặt Nginx trên hệ thống Ubuntu của bạn.
Bước 1 Chuẩn bị và triển khai ứng dụng NestJS
Trong phần này, bạn sẽ cài đặt NestJS CLI và tạo một ứng dụng NestJS cơ bản, ứng dụng này sẽ được triển khai bằng Nginx trong các phần sau.
Cài Đặt NestJS CLI Toàn Cục
Để cài đặt NestJS CLI trên máy Ubuntu của bạn, mở terminal và gõ lệnh sau:
npm i -g @nestjs/cli
Lệnh trên sẽ cài đặt giao diện dòng lệnh của NestJS trên máy của bạn. Tiếp theo, bạn sẽ học cách tạo một dự án NestJS mới.
Tạo Dự Án NestJS Mới
Hiện nay, NestJS cung cấp hai cách để bắt đầu một dự án mới. Bạn có thể chọn phương pháp phù hợp nhất với mình.
Sử dụng NestJS CLI
Gõ lệnh sau để tạo một dự án NestJS với CLI:
nest new <project-name>
Output? Which package manager would you ❤️ to use? (Use arrow keys) ❯ npm yarn pnpm
Bạn sẽ nhận được kết quả đầu ra như sau sau khi hoàn thành:
OutputCREATE node_app/.eslintrc.js (663 bytes) CREATE node_app/.prettierrc (51 bytes) CREATE node_app/README.md (3340 bytes) CREATE node_app/nest-cli.json (171 bytes) CREATE node_app/package.json (1947 bytes) CREATE node_app/tsconfig.build.json (97 bytes) CREATE node_app/tsconfig.json (546 bytes) CREATE node_app/src/app.controller.ts (274 bytes) CREATE node_app/src/app.module.ts (249 bytes) CREATE node_app/src/app.service.ts (142 bytes) CREATE node_app/src/main.ts (208 bytes) CREATE node_app/src/app.controller.spec.ts (617 bytes) CREATE node_app/test/jest-e2e.json (183 bytes) CREATE node_app/test/app.e2e-spec.ts (630 bytes)
Lệnh trên sẽ tạo một dự án mới trong thư mục hiện tại. Bạn cũng có thể cung cấp đường dẫn tuyệt đối cho một thư mục khác, thay vì <project-name>
.
Sao chép mẫu khởi tạo
NestJS cung cấp một cách khác để bắt đầu dự án. Đây là một repository git đóng vai trò như một mẫu khởi tạo (boilerplate template). Bạn có thể clone repository đó và bắt đầu dự án với các lệnh sau:
git clone https://github.com/nestjs/typescript-starter.git <project-directory >
Sau khi clone xong, bạn cần chuyển vào thư mục dự án và chạy lệnh npm install
để cài đặt các phụ thuộc từ file package.json
:
cd <project-directory> npm install
Khi dự án đã sẵn sàng, bạn có thể khởi động máy chủ ứng dụng bằng lệnh sau:
npm run start
Lệnh trên sẽ chạy ứng dụng tại địa chỉ http://localhost:3000. Giờ đây, bạn đã có một ứng dụng NestJS cơ bản sẵn sàng chạy trên localhost.
Kiểm thử ứng dụng
Sau khi phát triển ứng dụng, bạn có thể chạy các bài test để kiểm tra ứng dụng có hoạt động đúng như mong đợi hay không. NestJS cung cấp các bài test mặc định với Jest, bạn có thể khởi chạy test bằng lệnh:
npm run test
Lệnh trên sẽ kiểm tra ứng dụng và trả về kết quả tương tự như sau:
Output> node_app@0.0.1 test > jest PASS src/app.controller.spec.ts AppController root ✓ should return "Hello World!" (24 ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 2.895 s Ran all test suites.
Ở phần tiếp theo, bạn sẽ học cách triển khai ứng dụng NestJS này trên máy chủ web sử dụng Nginx làm reverse proxy.
Bước 2 – Cấu hình Nginx để phục vụ ứng dụng NestJS
Bây giờ, chúng ta sẽ tiến hành thiết lập máy chủ web để host ứng dụng NestJS này. Chúng ta sẽ sử dụng phương pháp reverse proxy. Theo phương pháp này, chúng ta sẽ chạy ứng dụng trên localhost với một cổng xác định, sau đó sử dụng máy chủ Nginx để chuyển tiếp mọi yêu cầu từ địa chỉ IP công cộng của VPS hoặc domain đến ứng dụng chạy trên localhost. Việc sử dụng reverse proxy là một thực hành phổ biến trong ngành vì nó tăng cường bảo mật cho máy chủ web bằng cách tạo ra một lớp rào cản giữa các yêu cầu đến và ứng dụng backend. Ngoài ra, reverse proxy còn cho phép quản lý tải tốt hơn trên máy chủ, đặc biệt khi dùng máy chủ để host nhiều ứng dụng web.
Chúng ta sẽ bắt đầu bằng cách cài đặt trình quản lý tiến trình pm2, giúp quản lý ứng dụng trong runtime.
CàI đặt trình quản lý tiến trình pm2
Bạn có thể cài đặt pm2 bằng lệnh sau:
npm install -g pm2
Lệnh trên sẽ cài đặt pm2 toàn cục trên máy của bạn.
Tạo cấu hình Nginx cho ứng dụng NestJS
Tiếp theo, cấu hình Nginx để chạy ứng dụng. Hãy đảm bảo rằng bạn đã cho phép ứng dụng Nginx thông qua firewall cho cả HTTP và HTTPS, như đã đề cập trong hướng dẫn yêu cầu ban đầu. Nếu bạn đang sử dụng firewall ufw, bạn có thể thực hiện theo các lệnh sau:
Bây giờ, bạn sẽ tạo một khối cấu hình cho ứng dụng NestJS của mình. Khuyến nghị tạo các khối cấu hình mới cho từng ứng dụng thay vì chỉnh sửa cấu hình mặc định. Để tạo khối cấu hình, gõ lệnh sau trong terminal:
sudo nano /etc/nginx/sites-available/your_domain
Ở đây, chúng ta dùng your_domain
cho ứng dụng, nhưng bạn nên thay đổi thành tên ứng dụng của bạn. Sau đó, trong trình chỉnh sửa, nhập đoạn mã sau:
server { server_name your_domain www.your_domain; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }
Tiếp theo, tạo một symlink để Nginx biết tìm các ứng dụng web có sẵn trong thư mục sites-available
:
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
Cũng cần vô hiệu hóa symlink mặc định, nếu không Nginx sẽ chuyển hướng tất cả các yêu cầu tới trang mặc định. Sử dụng lệnh sau để xóa liên kết mặc định:
sudo unlink /etc/nginx/sites-enabled/default
Sau đó, khởi động lại dịch vụ Nginx với lệnh:
sudo systemctl restart nginx
Triển khai ứng dụng Nestjs sử dụng Nginx
Bây giờ, bạn sẽ thiết lập trình quản lý tiến trình pm2 để xử lý việc chạy ứng dụng NestJS của bạn. Chuyển thư mục làm việc đến thư mục ứng dụng NestJS của bạn và gõ lệnh sau:
pm2 start npm --name "your_domain" –- start
Bạn có thể chạy lệnh sau để cấu hình pm2 tự động khởi động cùng server:
pm2 startup
Khi đã thiết lập xong ứng dụng với pm2, lưu lại danh sách tiến trình của pm2 bằng lệnh:
pm2 save
Bây giờ, chúng ta đã thiết lập ứng dụng web chạy cùng với khởi động hệ thống và cấu hình Nginx làm reverse proxy chuyển tiếp đến ứng dụng chạy trên localhost.
Kiểm thử ứng dụng Web
Bạn có thể kiểm tra ứng dụng web từ console bằng cách gõ lệnh sau:
curl http://localhost
Vì chúng ta đã thiết lập reverse proxy trên địa chỉ IP công cộng của server, mọi yêu cầu đến IP công cộng của máy chủ, domain hoặc yêu cầu từ localhost trên server sẽ được chuyển hướng tới ứng dụng NestJS của your_domain
.
OutputHello World!
Ở phần tiếp theo, bạn sẽ học cách thêm SSL cho ứng dụng, cho phép bạn sử dụng giao thức HTTPS cho các yêu cầu.
Bước 3 – Thêm SSL bằng Let’s Encrypt
Cho đến nay, bạn đã học cách triển khai một ứng dụng NestJS hoạt động đầy đủ với máy chủ Nginx. Tuy nhiên, việc triển khai này sử dụng giao thức HTTP không được khuyến nghị trong môi trường sản xuất do dễ bị khai thác lỗ hổng. Do đó, bạn sẽ muốn chuyển sang giao thức HTTPS – phiên bản mã hoá của HTTP. HTTPS sử dụng chứng chỉ SSL/TLS do một Certificate Authority cung cấp. Các chứng chỉ này đặc thù cho từng website và mã hóa quá trình giao tiếp giữa client và server.
Trong phần này, bạn sẽ học cách thêm chứng chỉ SSL/TLS của Let’s Encrypt cho website của mình.
Lưu ý: Để thực hiện phần này, bạn cần có một chứng chỉ A cho domain của bạn. Trong ví dụ này, chúng ta dùng
your_domain
, tuy nhiên bạn chỉ nên thêm chứng chỉ SSL sau khi đã thêm domain vào website.
Cài đặt Certbot CLI của Let’s Encrypt
Let’s Encrypt cung cấp một CLI để quản lý và tự động hoá chứng chỉ SSL cho người dùng. Bạn có thể cài đặt công cụ này bằng lệnh:
sudo apt install certbot python3-certbot-nginx
Lệnh trên sẽ cài đặt certbot client trên VPS Ubuntu của bạn.
Lấy chứng chỉ SSL/TLS cho Domain của bạn
Bây giờ, bạn có thể lấy chứng chỉ SSL cho domain của mình bằng lệnh sau:
sudo certbot --nginx -d <your_domain> -d <www.your_domain>
Bạn cần thay thế <your_domain>
bằng tên thực của domain. Nếu đây là lần đầu tiên bạn chạy certbot trên VPS, bạn sẽ được yêu cầu nhập email và đồng ý với các điều khoản sử dụng. Hãy cung cấp thông tin cần thiết và tiến hành theo hướng dẫn.
Lưu ý: Lệnh trên chỉ hoạt động nếu bạn có một domain hợp lệ và đã liên kết domain đó với ứng dụng NestJS của mình.
Sau khi chứng chỉ được cài đặt, bạn có thể chuyển hướng tất cả các yêu cầu sang HTTPS. Khuyến nghị chuyển hướng tất cả các yêu cầu nhằm đảm bảo tính toàn vẹn cho website của bạn.
Thông tin: Chứng chỉ do certbot cài đặt có thời hạn 90 ngày. Tuy nhiên, certbot sẽ tự động gia hạn chứng chỉ, do đó bạn không cần kiểm tra thường xuyên.
Kết luận
Trong hướng dẫn này, bạn đã nắm vững cách triển khai một ứng dụng NestJS trong môi trường production trên Ubuntu VPS, sử dụng Nginx làm máy chủ web. Bạn cũng đã tìm hiểu cách thiết lập dự án NestJS, cấu hình reverse proxy với Nginx và tích hợp chứng chỉ SSL/TLS để bảo mật kết nối giữa client và server. Để mở rộng kiến thức, bạn có thể tiếp tục phát triển các ứng dụng NestJS phức tạp hơn, chẳng hạn như tích hợp cơ sở dữ liệu, triển khai bộ kiểm tra đầu vào (validation), tối ưu hiệu suất, và nhiều tính năng nâng cao khác. Việc nắm vững những kỹ thuật này sẽ giúp bạn xây dựng các hệ thống backend mạnh mẽ, bảo mật và dễ mở rộng trong thực tế.