本文山姆鍋分享如何安裝與設定一個 NodeBB 論壇的正式生產環境(production environment)。由於整個環境不只包含 NodeBB 本身,會從主機系統的開始設定開始到 Nginx web 服務。安裝過程參考了多篇文章,對於特定元件的安裝細節會直接連結到對應的教學文章,本文盡量只做重點說明。
歡迎您加入 #Developers.TW ⎘ ,A.K.A. #呆丸開發者。
安裝目標
本文是以 #Developers.TW ⎘ 作為實際案例,並以符合需求的最少安裝為目標。選擇性的元件,如 iframely 網頁內嵌剖析或者 Solr 搜尋服務並不在本文說明。因為目標是可用在正式上線的最小安裝,擴充性、可用性等等自然也就先不要求了。
下圖是部署完成後粗略的系統架構圖:
準備工作
底下是一些 NodeBB 論壇安裝設定需要的前置需求:
- 有 NodeBB 論壇的專屬域名或子域名,像 #Developers.TW 的域名是 developers.tw。
- 域名服務器已經設定完畢。本文是採用 CloudFlare 作為 DNS 以及 CDN 服務供應商。
- 讀者知道如何設定域名的 DNS 紀錄。
- 部署使用的工作機(筆電或者PC)已經有 SSH 登入的金鑰對(key pair)。
主機系統
對於經濟實惠又需要完整系統的部署環境,山姆鍋通常都會選用 DigitalOcean 的 VPS 虛擬私有伺服器,這次也不例外,選用一個標準型 1GB 記憶體、1核 vCPU 的 Droplet 作為部署環境。
註冊 DigitalOcean 帳戶以及建立一個 Droplet 可以參考 Digital Ocean: 申請自己的虛擬主機伺服器 ⎘。
基本環境 (Ubuntu 18.04)
項目 | 方案 |
---|---|
主機環境 | DigitalOcean Droplet |
主機組態 | 1 core vCPU, 1GB RAM, 25GB SSD |
作業系統 | Ubuntu 18.04 64-bit |
郵件寄送
強烈建議使用雲端電子信件寄送服務,不要在主機自行安裝 Postfix, Exim 等郵件軟體。現在雲端郵件寄送服務功能完整、成功送達率較高,又有每月免費使用額度。#Developers.TW 使用的是 SendGrid 提供的郵寄服務,只是因為山姆鍋有使用經驗,讀者可以選擇自己熟悉的服務。
不管採用哪個服務,需要取得下列郵件寄送服務的網路參數:
項目 | 說明 |
---|---|
SMTP 伺服器位址 | IP 或域名 |
SMTP 監聽埠 | 如 487 |
SMTP 登入名稱 | SendGrid 使用 ‘apikey’ 作為登入名稱 |
SMTP 登入密碼 | 從 SendGrid 申請的 api key 內容 |
有了雲端郵件寄送服務後,要讓主機系統可以寄出信件,尚須安裝與設定下列套件:
- mailutils
- ssmtp
使用下列指令安裝:
$ sudo apt-get install mailutils ssmtp
ssmtp 需要根據雲端郵寄服務提供的網路參數來設定,底下是 /etc/ssmtp/ssmtp.conf
檔案的內容:
#
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
[email protected] # 管理者的 email
# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named mail.domain.com
mailhub=smtp.sendgrid.net:587 # 雲端郵件寄送服務提供接口
# Where will the mail seem to come from?
#rewriteDomain=
rewriteDomain=developers.tw #改寫收件人看到的郵件來源域名
# The full hostname
hostname=nodebb-test # 主機名稱
# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
#FromLineOverride=YES
AuthUser=apikey # SMTP 登入名稱
AuthPass=xxxxxxxxxx # SMTP 登入密碼
UseSTARTTLS=YES
UseTLS=YES
餐考文章:
安全強化
完成主機系統的基本安裝後,作為網路服務主機,主機安全性也不容輕忽。
SSH
底下是一些安全強化重點(只是基本):
- 只允許使用憑證 SSH 遠端登入主機,禁用密碼。
- SSH 不允許直接以 root 帳戶登入。
- (選擇性) 更改 SSH 服務的監聽埠(port),例如:939:這個不會增加多少安全性,但可以有效減少系統日誌的被攻擊的紀錄。
參考文章:
自動更新安全修補
當主機系統被發現有安全漏洞時,山姆鍋希望能夠自動更新修補程式。採考此文章 How To Setup And Enable Automatic Security Updates On Ubuntu ⎘ 。
安裝 unattended-upgrade 套件
使用下列指令安裝 unattended-upgrade 套件:
$ sudo apt install unattended-upgrades
unattended-upgrades
的設定檔為 /etc/apt/apt.conf.d/50unattended-upgrades
,山姆鍋直接使用預設值。如果需要增加自動更新的套件庫(repository),可以用文字編輯器修改此文件,移除對應行前 //
註解符號。
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
// Extended Security Maintenance; doesn't necessarily exist for
// every release and this system may not have it installed, but if
// available, the policy for updates is such that unattended-upgrades
// should also install from here by default.
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
// "${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};
啟用自動更新
/etc/apt/apt.conf.d/20auto-upgrades
設定檔控制系統自動更新的行為。
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInternal "7";
其中,“1” 表示啟用,要禁用則改為 “0”。
測試自動更新
使用下列指令進行空轉測試:
sudo unattended-upgrades --dry-run -–debug
會顯示類似下面的結果:
... 前面省略
adjusting candidate version: python3-zope.interface=4.3.2-1build2
pkgs that look like they should be upgraded:
Fetched 0 B in 0s
fetch.run() result: 0
blacklist: []
whitelist: []
No packages found that can be upgraded unattended and no pending auto-removals
啟用防火牆
不少雲端基礎服務商,如DigitalOcean, 都有提供雲端防火牆,如果是多台主機的情況下,使用雲端防火牆比較方便。以本文的單一主機來說,直接使用 Ubuntu 內建的 ufw 來提供簡易主機防火牆。
ufw allow 80
ufw allow 443
ufw allow ssh
ufw enable
其中,假如 SSH 服務的監聽埠不是預設的 22 的話,要把 ssh
改成對應的埠號。
注意: 不開啟 NodeBB 的 4567, 這個只允許從本機(localhost)連線
資料庫安裝 (Redis)
直接安裝系統預設的 Redis 套件,使用下列指令安裝:
$ sudo apt-get install -y redis-server
安裝後,為了讓 Redis 服務開機時自動啟動需要執行下列指令:
$ sudo systemctl enable redis.service
Redis 是作為 NodeBB 的主資料庫,所以資料持久性(persistence)需要特別設定以減少系統不正常當機時資料遺失的風險。為了這個目的,啟用 Redis 的 append-only log,底下是 append-only log 以及幾個相關的設定值(檔案 /etc/redis/redis.conf):
daemonize yes
supervised systemd
requirepass dsfjklewreriier # redis 客戶端連線密碼,請不要直接套用,讀者需自訂。
appendonly yes
讀者需要將設定項目改成對應的設定值。
設定修改完成後,使用下列指令重啟 Redis:
$ sudo systemctl restart redis.service
Redis 安裝可參考 如何在 Ubuntu 18.04 上安裝和配置 Redis ⎘ 。
Web 安全憑證 (Let’s Encrypt)
Web 伺服器憑證是伺服器域名的身分證明,需要向一個 CA 組織申請核發,Let’s Encrypt 是個免費且受歡迎的 CA。 由於 Let’s Encrypt 已經支援 wildcard 域名憑證,本文使用 DNS 認證機制來申請 wildcard 憑證。
參考下列文章安裝 certbot 進行申請憑證:
-
Install Let’s Encrypt Free SSL Wildcard Certificate on ubuntu 18 ⎘
-
Let’s Encrypt Wildcard SSL nginx for WordPress Ubuntu 18.04 ⎘
因為希望憑證同時支援裸域名(developers.tw)以及子域名(*.developers.tw),申請指令要稍微修改
sudo certbot --server https://acme-v02.api.letsencrypt.org/directory -d *.developers.tw -d developers.tw --manual --preferred-challenges dns-01 certonly
按照畫面指示新增指定名稱的 DNS TXT 紀錄並進行驗證,如通過憑證檔案位於 /etc/letsencrpyt
目錄。
Web 服務 (Nginx)
Web 服務有下列目的:
- 作為 NodeBB 負載均衡器(load balancer)。
- 支援 TLS/SSL 網路加密結定。
- 服務 NodeBB 靜態檔案資源。
#Developers.TW 使用 Nginx 作為 web 服務軟體。
安裝 Nginx 套件
$ sudo apt-get install -y nginx
設定 Nginx
本文的安裝,NodeBB 服務只接受本地(127.0.0.1)連線,監聽埠是 4567。底下將 Nginx 設為 NodeBB 服務的代理伺服器。
新增 /etc/nginx/sites-available/developers.tw
,檔案內容如下:
upstream backend {
server 127.0.0.1:4567;
}
server {
listen 80;
access_log off;
error_log off;
server_name developers.tw www.developers.tw;
return 301 https://developers.tw$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
access_log off;
error_log off;
server_name www.developers.tw;
ssl on;
ssl_certificate /etc/letsencrypt/live/developers.tw/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/developers.tw/privkey.pem; # managed by Certbot
return 301 https://developers.tw$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
error_log /var/log/nginx/developers.tw-error.log;
access_log /var/log/nginx/developers.tw-access.log;
server_name developers.tw;
root /opt/nodebb/public;
index index.html;
gzip on;
gzip_min_length 1000;
gzip_proxied off;
gzip_types text/plain application/xml text/javascript application/javascript application/x-javascript text/css application/json;
ssl on;
ssl_stapling on;
ssl_stapling_verify on;
ssl_certificate /etc/letsencrypt/live/developers.tw/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/developers.tw/privkey.pem; # managed by Certbot
ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_session_cache shared:SSL:10m;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
# Socket.IO Support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
location @backend {
proxy_pass http://backend;
}
location ~ ^/assets/(.*) {
root /opt/nodebb/;
try_files /build/public/$1 /public/$1 @backend;
}
location /plugins/ {
root /opt/nodebb/build/public/;
try_files $uri @backend;
}
location / {
proxy_pass http://backend;
}
}
同樣地,developers.tw
需要更換為論壇實際使用的域名。
除了來自 NodeBB 官方文件的建議設定外,也設定了強制將 www.developers.tw
轉址為 developers.tw
,且 http
協定轉成 `https’,也就是說: 只接受 HTTPS 連線。
啟用 NodeBB 的站點
$ sudo ln -s /etc/nginx/sites-available/developers.tw /etc/nginx/sites-enabled/
$ sudo nginx -t
$ sudo systemctl restart nginx
到這個步驟,沒問題的話可以使用瀏覽器連線到 https://developers.tw ⎘ , 但因為後端的 NodeBB 還沒啟用,網頁會出現 503 錯誤。
執行環境安裝 (NodeJS)
NodeJS 以及 NodeBB 的安裝都是參考這篇文章 How To: Install NodeBB on DigitalOcean/Ubuntu 18.04 ⎘ 。
使用下列指令安裝 NodeJS:
$ sudo curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
$ sudo apt update
$ sudo apt install nodejs -y
應用服務安裝(NodeBB)
新增 nodebb 帳戶
為了權限控管,NodeBB 服務使用 nodebb 帳戶執行。使用下列指令新增帳戶:
$ sudo adduser nodebb
複製 NodeBB 原始程式
$ cd /opt
$ sudo git clone https://github.com/NodeBB/NodeBB.git nodebb
$ sudo chown -R nodebb:nodebb ./nodebb
$ sudo su - nodebb
初始設定 NodeBB
$ cd /opt/nodebb
$ ./nodebb setup
./nodebb setup
會詢問一系列問題,除下列外其餘使用預設值:
項目 | 設定值 |
---|---|
url | https://developers.tw ⎘ |
database | 選擇 redis |
redis password | 在資料庫安裝 (Redis) 章節中,requirepass 的設定值 |
url
需要根據實際的域名做修改,上面範例是 #Developers.TW 的域名。
讓 NodeBB 隨系統自動啟動
使用文字編輯器新增/修改檔案/etc/systemd/system/nodebb.service
,內容為:
[Unit]
Description=NodeBB
Documentation=https://docs.nodebb.org
After=system.slice multi-user.target redis.service
[Service]
Type=forking
User=nodebb
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=nodebb
WorkingDirectory=/opt/nodebb
ExecStart=/usr/bin/node loader.js
Restart=always
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl enable nodebb.service
$ sudo systemctl start nodebb.service
啟動完成後,就可以開啟瀏覽器連到 https://developers.tw/admin ⎘ , 登入控制台進行 NodeBB 的管理與設定。
小結
經過冗長的來來回回步驟後,終於有個可以上線的部署環境。但有了基本部署環境,NodeBB 還要根據需要進行設定與客製化,這個才是重中之重。NodeBB 的設定可以參考 官方的文件 ⎘,而NodeBB 的進階功能,不少需要額外申請雲端服務(如 Facebook SSO)或者安裝軟體(如 Solr等),讀者可視目的來決定是否有需要。