Raspberry Pi 的實作 - 用 Nginx 架設網頁伺服器

by 6/10/2014 2 意見

說到 Linux 上的網頁伺服器,大家直覺會想到的一定是 Apache,但是在 Raspberry Pi 的硬體資源有限的狀況下,應該是 Nginx 這個小又美的套件會更適合。

Nginx 的官方網站在 http://nginx.org/,念法是「Engine X」,它是由俄羅斯團隊研發出來的 Web Server,同時具有網站反向代理 (Reverse Proxy)、POP3 / IMAP / SMTP 郵件代理的功能,支援多種平台,硬體需求不高,兼具可靠性及高效能於一身。

最後更新日期 - 2015/01/14

事前準備

  • Raspberry Pi Type A / A+ / B / B+。
  • Raspbian 作業系統。

開始安裝

  • 我們可以直接從 Raspbian 套件庫安裝。
    sudo apt-get -y install nginx

  • 目前最新的穩定版是 1.6.2,若要安裝最新版本時,可自行至 Nginx 官網下載 後,詳細步驟請參考 Nginx 官網的安裝說明

    先下載原始檔並解壓縮。
    wget http://nginx.org/download/nginx-1.6.2.tar.gz


    tar zxvf nginx-1.6.2.tar.gz


    安裝相依套件後,進行編譯及主程式的安裝。
    apt-get install libpcre3* libssl-dev


    ./configure --prefix=/usr --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx.lock --user=www-data --group=www-data --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/proxy --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --http-scgi-temp-path=/var/lib/nginx/scgi --with-http_ssl_module --with-http_stub_status_module --with-debug


    make && sudo make install

編輯主設定檔


在編輯設定檔的時候,可以使用 nginx 指令來測試設定檔內容的語法是否正確。
sudo nginx -t

如果語法正確的話,就只會顯示「syntax is ok」及「test is successful」,若是有錯誤的話,則會提示我們錯誤的部份及所在的行號,以及「test failed」。

我們先將服務啟動。
sudo service nginx restart

打開瀏覽器後,在網址列輸入 Raspbeery Pi 的 IP,就會看到預設的 index.html 網頁。

主站台預設目錄在 /usr/share/nginx/www,目前只有 index.html 及 50x.html 兩個檔案。

主設定檔是 /etc/nginx/nginx.conf
sudo vi /etc/nginx/nginx.conf

關於設定檔的內容,可以參考 官網的設定檔說明,這邊是我稍微整理過的內容:

########## 我是分隔線 ##########
user             www-data; # 啟動服務的使用者帳號
worker_processes 2;        # 指定執行緒數量
pid              /var/run/nginx.pid;

events {
  worker_connections 1024; # 同一時間下允許的最大連線數
  multi_accept       on;
  use                epoll;
}

http {
  sendfile            on;
  tcp_nopush          on;
  tcp_nodelay         on;
  types_hash_max_size 2048;
  server_tokens       off; # 隱藏 Nginx 的版號

  keepalive_timeout         30;
  client_header_timeout     10;
  client_body_timeout       10;
  reset_timedout_connection on;
  send_timeout              10;

  include             /etc/nginx/mime.types;
  default_type        application/octet-stream;

  access_log /var/log/nginx/access.log; # 一般存取記錄
  error_log  /var/log/nginx/error.log;  # 錯誤存取記錄

  gzip              on;      # 啟用 GZip 功能
  gzip_disable      "msie6"; # 禁止 GZip 支援 IE6 以下的用戶端
  gzip_comp_level   6;       # 壓縮比由 1 到 9,數字越高,頻寬流量越小,CPU 資源越重
  gzip_min_length   1k;      # 1KBytes 以下的檔案不壓縮
  gzip_buffers      16 8k;
  gzip_http_version 1.1;
  gzip_vary         on;
  gzip_types        text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; # 允許壓縮的檔案類型

  include /etc/nginx/conf.d/*.conf;
  include /etc/nginx/sites-enabled/*;
}

########## 我是分隔線 ##########

為了方便管理,我們會把不同 IP 或不同 Domain Name 的站台儲存在獨立的檔案,儲存的目錄在 /etc/nginx/sites-enabled/ 下,而 /etc/nginx/sites-available 則是儲存未啟用的站台設定檔。

預設只有一個站台設定檔「default」,也就是主站台。

這裡先以主站台設定檔為例。
sudo vi /etc/nginx/sites-enabled/default

這個範例是最陽春的內容,設定檔的內容參數就請依實際環境修改,尤其是紅色的文字,同樣可以參考 官網的設定檔說明

########## 我是分隔線 ##########
server {
  listen      80;                   # 站台的通訊埠
  root        /usr/share/nginx/www; # 站台根目錄的絕對路徑
  index       index.html index.htm; # 預設首頁的檔案名稱
  server_name localhost;            # 網站的 Domain Name,如 blog.itist.tw

  location / {
    try_files $uri $uri/ /index.html;
  }

  location ~ /\.ht {
    deny all;
  }
}
########## 我是分隔線 ##########


虛擬站台


當我們只有一部 Web Server,卻要提供多個站台的時候,就是用虛擬站台的方式來處理。

為了方便管理,我們為每一個站台新增專屬的設定檔儲存到 /etc/nginx/sites-enabled/,這裡我們加入一個部落格為例。

先新增部落格的目錄。
sudo mkdir /usr/share/nginx/blog

新增一個陽春的首頁。
sudo vi /usr/share/nginx/blog/index.html

新增虛擬站台的設定檔。
sudo vi /etc/nginx/sites-enabled/blog.local.conf

########## 我是分隔線 ##########
server {
  listen      80;
  root        /usr/share/nginx/blog;
  index       index.html index.htm;
  server_name blog.local;

  location / {
    try_files $uri $uri/ /index.html;
  }

  location ~ /\.ht {
    deny all;
  }
}

########## 我是分隔線 ##########

如此就完成了虛擬站台的新增了,重新啟動 Nginx 服務後生效。
sudo service nginx restart

不過,
我們要測試這個虛擬站台之前,必須先處理好 Domain Name 的解析,也就是必須自行架設好 DNS Server,讓瀏覽器能解析到 blog.local 對應的 IP。

否則,就是要使用真實的 Domain Name,並處理好 DNS Record 的設定。


虛擬目錄


當我們要將儲存在其他目錄的檔案,放到現有站台的目錄下提供瀏覽,但卻又無法將它們搬移或複製到站台的根目錄裡面時,就要用虛擬目錄來解決。

這裡以主站台設定檔為例,我們要把儲存在 /usr/share/nginx/test/ 目錄的檔案,讓使用者在瀏覽 http://192.168.88.22/test-folder/ 看到。

編輯剛剛新增的 blog 站台設定檔。
sudo vi /etc/nginx/sites-enabled/default

server { } 中間加入下列文字。 
########## 我是分隔線 ##########
server {
  listen      80;
  root        /usr/share/nginx/www;
  index       index.html index.htm;
  server_name localhost;

  location / {
    try_files $uri $uri/ /index.html;
  }

  location ~ /\.ht {
    deny all;
  }

  location /test-folder {        # 虛擬路徑
    index index.html index.htm;
  # 預設首頁的檔案名稱
    alias /usr/share/nginx/test; # 虛擬目錄的絕對路徑
  }
}

########## 我是分隔線 ##########

如此就完成了虛擬目錄的新增了,重新啟動 Nginx 服務後生效。
sudo service nginx restart


SSL 支援


要讓站台提供 HTTPS 的支援,請參閱 Raspberry Pi 的應用 - 產生一張由自己核發的測試用 SSL 憑證,先產生 SSL 的金鑰與憑證。

接著,將憑證放到適當的目錄。
sudo mkdir /etc/nginx/certs 
sudo cp ~/server.crt ~/server.key /etc/nginx/certs/

請注意,千萬不要把憑證放到任何一個站台根目錄下,如:/usr/share/nginx/html/,以免當站台被攻破時,憑證也同時被盜取。

建新新的站台設定檔。
sudo vi /etc/nginx/sites-enabled/ssl.conf

########## 我是分隔線 ##########
server {
  listen      443;
  root        /usr/share/nginx/html;

  index       index.html;
  server_name localhost;

  ssl                 on;
  ssl_certificate     /etc/nginx/certs/server.crt;
  ssl_certificate_key /etc/nginx/certs/server.key;
}

########## 我是分隔線 ##########

重新啟動 Nginx 服務。
sudo service nginx restart

就可以從瀏覽器用 HTTPS 的方式連上網站了。

至於,
為何出現「此網站的安全性憑證有問題」的錯誤訊息,原因是這張憑證並不是向 VeriSign、Go Daddy、中華電信 ... 等正式憑證核發單位所購買的 SSL 憑證,而是我們自行簽發所產生的。


系列文章


參考資料


更新紀錄

  • 2014/06/10 撰文。
  • 2015/01/14 加入安裝畫面,修正內文錯誤。

Heracles Jam,江湖人稱「海公公」

IT 技術家 - 創站部落客

一個常用 Windows、慣用 macOS、愛用 Linux 的 3C 阿宅
現職 MIS / 業界講師 / 資訊顧問 / 部落客

2 則留言 :

  1. 您好
    我想請問 虛擬目錄的部分
    如果將/etc/nginx/sites-enabled/default 修改後
    那不就一樣是一個web server處理一個web 嗎?
    如何做到一對多呢?
    謝謝

    回覆刪除
    回覆
    1. 你提到的功能一般稱為「虛擬站台」,分為兩種:IP Base 與 Name Base,
      我們常用的是 Name Base,也就是用 Domain Name 來區分,在 Nginx 裡實作最簡單的方法:
      建立一個新的設定檔,內容直接從 default 的內容複製過來,再把 server_name 改掉就行了。

      要幾個站台就建立幾個對應的設定檔,不過,千萬記得 server_name 「絕對」不可以重覆....

      刪除