好的,這是一個很常見的網站架構。你想用 Apache 當作 反向代理伺服器 (Reverse Proxy),把外面連進來的請求導向你內部跑在 Port 3000 上的 Next.js 應用程式。
我會用繁體中文,用像心情筆記一樣的口語風格來跟你說明詳細步驟,高中生應該也能理解。
設定 Apache 反向代理
這個整合的重點,就是去改 Apache 的設定檔。
步驟一:確認 Apache 模組已經啟用
首先,我們要確定 Apache 已經打開了幾個重要的功能模組。這些模組就像是 Apache 的外掛,反向代理需要它們才能運作。
你需要確認以下三個模組是啟用的:
mod_proxy:這是代理功能的基礎。mod_proxy_http:這是處理 HTTP 請求的代理模組。mod_headers:這個會讓我們可以修改傳輸的標頭,確保 Next.js 伺服器能拿到正確的連線資訊。
在大部分 Linux 系統上,你可以用這個指令來啟用它們(如果還沒啟用的話):
sudo a2enmod proxy proxy_http headers
啟用後,要記得重新啟動 Apache 讓設定生效:
sudo systemctl restart apache2
步驟二:編輯 Apache 設定檔
接下來,我們要告訴 Apache 哪個網址要導向 Port 3000。我們通常會在一個特定的設定檔中做這件事,例如在 /etc/apache2/sites-available/ 目錄下的網站設定檔(例如 000-default.conf 或是你專屬的設定檔)。
請你用編輯器打開這個檔案。假設你的網站要使用 80 Port (標準 HTTP) 連線,設定會寫在 <VirtualHost *:80> 裡面。
你需要加入以下這幾行設定:
<VirtualHost *:80>
ServerName 你的網域名稱 # 例如:www.yourwebsite.com
# 這一行很重要,它會把所有連到這個網域的請求,
# 偷偷轉發給內部 Port 3000 的 Next.js 伺服器。
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
# 這些是為了確保 Next.js 拿到的連線資訊是正確的,
# 例如:用戶真實的 IP 位址。
RequestHeader set X-Forwarded-Proto "http"
RequestHeader set Host "你的網域名稱"
</VirtualHost>
如果你也想處理 HTTPS (443 Port) 的連線,那就要在另一個 <VirtualHost *:443> 區塊裡,再寫一次 ProxyPass 和 ProxyPassReverse。當然,前提是你已經設定好了 SSL 憑證。
步驟三:測試並重新載入設定
設定檔改好之後,我們需要檢查一下有沒有語法錯誤。
- 測試指令:
sudo apachectl configtest - 如果它回覆
Syntax OK,表示語法正確,我們就可以重新啟動 Apache 了。 - 重新啟動指令:
sudo systemctl restart apache2
步驟四:確認 Next.js 伺服器運作中
在做完上面的 Apache 設定後,你要確保你的 Next.js 應用程式正在 VPS 上用 Node.js 跑起來,而且確實是監聽著 Port 3000。
- 例如,你可能需要執行:
node server.js或是用 PM2 這樣的工具來管理你的 Node.js 應用程式。 - 重點:請確認你的 Next.js 伺服器不是直接開放給外面連線的,它應該只監聽
localhost:3000或是127.0.0.1:3000,這樣才能確保只有 Apache 這個代理可以連到它,更安全一些。
最後的結果:
現在,當用戶在瀏覽器輸入你的網域名稱 (例如 http://www.yourwebsite.com),Apache 會接收到這個請求,然後:
- Apache (在 80 Port) 接收到請求。
- Apache 偷偷把請求轉發給
http://localhost:3000。 - Next.js 伺服器處理請求,生成 HTML。
- Next.js 把結果傳回給 Apache。
- Apache 把結果回傳給用戶的瀏覽器。
對用戶來說,他們只會看到你的網站,完全不知道背後是 Apache 在幫 Next.js 擋駕和轉發。
你想知道 Apache 到底有沒有正確讀取和使用你為 nextjs-hello.yourwebsite.com 設定的虛擬主機區塊,這是確認反向代理為什麼沒生效的關鍵一步。
驗證 Apache 虛擬主機載入的步驟
我們主要使用 Apache 內建的工具指令來檢查。
步驟一:檢查哪些設定檔被啟用
首先,要確認你建立的設定檔是否有被 Apache 啟用。在 Debian/Ubuntu 系統上,通常是這樣操作:
- 確認你的設定檔已經在
/etc/apache2/sites-available/這個目錄下。 - 確認你已經執行了啟用指令,它會在
/etc/apache2/sites-enabled/建立一個符號連結:- 啟用指令:
sudo a2ensite 你的設定檔名稱
- 啟用指令:
- 檢查符號連結是否存在:
- 檢查指令:
ls -l /etc/apache2/sites-enabled/ - 你應該會看到一個箭頭指向
/etc/apache2/sites-available/的檔案。
- 檢查指令:
步驟二:使用 apache2ctl -S 檢查設定檔解析狀態
這是最直接、最準確的方法,它會告訴你 Apache 實際讀取到的虛擬主機清單。
- 執行指令:
sudo apache2ctl -S
執行這個指令後,你會看到類似這樣的輸出:
VirtualHost configuration:
*:80 is a NameVirtualHost
default server your-default-domain.com (/etc/apache2/sites-enabled/000-default.conf:1)
port 80 namevhost your-default-domain.com (/etc/apache2/sites-enabled/000-default.conf:1)
port 80 namevhost nextjs-hello.dropboxlike.com (/etc/apache2/sites-enabled/nextjs-hello.conf:5)
*:443 is a NameVirtualHost
default server ... (略)
port 443 namevhost nextjs-hello.dropboxlike.com (/etc/apache2/sites-enabled/nextjs-hello-ssl.conf:10)
ServerRoot: "/etc/apache2"
...
如何解讀這個輸出:
*:80 is a NameVirtualHost:這表示 Apache 在 80 Port 上啟用了名稱虛擬主機,它會根據用戶連線的網域名稱來區分不同的網站。default server ...:這是 Apache 找不到匹配網域名稱時,會使用的預設主機。port 80 namevhost nextjs-hello.yourwebsite.com:- 如果你看到這行,而且檔案路徑指向你設定 Next.js 反向代理的那個設定檔,那就表示 Apache 已經成功讀取你的設定了。
步驟三:確認 NameVirtualHost 指令
在某些舊版的 Apache 或特定組態中,你可能需要手動在主要設定檔中加上 NameVirtualHost *:80。不過,在多數新版的 Ubuntu/Debian 系統上,這個指令已經被預設啟用,不用再手動設定。
只要 apache2ctl -S 的輸出中,nextjs-hello.yourwebsite.com 有出現,就表示設定檔已被載入。如果還連到預設網站,那問題可能就是:
- 網域名稱解析問題:你的電腦或 DNS 是否正確將
nextjs-hello.yourwebsite.com指向你的伺服器 IP。 - 其他 VHost 衝突:是不是有另一個設定檔更早被 Apache 判斷為匹配,搶先處理了這個網域的請求。但這在名稱虛擬主機中比較少見。
你現在試試看執行 sudo apache2ctl -S,然後告訴我關於 nextjs-hello.yourwebsite.com 的輸出結果吧。