Hướng dẫn cấu hình cloudflare tới host heroku

Nghe tiêu đề thật là hấp dẫn, một món hàng ngon, bổ, rẻ thì ai mà chẳng thích. Đấy là sự thật, trong bài này tôi sẽ đưa ra khuyến nghị về mô hình triển khai một website như vậy.

Hướng dẫn cấu hình cloudflare tới host heroku

Lưu ý mô hình khuyến nghị này nên chỉ áp dụng cho cá nhân hoặc tổ chức nhỏ lẻ. Quan điểm triển khai một website public của tôi follow theo 2 xu thế:

  1. Cloud hóa, managed as service: cứ đẩy lên môi trường, hệ thống cloud, họ sẽ vận hành cho mình, không việc gì phải thuê server rồi cài rồi ssh, hardening rồi chống tấn công, rồi chưa kể phải scale khi tăng tải, ...
  2. Opensource, tập trung bảo vệ content và danh tiếng: nên sử dụng opensource hoặc tự code thì cứ tự tin opensource nó ra cho ai cũng dùng được. Khi đó sẽ tự tin lúc nào cũng dựng lại được web, ngay cả khi hệ thống cloud bị sập vì code đã được backup khắp nơi và mình cũng tận dụng được tri thức của cộng đồng trong việc fix lỗi. Cái quan trọng nhất cần giữ là db và domain. Nên backup db và ảnh thường xuyên. Domain thì bảo vệ cẩn thận.

Hướng dẫn cấu hình cloudflare tới host heroku

Ảnh: mô hình khuyến nghị

Dev: Tính luôn từ đầu là nên dùng các nền tảng và code trên nguyên tắc phù hợp với Heroku (devcenter.heroku.com). Source code nên commit lên Github, tùy mức độ mở, có thể dùng repo private hoặc public.

Deploy: Như đã nói ở trên, Heroku là nơi quá phù hợp để lựa chọn để hosting web, vừa dạng PaaS, vừa miễn phí, lại có rất nhiều add on db. Nói về add on trên Heroku, nên lựa chọn lưu db trên các add on của Heroku để có tính đồng nhất, sau đó setup định kỳ backup trên các add on này. Việc liên lạc giữa code chạy trên Heroku với các add on và các cấu hình khác như kiểu mật khẩu nên lưu trên biến môi trường (Config vars) để dễ dàng điều chỉnh và cũng đỡ sợ bị lộ source.

Media: Ngoài db thì Media (ảnh, video) cũng là một phần hồn của web, setup một tài khoản AWS miễn phí để đẩy ảnh lên và lưu trữ lâu dài.

Https, WAF, Antiddos: Cloudflare quá ngon, cho free cert https xanh lè, lại có con DNS cấu hình dễ dàng, thi thoảng cần chặn gì thì lại có sẵn 5 rule WAF miễn phí.

Monitor: Quá trình cài đặt xong, web chạy ngon lành, advance thêm chút là giám sát sống chết. uptimerobot.com là lựa chọn tuyệt vời, vừa giám sát được web, lại giám sát được cả TCP/IP, gửi mail tức thì, ngoài ra một ưu điểm vượt trội là có thể tạo 1 web dạng status.requestbin.net miễn phí để xem trạng thái các service.

Update 7/2021: uptimerobot đã không còn free cho tạo subdomain dạng status.abc.com

Vậy đấy, tất cả đều miễn phí, cái AWS đâu đó khoản 1,2 USD 1 năm, không đáng kể coi như free. Vậy là bạn đã có 1 web https đẹp đẽ, có waf bảo vệ, chống ddos, chống xâm nhập, phục hồi nhanh chóng, lại còn có cả giám sát down time, đặc biệt là miễn phí :)

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

Hướng dẫn cấu hình cloudflare tới host heroku
SSL - Nginx - Pm2 - Serve

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áy local của bạn mà sẽ chạy trên một máy server vậy thì có cách nào để chạy dự án ko? Có chứ bạn, và chúng ta sẽ dùng 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; } } ` 1 để chạy dự án.
  • Ok vậy thì ở môi trường 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; } } `

    2 thì mình chạy lệnh

    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; } } `

    3 hay

    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; } } `

    4 để chạy dự án còn trên server chạy bằng

    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; } } `

    1 thì ta sẽ dùng lệnh gì nhỉ? Nếu cứ theo thông thường thì dùng lệnh

    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; } } ` 3 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è 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; } } `

    7. 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ập

    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; } } ` 8 được.

Serve

  • Bạn thắc mắc thêm là trong file 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; } } `

    9 thường có lệnh `review`0 để build dự án ra một folder `review`1 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ói `review`2 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 `review`3

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 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; } } ` 3. Đâ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à `review`5 ra đời. Pm2 là gói package quản lý bởi npm nên cài đặt với lệnh `review`6, 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 `review`2 thì sẽ có cú pháp câu lệnh `review`8 ví dụ: `review`9

Nginx

Chúng ta đã có `review`5 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 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; } } ` 7 đ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 `development`2 trỏ về `development`3 sau đó thêm tiếp thẻ `development`4 tại `development`5 trỏ về `development`2 để khi người dùng gõ `development`7 hay `development`8 thì nó đều trỏ về `development`3 hết.
  • Tiếp theo là bạn cần phải có một web server ở đây thì có `testing`0 hoặc `testing`1 mình thì chọn `testing`1 vì nó có nhiều tính năng hơn và nhanh hơn so với `testing`0. Nhiệm vụ của `testing`1 là nhận request mặc định từ cổng 80 (http) hoặc 443 (https) tại `testing`5 rồi sau đó `testing`6 dịch nôm na là chuyển hướng về ứng dụng reactjs đang chạy ở cổng `testing`7 trong `testing`8.
  • Mặc định thì Nginx sẽ phục vụ file cho người dùng trong folder `testing`9 do đó sau khi chạy lệnh `review`0 thì mình sẽ copy toàn bộ folder `staging`1 vào trong `staging`2
  • Tham Khảo cấu hình của một testing`1 trong file tại staging`4 `

    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à `development`7 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ỉ `staging`6 cho cái `staging`7 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í `staging`8 thông qua ứng dụng `staging`9

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ừ `development`0 tìm ra `development`3 rồi gửi request tới `development`3 qua cổng 443 (https - vì mình đã cài SSL rui). Từ đây thì `testing`1 sẽ xử lý dựa vào `development`4 thì Nginx sẽ chuyển hướng tới folder chứa ứng dụng đang chạy tương ứng ở `development`5

Lời kết

Có nhiều cách đưa dự án Reactjs lên trên internet và deploy & host trên VPS cũng là một option và nó sẽ hơi khó để có thể thực hiện nó. Nhưng khi bạn thực hiện được nó thì sẽ là một cảm giác vô cùng yomost vì bạn đã hiểu rõ hơn hệ thống các thành phần làm việc với nhau và những việc tối thiểu phải làm để đưa dự án reactjs của bạn ra bên ngoài thế giới net