Learning Objectives
- 用 apt 更新 Ubuntu 系統並安裝 Nginx 網頁伺服器
- 用 ufw 設定主機上的防火牆,先允許 SSH 再啟用,避免把自己鎖在門外
- 建立網站目錄與首頁,並用 server block 讓 Nginx 依網域名稱提供網站
- 用 nginx -t 檢查設定、systemctl reload 套用設定,並說明單一伺服器是單點故障
從一台空的主機,到一個連得到的網站
上一課建立了一台 Ubuntu 24.04 虛擬機,也用 SSH 登入了。這台主機現在什麼都沒有:沒有網頁伺服器,也沒有網頁。 這一課要把它變成一個瀏覽器連得到的網站,步驟是:
| 步驟 | 指令 | 目的 |
|---|---|---|
| 1. 更新系統 | apt update、apt upgrade |
先補上安全性更新 |
| 2. 設定防火牆 | ufw allow、ufw enable |
只讓 SSH 與網頁的連線進來 |
| 3. 安裝網頁伺服器 | apt install nginx |
讓主機能回應瀏覽器的 HTTP 請求 |
| 4. 放上自己的網頁 | mkdir、chown、建立 index.html |
準備網站的檔案 |
| 5. 設定 server block | sites-available、ln -s、nginx -t、reload |
告訴 Nginx 哪個網域對應哪個資料夾 |
Nginx(念作 engine-x)是一套網頁伺服器軟體:收到瀏覽器的請求,就把對應的檔案傳回去。 它也常被放在 Flask 這類應用程式前面,負責接收請求再轉交給程式(反向代理),不過這一課只做到靜態網頁。
以下指令都在 SSH 登入雲端主機之後執行(提示字元是 ubuntu@web-01:~$)。範例的 IP 是 203.0.113.10、網域是 example.com,請換成你自己的。
先認識兩個常用的字:sudo 與 apt
| 指令 | 意思 |
|---|---|
sudo 指令 |
以系統管理員(root)的權限執行。安裝軟體、修改 /etc 下的設定都需要;登入帳號 ubuntu 預設可以使用 sudo |
apt update |
向套件來源下載「有哪些套件、最新版本是什麼」的清單,不會安裝任何東西 |
apt upgrade |
依照清單,把已安裝的套件升級到新版 |
apt install 套件 |
安裝新的套件;加 -y 表示自動回答「是」 |
systemctl status/reload/restart 服務 |
查看、重新載入設定、重新啟動系統服務(投影片的舊寫法是 service nginx status) |
&& 的意思是「前一個指令成功,才執行下一個」。
導覽:更新系統、設定防火牆、安裝 Nginx
先用 ssh [email protected] 登入上一課建立的主機,再依序執行。輸出很長的地方只節錄重點,中間的「…」代表省略的內容。
-
1
更新系統
新主機的套件不一定是最新的,先更新一次。
apt update更新清單,apt upgrade -y實際升級。升級到核心之類的套件時,畫面可能提示需要重新開機,這時執行sudo reboot,等一分鐘左右再重新 SSH 登入。 -
2
先允許 SSH,再啟用防火牆
順序很重要:
ufw(Uncomplicated Firewall)一啟用就會擋掉沒有允許的連線。如果先enable才想到 SSH,你現在這條連線可能就斷了,再也登不進去。所以先ufw allow OpenSSH(允許 22 連接埠),再ufw enable。啟用時會警告「可能中斷現有的 SSH 連線」,因為已經允許了 OpenSSH,輸入y即可。 -
3
安裝 Nginx
apt install -y nginx安裝 Nginx。安裝完成後,Nginx 會自動啟動,而且設定成開機時自動執行。 -
4
允許網頁連線:Nginx HTTP
安裝 Nginx 時,它順便向 ufw 登記了幾個「應用程式設定檔」,
ufw app list看得到。這也是為什麼要先裝 Nginx 才能允許Nginx HTTP:還沒安裝時,ufw 找不到這個名稱。Nginx HTTP只開 80,Nginx HTTPS只開 443,Nginx Full兩個都開;目前還沒有 HTTPS,先開Nginx HTTP。 -
5
確認 Nginx 正在執行
systemctl status nginx看到綠色的active (running)就代表 Nginx 在執行中(按q離開)。這時在自己電腦的瀏覽器打開http://203.0.113.10,應該會看到「Welcome to nginx!」的預設網頁,它對應主機上的/var/www/html/index.nginx-debian.html。也可以在主機上用curl -I只看回應的標頭,200 OK代表成功。
瀏覽器連不上?檢查兩道門
主機上 curl 看得到網頁,自己電腦的瀏覽器卻一直轉圈圈,最常見的原因是防火牆。現在你的主機前面有兩道門:
瀏覽器 ──▶ ① 雲端服務商的防火牆規則(第 03 課,在主控台設定)──▶ ② 主機裡的 ufw(本課)──▶ Nginx
兩道門都要允許 80,請求才進得來。排查順序:
| 檢查 | 怎麼看 |
|---|---|
| Nginx 有在執行嗎 | systemctl status nginx |
| 主機自己連得到嗎 | curl -I http://localhost |
| ufw 有允許 80 嗎 | sudo ufw status 裡有 Nginx HTTP |
| 雲端防火牆規則有允許 80 嗎 | 到主控台檢查這台虛擬機套用的規則 |
| 網址打對了嗎 | 現在還沒有 HTTPS,要用 http://;有些瀏覽器會自動改成 https:// 而連不上 |
導覽:放上自己的網頁,設定 server block
一台主機可以同時放好幾個網站。Nginx 用 server block(伺服器區塊)區分:每個網站一份設定檔,寫明網域名稱與網頁資料夾。以下為 example.com 建立一個網站。
-
1
建立網站目錄並調整權限
/var/www是放網站的慣用位置。mkdir -p建立多層資料夾。這個資料夾預設屬於 root,chown -R $USER:$USER把它改成屬於目前登入的使用者(ubuntu),之後編輯網頁就不必每次 sudo。chmod -R 755讓擁有者可以讀寫、其他人(包括 Nginx)可以讀取。 -
2
建立首頁 index.html
用文字編輯器
nano建立首頁,輸入下面的內容,按Ctrl+O、Enter 存檔,再按Ctrl+X離開:<!DOCTYPE html> <html lang="zh-Hant-TW"> <head><meta charset="utf-8"><title>我的雲端網站</title></head> <body> <h1>Hello from example.com!</h1> <p>這個網頁放在雲端主機上,由 Nginx 提供。</p> </body> </html>因為上一步已經把資料夾的擁有者改成自己,這裡不需要 sudo。(投影片用
sudo echo "…" > 檔案寫入,但>是由目前的 shell 處理,不會套用 sudo 權限;資料夾還屬於 root 時會失敗,這也是先 chown 的原因。) -
3
撰寫 server block 設定檔
Nginx 的網站設定放在
/etc/nginx/sites-available/,一個網站一個檔案。建立example.com這個設定檔:server { listen 80; listen [::]:80; root /var/www/example.com/html; index index.html index.htm; server_name example.com www.example.com; location / { try_files $uri $uri/ =404; } }設定 意思 listen 80在 80 連接埠接收 HTTP 請求( [::]:80是 IPv6)root網站檔案所在的資料夾 index只輸入資料夾網址時,預設回傳哪個檔案 server_name這個 server block 負責哪些網域 try_files … =404找得到檔案就回傳,找不到就回 404 每一行設定要用分號
;結尾,漏掉是最常見的錯誤。預設網站的設定檔default裡有default_server,代表「沒有符合任何網域時用它」;一台主機只能有一個,所以自己的設定檔不要加。 -
4
用符號連結啟用網站
Nginx 只會讀取
sites-enabled/裡的設定。ln -s在sites-enabled/建立一個指向設定檔的符號連結(類似捷徑):sites-available是「寫好的設定」,sites-enabled是「目前啟用的設定」。要暫時停用某個網站,刪掉連結就好,設定檔本身還在。 -
5
檢查設定,再重新載入
每次改完設定,先用
nginx -t檢查語法,看到syntax is ok與test is successful才套用;有錯誤時它會指出哪個檔案的第幾行。確認無誤後,systemctl reload nginx重新載入設定,不會中斷正在連線的使用者(restart則是整個重啟)。 -
6
測試網站
Nginx 依請求裡的網域名稱(
Host標頭)決定要用哪個 server block。在主機上可以用curl -H "Host: example.com"模擬瀏覽器連到 example.com。要讓瀏覽器真的用網域連進來,有兩種方式:
- 正式做法:在網域的 DNS 設定加一筆 A 紀錄,把網域指向主機的公用 IP(第 02 課)
- 測試用:在自己電腦的 hosts 檔加一行
203.0.113.10 example.com(Windows 在C:\Windows\System32\drivers\etc\hosts,macOS/Linux 在/etc/hosts,都需要系統管理員權限),只影響你自己的電腦
直接用 IP
http://203.0.113.10連線時,請求裡沒有你的網域名稱,所以仍然看到 Nginx 的預設網頁,這是正常的。
網站上線了,接下來呢?
你的網站現在可以用 HTTP 連線。實際上線前,通常還會再做:
| 下一步 | 說明 |
|---|---|
| 加上 HTTPS | 用 Let's Encrypt 這類免費憑證機構申請憑證(工具是 certbot),再到防火牆開放 443;本課不示範 |
| 放上 Flask 程式 | 讓 Nginx 把請求轉交給 Flask(反向代理),並用程序管理工具讓程式持續執行 |
| 定期更新 | 定期 sudo apt update && sudo apt upgrade 補上安全性更新 |
| 備份 | 網站檔案與設定檔放進 Git,資料定期備份 |
不過還有一個根本的問題:整個網站只有這一台主機。下面的練習會讓你親眼看到這代表什麼。
單點故障
只有一台伺服器時,它就是單點故障(single point of failure):系統更新要重新開機、程式當掉、硬體故障、這台主機所在的機房出問題, 任何一件事都會讓整個網站停擺,直到你發現並修好為止。
| 情況 | 一台伺服器 | 多台伺服器+負載平衡器(第 02、05 課) |
|---|---|---|
| 一台要重新開機更新 | 網站暫停 | 輪流更新,其他台繼續服務 |
| 一台硬體故障 | 網站停擺 | 負載平衡器避開它,使用者幾乎察覺不到 |
| 流量突然暴增 | 變慢甚至逾時 | 可以加開機器分攤 |
| 費用 | 低 | 機器越多,費用越高 |
課堂專題、個人作品集用一台主機通常就夠了,重點是知道風險在哪裡,並做好備份。 要服務很多人、不能停機的網站,就需要下一課的水平擴展與負載平衡。
想一想:防火牆與 Nginx
在 SSH 連線中設定 ufw,下面哪一個順序最安全?
主機上 curl -I http://localhost 回傳 200 OK,但自己電腦的瀏覽器連 http://203.0.113.10 一直逾時。最該先檢查什麼?
修改 /etc/nginx/sites-available/example.com 之後,正確的套用方式是?
想一想:server block 與單點故障
sites-available 與 sites-enabled 的關係是?
整個網站只有一台主機。下面哪一個說法正確?
重點精華回顧
- 先更新系統:
sudo apt update && sudo apt upgrade -y;提示需要時sudo reboot。 - 防火牆順序:
sudo ufw allow OpenSSH→sudo ufw enable;裝好 Nginx 後再sudo ufw allow 'Nginx HTTP',用sudo ufw status確認。 sudo apt install -y nginx安裝,systemctl status nginx看到active (running)代表執行中。- 網站檔案放在
/var/www/網域/html,先chown給自己、chmod 755讓 Nginx 讀得到。 - server block 寫在
/etc/nginx/sites-available/網域,用ln -s連結到sites-enabled啟用;改完先sudo nginx -t,再sudo systemctl reload nginx。 - 外面連不進來時檢查兩道門:雲端的防火牆規則與主機裡的 ufw。網域要連到主機,需要 DNS 的 A 紀錄(或測試用的 hosts 檔)。
- 只有一台伺服器就是單點故障:它停,網站就停。