Deploy và host dự án ReactJS ra thế giới Internet với Nodejs,Serve, Pm2, Nginx trên một VPS (Máy ảo)
Đưa dự án Reactjs ra thế giới Internet
Khi bạn đang code reactjs hoặc đã code xong rồi và muốn trình bày thành quả của mình cho mọi người xem hoặc ai đó xem để review
đánh giá thì có nghĩa là đã tới lúc bạn cần phải có một nơi để đưa dự án reactjs lên đó rồi.
Khi bạn code ở máy của bạn thì dự án đang ở chế độ development
và khi đưa lên mạng trong môi trường review kiểm thử thì nó có thể là testing
hoặc staging
. Với chế độ development
thì dự án chạy ở trên máy của bạn. Ai muốn xem thì phải qua máy bạn xem còn nếu người khác muốn xem thì bạn phải đưa dự án chạy trên một môi trường mạng, tạm gọi là server
mà ở đó luôn có kết nối mạng và bất kỳ ai, vào bất kỳ lúc nào cũng có thể xem dự án của bạn miễn là họ có mạng và trình duyệt.
Hiện tại thì có vài phương án đưa web của bạn lên thế giới internet từ đơn giản cho tới phức tạp, từ miễn phí cho tới có phí. Một vài phương án như
- Deploy và host trên dịch cung cấp JAM stack ví dụ như: Netlify, Cloudflare Pages…
- Deploy và host trên dịch vụ cloud có lựa chọn miễn phí như là: Heroku…
- Deploy và host trên một server ảo (VPS) riêng biệt
Về deploy và host trên các nền tảng cung cấp dịch vụ thì có điểm thuận tiện là họ có cơ sở hạ tầng sẵn, chịu trách nhiệm về phần cứng, phần mềm hỗ trợ và bạn chỉ việc làm theo hướng dẫn là dự án reactjs của bạn sẽ ra thế giới net ngay và luôn. Nhưng hôm nay thì mình sẽ không nói về cái này. Mình muốn nói kỹ hơn cho các bạn muốn tìm hiểu một dự án được chạy như thế nào khi triển khai trên một server. Điều này sẽ giúp bạn hiểu rõ hơn về hệ thống, cách các thành phần làm việc và từ đó sẽ tăng khả năng giám sát, theo dõi của bạn hơn đối với dự án trên production để kịp thời có những điều chỉnh sao cho cân bằng giữa chi phí bỏ ra và trải nghiệm mang lại cho user là người sử dụng trang web, ứng dụng mà bạn cung cấp.
Sự liên quan của các thành phần Reacjt, Nodejs, Serve, Pm2, Nginx, SSL trên VPS
Để biết sự liên quan bạn tham khảo hình này
Nodejs
- Đầu tiên là mình cùng nói sơ qua chút là dự án reactjs viết bằng ngôn ngữ
javascript
và ngôn ngữ này mặc định chạy trên trình duyệt nơi có thành phần bộ máy có chức năng dịch, chuyển đổi dòng lệnh javascript thành ngôn ngữ máy (binary) để máy tính có thể đọc được và thực thi. Còn bây giờ dự án của bạn sẽ không phải chạy trên trình duyệt mà chạy trên máylocal
của bạn mà sẽ chạy trên một máyserver
vậy thì có cách nào để chạy dự án ko? Có chứ bạn, và chúng ta sẽ dùngNodejs
để chạy dự án. - Ok vậy thì ở môi trường
dev
thì mình chạy lệnhnpm start
hayyarn start
để chạy dự án còn trên server chạy bằngNodejs
thì ta sẽ dùng lệnh gì nhỉ? Nếu cứ theo thông thường thì dùng lệnhnpm start
dự án - Mặc định dự án chạy trên port 3000 và vps thì có public ip bạn có thể dùng trình duyệt từ máy tính local của bạn truy cập vào vps tới port 3000 để xem app chạy nè
http://ip.cua.vps:3000
. Do bạn đang dùng vps thường không có cài Graphic User Interface (GUI) và trình duyệt nên bạn không truy cậphttp://localhost:3000
được.
Serve
- Bạn thắc mắc thêm là trong file
package.json
thường có lệnhnpm build
để build dự án ra một folder/build
và sau đó chạy dự án trên folder này chỉ bao gồm html, css, javascript hay còn gọi là static files vậy thì làm sao chạy những files này. Và cách dễ dàng nhất là dùng góiserve
tại Github theo link hướng dẫn https://create-react-app.dev/docs/deployment/ thì cài đặt như package quản lý bởi npm
cài server với lệnh
npm install -g serve
Pm2
Nếu đơn giản như bên trên thì ngon quá. Nhưng đời đâu có dễ dàng thế. Có vài điều cần lưu ý như sau:
- Giả sử dự án đang chạy trên vps mà vì lý do nào đó dự án của mình lỗi và bị crash và vps phải khởi động lại thì lúc đó người dùng không thể truy cập vào website trừ khi bạn remote (truy cập từ xa) vào vps và vào folder dự án chạy lệnh
npm start
. Đây chỉ là một trong vài lý do mà mình không nên chạy dự án trực tiếp như vậy mà mình nên có một trình quản lý chạy dự án và đó chính là chỗ làPm2
ra đời. Pm2 là gói package quản lý bởi npm nên cài đặt với lệnhnpm install -g pm2
, và ngoài việc giúp tự khởi động lại dự án khi vps bị restart hay app bị crash thì Pm2 cũng có nhiều tính năng hay ho khác như - Quản lý log
- Quản lý nhiều website chạy Nodejs trong cùng một vps
- Hỗ trợ load-balancing nhiều process node để sử dụng tối đa số core của server vì mặc định Node chỉ là single thread
Kết hợp với
serve
thì sẽ có cú pháp câu lệnhpm2 serve <path> <port> --spa
ví dụ:pm2 serve build/ 3000 --spa
Nginx
Chúng ta đã có Pm2
quản lý dự án reactjs chạy ok rùi. Có điều có một số điều cần lưu ý như sau:
- Dự án bạn chạy sẽ chạy trên cổng nào đó, mặc định là port 3000 và khi truy cập thì như bên trên mình có đề cập là bạn phải vào
http://ip.cua.vps:3000
điều này sẽ vô cùng bất tiện và do đó thì bạn phải làm một số việc tiếp theo như - Mua tên miền và trỏ tên miền đó về địa chỉ ip của vps bằng cách vào DNS của registra (godaddy, namecheap, namesilo..) và thêm record A tại
@
trỏ vềip.cua.vps
sau đó thêm tiếp thẻCNAME
tạiwww
trỏ về@
để khi người dùng gõdomain.cua.ban
haywww.domain.cua.ban
thì nó đều trỏ vềip.cua.vps
hết. - Tiếp theo là bạn cần phải có một web server ở đây thì có
Apache
hoặcNginx
mình thì chọnNginx
vì nó có nhiều tính năng hơn và nhanh hơn so vớiApache
. Nhiệm vụ củaNginx
là nhận request mặc định từ cổng 80 (http) hoặc 443 (https) tạidomain
rồi sau đóreverse proxy
dịch nôm na là chuyển hướng về ứng dụng reactjs đang chạy ở cổng3000
tronglocalhost
. - Mặc định thì Nginx sẽ phục vụ file cho người dùng trong folder
/var/www/
do đó sau khi chạy lệnhnpm build
thì mình sẽ copy toàn bộ folderbuild/
vào trong/var/www/build/
- Tham Khảo cấu hình của một
Nginx
trong file tại/etc/nginx/sites-available/default
1 2 3 4 5 6 7 8 9
server { listen 80; server_name `domain.cua.ban`; root path_to_react_build_directory_or_distribution_directory; index index.html; # react by default generate the file in the build directory location / { try_files $uri $uri/ =404; } }
Tóm lại thì cả quy trình là thế này: người dùng sẽ gõ tên domain trên thanh địa chỉ trình duyệt giả sử là
domain.cua.ban
thì browser sẽ tìm ra ip của vps và truy cập vào đó mặc định qua cổng 80 (http) hoặc 443 (https) và Nginx sẽ dựa vào domain rồi chuyển hướng truy cập đó vào trong localhost đang chạy reactjs ở cổng 3000
SSL
Để tăng tính bảo mật và tắt cảnh báo không an toàn từ trình duyệt khi truy cập vào app reactjs thì bạn cần phải cài chứng chỉ SSL
cho cái domain.cua.ban.host.reactjs
Và đó là lý do vì sao cần phải cài SSL. Và ta có thể xài chứng chỉ miễn phí Let's encrypt
thông qua ứng dụng certbot
Tóm lược
Vừa rồi là quá trình đi từ trong nhân dự án ra bên ngoài để các bạn hiểu vì sao phải cần các phần mềm, vì sao phải thiết lập các môi trường như vậy. Còn phần này thì mình sẽ tóm lược ngược lại từ ngoài vào trong nghĩa là từ lúc có ai đó dùng trình duyệt gõ vào địa chỉ trang web, ứng dụng reactjs của bạn thì phía sau background của trình duyệt sẽ từ Domain Name
tìm ra ip.cua.vps
rồi gửi request tới ip.cua.vps
qua cổng 443 (https - vì mình đã cài SSL rui). Từ đây thì Nginx
sẽ xử lý dựa vào domain Name
thì Nginx sẽ chuyển hướng tới folder chứa ứng dụng đang chạy tương ứng ở localhot