RexHung's Blog

塵世中一個前端迷途小書僮!

0%

[Third party service Note] - 全端手動部署 VPS(VM) 踩坑全記錄 By Vue + Node.js + Nginx + MySQL8 + CentOS Stream 9

Introduction & 前言

Banner

這是一篇將 前端(Vue) + 後端(Node.js) + 資料庫(MySQL) 部署至 Linode 的踩坑全記錄,這篇需要一點事前準備,如果你手邊剛好有前端專案 (純 HTML 也可以) ,又剛好有後端專案,恰巧你也有資料庫,然後你也想要把作品呈現給其他人看,這篇文章就非常適合你。

如果不是,也可以先參考筆者以下文章

整篇文章是筆者自己的心得,如果文內有錯誤的地方,還請盡情指出。

此篇筆記起因是因為筆者在之前有透過 VPS Linode 部署全端專案,而當時使用的是 CentOS 6 ,該版本已經不再維護了,可參考 CentOS 6 - End of Life Notice ,近期因為機器上專案出了一些問題,筆者乾脆重新開一台新的機器重新跑一次部署流程。

第一次部署的文章在此 [Third party service Note] - Vue + Node.js + Nginx + MySQL5.7, 第一次使用 VPS(Linode, DigitalOcean) 就可能會碰到的問題之如何簡單上手 ,因為內容有些過時了,這次順便更新一次會碰到的東西,基本流程都差不多,但有些東西更新了,下面會提到更新的內容。

很多時候一件事情第一次做就是矇矇懂懂,第二次會發現原來第一次好多東西是這麼愚蠢竟然弄錯,但是總會在第二次對事情印象深刻甚至學習到更多東西。


Summary & 摘要

本篇文章預設學習前的基本條件需求:

本篇文章更新的部分:

  • 虛擬機作業系統從 CentOS 6 更新為 CentOS Stream 9
  • MySQL5.7 更新為 8
  • Nginx 依舊使用預設安裝最新版本(不影響舊文章的操作流程)

本篇文章將有以下幾個步驟:

  1. 網域部分
  2. 主機及部署
  3. 新增SSH
  4. 建置環境
  5. 關於Nginx
  6. 抓取專案
  7. 配置資料庫
  8. 防火牆設定
  9. 配置SSL
  10. 關於權限問題
  11. 額外問題

網域部分

首先是網域的部分,基本上挑自己喜歡的網域商即可,目前比較多人使用的是 GoDaddy ,其餘的如果你覺得評價不錯,價格公道,都可以考慮。

關於網域商可以考慮此篇文章:【建站教學#3】如何選擇網域商?2021前六大網域商比較

very cool

這邊以 GoDaddy 為例,到網站後輸入想要購買的網域名稱就可以查詢價格,例如你想要購買的網域是 veryCool ,就輸入查詢。

very cool price list

之後就能查看價格是多少,有的網站可以一次購買一年份,有的一次一個月為單位也可以,但請記得網域只會越來越貴,每年價格都會有所調漲,基本結尾是 .com .tw 這種也會比較貴。

dns

網域申請一個後就可以透過子網域去對應綁定多個想要呈現給使用者看的網頁,可以查看上面這張圖,怎麼配置的話可以參考舊的文章內有寫到,這邊就不多做提及了。


主機及部署

購買好網域後,就可以選擇 VPS 主機商,這些主機商會提供虛擬主機給你存放專案,可以想像就是一台電腦主機,然後你把你做好的網頁或者專案丟到該電腦上去運行,這些電腦因為不是真的是一台 Mac 或者 Windows 主機,是透過一台大的主機去切分出來的多台小主機空間,稱為虛擬主機。

基本上 VPS 最有名的大家基本有聽過的肯定是 AWS 或者 GCP 等等,這些都可以選擇,筆者這邊依舊使用舊文章就使用的 Linode ,如果想選擇其他服務商可以參考 2025年国外VPS排行榜:前十名最好的国外VPS排名

Linode Price

這邊提一下 Linode 的優勢,便宜、老牌、穩定 ,基本上一個月最便宜共享主機方案為 5 美金,如上圖,約莫 163.70 台幣,少叫一餐 UberEat 就有空間可以丟作品去找工作了,划!!

USD TWD

當然大牌如 AWS 或者 GCP 等等一定比較貴,但是他們服務也比較多元,如果不想要像文章一樣手動部署安裝這麼麻煩多的東西,可以選擇大牌的服務商,他們在官方網頁內會有類似 網域、資料庫、網域代理… 等等的服務可以選,不需要自己再上去機器安裝配置,付錢就搞定!

Take My Money


新增SSH

關於 SSH 如果不明白可以參考此篇文章 Day21:【技術篇】SSH 的基本運作原理 ,基本可以理解為你有一組帳號及密碼,帳號是大家都能看到的,而帳號可以丟到你想連線或者操作的網站去,例如 GitLabGitHub 等等,而你想要對該網站進行操作例如抓取專案,就可以拿密碼去讓網站知道是你本人,不是駭客,這樣就可以進行操作了。

SSH Workflow

擁有 SSH 就無需使用帳號密碼去驗證,在任何提供 SSH 的網站都可以使用這個功能去進行操作。

But!請記得謹慎添加 SSH ,基本上在本機我們都會創建一組 SSH 用到底,哪個網站需要我們就用本機創建好的 id_rsa.pub(SSH 創建後如果沒有自行命名,預設名稱是 id_rsa.pub) 放到網站上,這基本是沒問題的,因為自己電腦比較不容易讓 id_rsa 外洩,但今天我們是要在虛擬主機上進行 SSH 拉取專案,如果主機上使用跟本機一樣的 SSH ,如果虛擬主機上的 SSH 外洩了,會比較麻煩,會需要多個使用到的網站都一起更新。

想避免上面情況,這樣我們不如直接在主機上創建一組新的 SSH ,並且該 SSH 專門只給該虛擬主機使用。

Launch LISH Console

我們主機開好後透過服務商網站提供的方式進入虛擬主機,然後到主機內執行

1
$ ssh-keygen

這時候會提示創建了一組 SSH 在主機內,基本上會放在 ~/.ssh/ 這個資料夾,可以執行

1
$ cat ~/.ssh/id_rsa.pub

Launch LISH Console

然後把文字貼到你的遠程倉庫去,例如 GitLabGitHub

備註:請記得你的服務商網站頁面內應該也有 SSH 可以新增,這邊請新增你本機電腦的,因為你之後是要從本機透過終端機 ssh 快速連進虛擬主機,但進到虛擬主機後再虛擬主機進行 git pull 是要用另一組去 GitLab 或者 GitHub 拉取的,如果真的覺得太麻煩,也可以都共用同一組沒問題。

關於本機連不上

如果本機透過 ssh 連不上虛擬機,可以先透過服務商的網頁進入虛擬主機,然後使用以下指令去嘗試

1
$ sshd -t

如果沒有開啟 ssh 服務可以使用以下指令去新增,新增前請先透過 firewall-cmd --list-all 去查看是不是 ssh 有被加入在 services ,如果沒有請使用以下指令加入

1
2
$ firewall-cmd --permanent --zone=public --add-service=mysql
$ firewall-cmd --reload

SSH Too Open

如果出現上圖代表你的 ssh 權限太高,只需要輸入 chmod 400 ~/.ssh/id_rsachmod 600 ~/.ssh/id_rsa 即可解決


建置環境

接著是比較重要的部分,主機需要安裝一些你專案必須的

除了 GitNginx 必裝之外,其他就是看你的專案,如果你是都包裝在 Docker 內,也可以都不需要裝,但是 Git 需要拿來拉取遠端倉庫專案,所以必須要裝。

安裝的部分有興趣都可以參考舊文章,如果有不確定怎麼安裝的部分也可以透過關鍵字查詢 centOS Stream 9 install xxx,這邊就不詳細解釋怎麼安裝,不過筆者可以提供幾個文章供參考

備註:關於 nvm 的介紹可以參考 nvm:安裝、切換不同 Node.js 版本的管理器 文章,簡易解釋 nvm 就是 node 的版本管理工具

Install Git

基本上在 CentOS Stream 9 內安裝都是靠 dnf ,大多數文章開頭都會請你先執行 dnf update -y,加上 -y 是預設安裝回答都是 yes ,如上圖就是在執行安裝 Git


關於Nginx

關於 Nginx 的配置可以參考之前的舊文章 [Third party service Note] - Vue + Node.js + Nginx + MySQL5.7, 第一次使用 VPS(Linode, DigitalOcean) 就可能會碰到的問題之如何簡單上手 ,基本上只要最後輸入 nginx -t 沒問題,應該都不會有什麼額外狀況。

基本上如果訪問機器一直看不到網頁,請先找到 nginxerror.log 存放位置,使用 cat /etc/nginx/nginx.conf,然後找到下面這行

1
2
3
4
5
6
7
8
9
10
11
12
13
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log; // <- 找到這行
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf

//...下略

找到後使用 vi /var/log/nginx/error.log 查看錯誤是什麼去仔細排除即可。


抓取專案

First Git Clone

Git 安裝完畢就可以透過 git clone 去抓取專案了,而第一次會出現 The authenticity of host 'gitlab.com(xxx.xxx.xxx)' can't be established. 是正常的,輸入 yes 之後,後續就不會再出現了。


配置資料庫

前面我們安裝完了資料庫,因為是安裝 MySQL8 有些東西需要先配置,MySQL 安裝完畢後,在終端機輸入

1
$ mysql -u root -h localhost -p

接著終端機會出現

1
// Enter password: 這邊接著輸入密碼

接下來需要允許可以遠端登入,與 MySQL5.7 比較不同的地方是原本舊版是直接輸入以下指令就可以

1
$ mysql> grant all privileges on *.* to '使用者名稱'@'IP位置' identified by'要登入的密碼';

但你會發現一直都連不上,對於 MySQL8 新增方式需要改為先創建用戶,可參考 How to grant all privileges to root user in MySQL 8.0

如果遠端登入也是使用 root 就不需要再創建新的使用者,可以直接忽略掉下面 CREATE USER 'root'@'%' IDENTIFIED BY 'PASSWORD'; 這段。

1
2
3
mysql> CREATE USER 'root'@'%' IDENTIFIED BY 'PASSWORD';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;

這時候再去連線應該就能連得上了,可以執行 migrate 之類的初始化資料庫操作囉。

資料庫連不上

遠端透過 GUI 或者指令資料庫連不上的話,下面會講到防火牆及權限問題,但也有可能是 SELinux 問題,關於這問題 ChatGPT 有給出回答,因為筆者非這塊專業,所以提供資訊,相關可能需要請另外爬文。

SELinux

另外也可能是出現 Permission denied 的問題,可以參考 nginx配置报错:connect() to 127.0.0.1:8080 failed (13: Permission denied) while connecting to upstream, ,輸入 setsebool -P httpd_can_network_connect 1 可能可以解決。


防火牆設定

當我們都佈置好前後端專案以及資料庫後,有一些 Port 號是從外面就會去訪問的,如果防火牆沒有開,可能會出現以下

Semanage Port List

解決方案一

這時候可以輸入 semanage port --list 然後再用 ALT + Fcommand + F 找尋 http_port_t 這個關鍵字,看看後面的 port 是多少,基本上筆者會把 3000 3306 開起來。

如果沒有新增到的 port 號可以使用以下指令

1
$ semanage port --add --type http_port_t --proto tcp "你要新增的 Port 號"

解決方案二

Firewall Cmd List All

也可以透過使用 firewall-cmd --list-all 去查詢,看看 ports 有沒有開到,如果沒有就使用以下指令, 3306 可以自行更換

1
2
$ firewall-cmd --zone=public --add-port=3306/tcp --permanent
$ firewall-cmd --reload

關於服務設定

另外因為防火牆也會阻擋一些服務,在使用 firewall-cmd --reload 的時候可以順便看一下 services 有沒有包含 https mysql ssh,如果沒有請使用以下指令, mysql 可以自行替換

1
2
$ firewall-cmd --permanent --zone=public --add-service=mysql
$ firewall-cmd --reload

SSH Connect Refused

像是上圖的狀況也是因為 SSH Service 沒有開啟 SSH 的服務允許。


配置 SSL

基本上現在網站都會需要 SSL ,這邊要借用就文章的描述。

到這邊大致完成了,揭著我們必須讓我們的網址可以吃 443 ,也就是 https ,有興趣可以參考 一文搞懂 HTTP 和 HTTPS 是什麼?兩者有什麼差別 ,簡單說最明顯的就是如果網站不是 443(https) 頁面左上角就會出現不安全。

而通常 SSL 是需要用買的,但這邊我們要當個免費仔(放心不是破解),而免費缺點是三個月需要更新一次,但別擔心各路大神都幫我們想好了怎麼自動更新憑證。

1
$ dnf install certbot

Install Certbot

這時候可能會出現上圖錯誤,如果有就請參考 CentOS Stream release 9如何安装certbot ,或者使用以下指令,主要是因為 CentOS Stream 9 默認 Certbot 不可用。

1
2
3
4
$ dnf install epel-release -y
$ dnf install certbot -y
$ dnf install python3-certbot-nginx // 如果使用 Nginx 服務器需要安裝
$ certbot --nginx

之後如果你的 Nginx 有更改設定檔,請一定要在執行 nginx -t,然後通過後要使用 certbot --nginx,這樣才會有該網域的憑證。

產生成功會出現 Congratulations! You have successfully enabled "憑證網址"

vi etc crontab

因為憑證會有時效期限,我們不太可能會常常手動去更新,所以這邊我們要輸入 vi /etc/crontab,然後進去在最下面新增下面的內容,如上圖

1
2
# let's encrypt
0 */8 * * * root python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew > /tmp/cert-bot_renew.log

接著儲存檔案,然後輸入 service crond restart,至此就會 每天檢查三次(00:00 08:00 16:00)

500 Error

極重要:因為在輸入 certbot –nginx 的時候,程式會去依照你設定的 nginx config 訪問你的網站,如果你之前的防火牆沒有開啟 http,會有可能訪問不到,請記得輸入 firewall-cmd --permanent --zone=public --add-service=http,後續新增成功看要不要再關掉都可以,筆者在這邊卡很久很久很久很久很久很久…,記得出現問題找不到就一直回去看 nginx error log 就對了!


關於權限問題

如果有碰到畫面顯示不了,資料庫連不上,皆有可能是資料庫問題,權限問題在前面提過,不外乎就是查看

  • firewall-cmd –list-all
  • semanage port –list

看看防火牆啦,或是 Port 有沒有開,如果真沒有頭緒,一切還是要從 nginxerror.log 來看,可以看上面文章有提到怎麼找到 error.log


額外問題

gsmtp

假如你的專案有使用 GSMTP ,也要記得開啟服務,開啟 Port ,然後密碼記得至 Google 申請一組密碼

Google Account

找到你要寄信的那組 Gmail Account ,點擊 管理你的 Google 帳戶

Security

在點擊 安全性 > 兩步驟驗證

Two Step

然後往下滑點擊應用程式密碼

Password

最後點擊產生密碼,記得一定要將這十六個英文字存下來,之後再打開這個頁面就不能再看到了。


Conclusion & 結論

這次因為重新啟動一台伺服器,所以重新再跑一次安裝流程,過程很多東西又重新釐清,也碰到新的問題,不過大致上都脫離不了權限、防火牆,如果有問題基本上丟到 Google 都能解決,希望這篇筆記能幫助到一些也在部署的朋友。


參考網站