先前已經將前後端都部署到 Vercel 和 Render 上了,接下來只要把資料庫也改為官方的雲端資料庫 MongoDB Atlas,整個應用程式就算是可以上線使用了!
創好 MongoDB Atlas 的帳號後會先經過 Create Organization 的步驟,但其實沒什麼好填的(?)
到最後一個選項,和其他雲端服務一樣會有存取限制的選項,因為是純屬個人練習的專案,我覺得不限制 IP 也無所謂:
如果不小心打開也沒關係,後續可以到儀表板新增白名單,點選 ALLOW ACCESS FROM ANYWHERE:
這樣就會建立一個全開的 IP 了:
MongoDB Atlas 只支援 IP 白名單,所以沒辦法使用 PaaS 提供的網址,如果是自架機器的話就可以設定機器 IP 進去。
:::danger
如果 side project 有提供給他人使用的話,也務必向大家聲明本專案僅為練習成果展示,請勿提供個人真實資訊。
:::
再來要建立一個 Project,別緊張,步驟也是超簡單......幾乎不需要填什麼東西就建起來了 XD
最後就是建立 Cluster(運行 MongoDB 的本體程序),Quick setup 的地方我取消了 Preload sample dataset
,打勾的話會先灌進一些預設的 collection:
建好之後儀表板的 Overview 可以看到剛剛建好的 Cluster0(我沒改名字):
按下 Connect 會彈出連線指南,第一步要先建立資料庫的使用者,這裡也有說明「第一個使用者會賦予管理權限」:
連接方式選 Drivers(使用官方提供的 SDK,也就是我們先前有安裝過的 npm install mongodb
),如果採用其他的 ORM/ODM 也是選這個選項:
因為最關鍵的資訊是那串 URI!
將程式中的 .env
替換成這個 URI 就可以向 Cluster0 發起連線,如果需要更詳細的說明,官方也有附上所有語言環境的連線示範程式碼。
通常這樣就可以正常連線了!
雖然 IP 全開好像很危險,但其實是可以後續再手動新增更細緻的使用者帳號,這邊就不多作介紹了(?)
測試本機的實際操作流程(祈禱中):
寫入成功的話可以在儀表板看到 Cluster0 的流量變化:
點擊 Browse Collections 會進到和一般 DB GUI 差不多的畫面,可以下語法查詢資料,或是手動編輯資料。剛剛在本機網頁的操作,例如聊天訊息、配對資訊、聊天室等也都可以看得到:
最後當然要來測試線上環境能不能正常運行囉!
後端的啟動程序要先把 Vercel 專案的 URL 換上:
async function bootstrap() {
const url =
process.env.ENV === 'production'
? 'https://cozy-chat-web.vercel.app'
: 'http://localhost:3000';
try {
await connectToDB();
setupSocketServer(
new Server(server, {
cors: {
credentials: true,
methods: ['GET', 'POST'],
origin: url,
},
})
);
到 Render 新增後端專案的環境變數,原本本機有使用到的變數都要填上去:
production
,否則 CORS 的設定最後還是會導向到 'http://localhost:3000'
)確定部署成功後,Render 專案的 URL:https://**.onrender.com
也要一併更新給前端。
先在根目錄新增 next.config.ts
:
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
env: {
NEXT_PUBLIC_SOCKET_URL: process.env.NEXT_PUBLIC_SOCKET_URL,
},
};
export default nextConfig;
然後替換掉 Socket.IO 連線時的 URL:
function connectSocket() {
socket.connect({
url: process.env.NEXT_PUBLIC_SOCKET_URL || 'http://localhost:8080',
query: {
roomId,
},
});
最後到 Vercel 設定剛剛新增好的環境變數 NEXT_PUBLIC_SOCKET_URL
:
等待 Vercel 部署完成後應該就可以正常聊天啦!
由於 MongoDB Atlas 的儀錶板,整體介面算是好理解,所以線上環境的轉移就簡單很多,只要環境變數都有正確給到就沒問題了!