[Third party service Note] - Vue + Node.js + Nginx + MySQL5.7, 第一次使用 VPS(Linode, DigitalOcean) 就可能會碰到的問題之如何簡單上手
Introduction & 前言
先說這篇文章僅用於筆記,如果您剛好、恰巧有專案是 前端 VUE 後端 NODE 想佈上虛擬主機上,不管是給客戶看還是自己當作品用,都可以接著往下看,亦或許您會在文章中圖找到一樣的問題,還有我怎麼蹶誒的。
這邊也不會去探討哪台虛擬主機比較好,但我會跟你說說為什麼我從 DigitalOcean 跳到 Linode 使用。
當程式完成後的下一步
相信不管你學什麼前端,什麼後端,寫完程式碼後,下一步就是想要想辦法把作品呈現出來,雖然我們平常可以使用 GitHub+Heroku 其實就可以簡單呈現一個小作品,但缺點是 Heroku 太久沒動靜,需要一點時間喚醒,加上免費專案只能有五個。
基於上面的問題加上筆者最近剛好在幫家人做 Side Project 預約系統,目前已經到了完成一個小階段,需要呈現給家人看,最後決定使用虛擬主機來放置我的專案。
考量到以後可能還會有其他 Side Project 所以就挑選了便宜的主機來用。
然後就開始採坑之旅了。
主機筆者怎麼挑
因為本篇文章不是深入討論主機問題,所以筆者第一次挑選主機就是從 便宜、便宜、很便宜 這三個條件下去選擇,同事立馬推薦我 DigitalOcean,一個月最低五美金的方案筆者覺得還行,沒有多想就開下去了。
因為後端使用 Node.js 加上開發是用 MacOS,所以筆者挑 CentOS 7.6(不挑8是因為同事認為 7 比較穩定,加上工作環境也都是用 7 碰到問題容易解決),而剛開始建立完機器虛擬主機會給你一個 IP Addresses,正常來說會是 IPv4。
想知道 IPv4 和 IPv6 有什麼不同可以點我 查看 認識IPv4與IPv6的差異
順帶一提,通常在建立過程中,會讓你選擇之後登入主機需要使用密碼或是 SSH,筆者建議兩個都填比較安全;簡單講解一下前者就字面上的意思,使用密碼登入,而 SSH 則是會有一組 id_rsa 跟 id_rsa.pub,這兩組 Key 可以用來識別你的身份,進而達到免密碼登入。
想知道 SSH 怎麼建立嗎?點我 查看 [教學] 產生SSH Key並且透過KEY進行免密碼登入
事前準備
上面筆者偷懶認為大概大家會看到文章 87% 已經知道怎麼做了,這邊在簡單提一下該準備什麼東西。
一組網域(推薦 GoDaddy 註冊)
一顆炙熱的寫 Code 心
為什麼要準備網域呢,待會這邊會用一張圖解釋一下,總之您可以先挑一個順眼的名稱註冊網域。
安裝環境
筆者再度簡單列出這次需要安裝的環境。
注意!因為每個人需要的不一樣,該裝的東西可能也會有些許差異,請自行斟酌。
請先進入到您自己得主機,通常會在終端機上輸入:
1 | // 使用密碼登入 |
xxx.xxx.xx.xx 為您的主機 IPv4 位置,而使用 ssh 需要您自己指定到您的 ssh 檔案位置。
設定時區
登入成功後,第一個需要做的不是安裝,是檢查自己的時區,因為錯誤的時區可能照成您的排程錯誤、資料庫資料時間錯誤…等等。
1 | $ date |
這時候如果出現時間錯誤,可以改為自己得時區:
1 | // 設定為亞洲台北 |
如何查看時區可以輸入:
1 | $ timedatectl list-timezones |
設定結束後記得再次輸入 date
查看時間對不對。
安裝 EPEL
有許多套件只有 EPEL 中才有,所以這邊我們需要先安裝:
1 | $ sudo yum install epel-release |
更新套件
安裝結束後我們需要更新一下我們所有的套件:
1 | $ sudo yum upgrade |
安裝 Nginx
這邊要講解為什麼要安裝 Nginx,但不會深入討論,有興趣可以參考 淺談Nginx之反向代理 中介紹反向代理,亦或是 深度詳解Nginx正向代理與反向代理?。
先看看上方這張圖,通常我們會在網路輸入一串網址,比如 fonts.google.com 或 translate.google.com,通常我們一個網域可能會有好幾個需要呈現的不同專案,就可以使用 主網域 及 子網域 來實現,很清楚我們可以看到 google 就是主網域,fonts 及 translate 就是子網域。
但你會想,一台主機一個 IPv4 會對應到一個子網域,那我是不是一個專案只能放一台機器呢?
其實我們靠 Nginx 就可以達到,輸入一串網址,網址子網域都對到同一個 IPv4,然後再依靠 Nginx 去找尋對應網域名稱的專案。
找到對應專案的設定欓,會把設定檔裡面的 root 路徑的檔案顯示出來,這樣就能達成輸入什麼網址會顯示什麼內容出來了。
知道後廢話不多說我們開始安裝,使用 yum 裝 Nginx:
1 | $ sudo yum install nginx |
啟動 Nginx 服務:
1 | $ sudo systemctl start nginx |
接著檢查 nginx 是否正常:
1 | $ sudo systemctl status nginx |
然後很重要記得,永久啟用 Nginx 服務,重新開機後可自動啟動:
1 | $ sudo systemctl enable nginx |
這時候進入網頁輸入 IPv4 或是已經掛載上 Godady 的網域,應該就可以看到。
PS: 如果進入網頁看到類似下面的網頁 無法連上這個網站 的話,有三種情況,第一個是有可能是你的防火牆沒打開,請記得打開防火牆,第二個是需要修改
/etc/firewalld/firewalld.conf
文件,最後則是需要輸入sudo firewall-cmd --permanent --add-service=https
可能你沒開啟 https 服務
第一種情況解決方式,輸入:
1 | $ sudo firewall-cmd --add-service=dns --permanent |
之後就能成功了!
第二種情況解決放是,輸入 systemctl status firewalld
查看有無報錯,如果有問題會出現下圖情況:
這種情形請輸入:
1 | $ vi /etc/firewalld/firewalld.conf |
然後輸入 systemctl restart firewalld
重啟防火牆,接著在輸入 systemctl status firewalld
查看還有無錯誤訊息,沒有就是排解了!
第三種也是最後一種情況可能是你的 https 沒有開啟,先輸入 sudo firewall-cmd --list-service
檢查你開了哪些服務,如果只出現 dhcpv6-client http ssh
,那就是你的 https 沒有開,裡面缺什麼就是什麼沒開,解決方式就是輸入 sudo firewall-cmd --zone=public --permanent --add-service=https
如果 http 沒有就是修改最後的 service,例如 sudo firewall-cmd --zone=public --permanent --add-service=http
這樣,輸入完記得重啟 sudo firewall-cmd --reload
緊接著再輸入一次 sudo firewall-cmd --list-service
查看是否有加入這項服務了!
安裝 Git
1 | $ yum install git |
先查看版本號,確認是否安裝成功:
1 | $ git --version |
接著安裝結束後記得設定你的 git config:
1 | $ git config --global user.name 你的名字 |
接著輸入 git config --list
查看是否設定成功,之後就成功安裝了。
安裝 Node
因為我們必須使用到 Node.js 以及 Npm 或 Yarn 功能,所以必須先安裝 Node,但由於筆者喜歡將機器上的版本改為跟本地一樣,所以我們這邊需要先安裝 nvm,可以當他是 Node 的版本管理器。
由於這邊我們會使用到 wget 區抓取套件,所以我們先安裝:
1 | yum install wget |
接著輸入以下指令安裝:
1 | $ wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.1/install.sh | bash |
然後記得登出在登入!接著輸入 nvm --version
就會拿到目前得版號。
緊接著安裝 Node,可以使用 nvm ls-remote
可以查看所有可以提供安裝的版本,挑選你喜歡或熟悉的版本:
1 | $ nvm install v12.16.1 |
安裝完成後輸入 node -v
查看是否安裝完成。
Yarn
因為有些人比較習慣使用 Yarn,這邊簡單說說怎麼安裝,有些教學會請您輸入 sudo yum install yarn
但會顯示沒有這個 package,所以這邊我們使用:
1 | // 請注意一定要 -g |
設定 Nginx
這邊略過 clone 專案下來的過程,但還是筆記一下通常筆者會把專案放置在 /var/www/
下面。
如果你是自己安裝 Nginx,會發現沒有 default.config 這個檔案,因為我們接下來的每一個專案都會有一個 ***.conf** 去引導使用者在瀏覽網頁時,主機會去拿哪一個專案丟給使用者看,如我沒有的話,也沒關係,使用下面我的範例建立一個,在自己去更改專案路徑即可。
在創建之前,你可以先使用 vi /etc/nginx/nginx.conf
去查看立面是否有顯示 include /etc/nginx/conf.d/*.conf
沒有可以自己加上去,基本上之後設定檔不是放在這個地方,就是放在 /etc/nginx/sites-available/
或是 /etc/nginx/sites-enabled/
都可以。
加上
vi /etc/nginx/nginx.conf
是為了能讓你專案的設定欓被吃到,不然還是會找不到你專案的位子。
檢查完確定 nginx 的設定欓就可以開始動手建立自己專案的設定欓了(記得通常是一個專案一個設定欓)。
範例程式碼可以複製這邊,或是上 Digitalocean NGINXConfig 試著配置出一份,通常都大同小異,只是內部有一些細微更改:
1 | server { |
這邊很重要!如果你是使用 Vue History 模式,請一定要在
location / {
那邊裡面加上try_files $uri $uri/ /index.html;
不然你會發現怎麼切換路由就會出錯了。
接著很重要,檢查 Nginx 是否正常:
1 | $ sudo systemctl status nginx |
如果一切正常請重啟 Nginx
1 | $ sudo systemctl restart nginx |
設定 SSL
到這邊大致完成了,揭著我們必須讓我們的網址可以吃 443,也就是 https,有興趣可以參考 一文搞懂 HTTP 和 HTTPS 是什麼?兩者有什麼差別,簡單說最明顯的就是如果網站不是 443(https) 頁面左上角就會出現不安全。
而通常 SSL 是需要用買的,但這邊我們要當個免費仔(放心不是破解),而免費缺點是三個月需要更新一次,但別擔心各路大神都幫我們想好了怎麼自動更新憑證。
由於我們是 CentOS 7 所以輸入下列程式碼安裝:
1 | $ yum install certbot |
然後我們需要產生 SSL 憑證:
1 | $ yum install python-certbot-nginx |
通常如果您已經有設定 Nginx 的 Config,他會自動問您是否要選擇那一個網域,選擇後會幫您建立一個 SSL 憑證,而且 config 裡面也會自動幫您更新。
成功產生出來會出現以下的文字提示:
1 | Congratulations! You have successfully enabled "憑證網址" |
為了不讓明證過期,我們可以輸入 vi /etc/crontab
去修改這隻檔案,然後在裡面空白處輸入:
1 | # let's encrypt |
然後輸入 service crond restart
,這樣就會 **每天檢查三次(00:00 08:00 16:00)**。
建立 SSL 之前必需要做的事情
因為我們輸入下列其中一個指令時,網址會檢查是否有對應到,所以必須先去 Godaddy 或是您買網域的地方,去把 DNS 設定好,這樣才能檢查通過,不然可是會失敗。
certbot -> 產生憑證(需要輸入資訊)
certbot –nginx (如果有 config 可以快速建立並且更新)
安裝資料庫
如果你已經有在其他服務申請資料庫,這個步驟可以跳過,但如果你跟筆者一樣安裝在虛擬主機上,就可以照著以下步驟走。
首先確定你要安裝 MySQL 5.7 還是 MySQL 8.0 兩者差別可以參考 **MySQL 8.0正式版來了! 高負載讀寫效能是5.7版的2倍**,這邊不過多討論。
- 首先我們需要用到 yum-utils 套件,下面會用到 yum-config-manager 指令:
1 | $ sudo yum install yum-utils -y |
- 下載安裝相關套件:
接著安裝套件,通常看到的教學文章會安裝指定版本號套件,下面這個會將幾個版本的套件包含進去
1 | $ sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm -y |
- 啟用要安裝的 MySQL 5.7 源:
因為接下來我們需要安裝 5.7 版本,先將剛剛包含幾個本版進去的套件 MySQL 8.0 關閉,並啟用 5.7
1 | $ sudo yum-config-manager --disable mysql80-community |
- 檢查 MySQL Yum 源是否為 5.7 版本:
1 | $ sudo yum repolist enabled | grep "mysql.*-community.*" |
如果是需要安裝 8.0 最後一個會看到 MySQL 8.0 Community Server。
- 安裝 MySQL,並啟用 MySQL 服務,然後加上每次重開機會啟動的設定,在檢查啟動狀態:
1 | // 安裝 |
- 安裝完成後,現在的密碼會是一組暫時密碼,所以我們必須要更改成自己會記得的密碼,先輸入下列程式碼拿取暫時密碼,請記得要截圖留存下來,或是把最後那串密碼複製存下來,等等馬上會用到:
1 | $ sudo grep 'temporary password' /var/log/mysqld.log |
- 更改密碼並且填寫相關設定:
1 | $ sudo mysql_secure_installation |
請注意: 密碼必須包含一個大寫字母、一個小寫字母、一個數字和一個特殊符號,長度至少為 8 個字元
基本上後面開始都是一些問題,像是 是否移除 anonymous 匿名者帳號、禁止 root 從非本機登入、移除測試資料庫…等等,基本上全都填寫 **Y(同意/確定)**。
- 查看版本:
這時候輸入指令查看是否安裝完成:
1 | $ sudo mysqld -V |
- 開啟 3306 防火牆
資料庫預設都是吃 3306port 的,如果不打開會出現 Connection Refused,然後我們要設定一組可以遠端從其他地方登入的帳號,我們總不能每次都連上主機再去連進資料庫吧。
先查看防火牆是否開啟:
1 | $ firewall-cmd --query-port=3306/tcp |
開啟防火牆:
1 | $ firewall-cmd --zone=public --add-port=3306/tcp --permanent |
如果要關閉可以輸入:
1 | $ firewall-cmd --zone=public --remove-port=3306/tcp --permanent |
重新啟動防火牆:
1 | $ firewall-cmd --reload |
- 登入資料庫:
接著我們要去新增可以任意登入的用戶,我們先登入:
1 | $ mysql -u root -h localhost -p |
然後新增可以遠端登入的帳號:
1 | mysql> grant all privileges on *.* to '使用者名稱'@'IP位置' identified by'要登入的密碼'; |
// 如果想要任何地方都可以連線請在IP位置輸入 % 範例如下:mysql> grant all privileges on *.* to 'root'@'%' identified by'abc';
上面 . 為權限,這個意思是可以訪問所有的資料庫及資料表。
這樣就新增成功了,之後在任何地方都可以使用 root 登入。
使修改重新生效:
1 | mysql> flush privileges; |
- 試看看遠端連線吧!
額外小坑
出現 “permissions are too open” 的錯誤
這是您的 SSH 的權限問題,只需要輸入 chmod 400 ~/.ssh/id_rsa
或 chmod 600 ~/.ssh/id_rsa
即可解決
VUE 的 Router 導致頁面出現 404
由於我們在 Nginx 已經設定好路由就是吃到 /var/www/frontend/dist
的 index,如果被路由轉導後,可能會變成 https://xxx.xxx/index/dashboard/edit/1
之類的網址,這時候就會找不到對應該渲染的畫面。
解決方式其實很簡單,只需要在 Nginx 的設定欓修改一下:
1 | // 找到 location 並在裡面加上 try_files 這行即可 |
頁面出現 502 Bad Gateway
查看 Nginx 的 Error config:
1 | // 詳細位置可先查看 |
裡面如果出現了 (13: Permission denied) 的關鍵字,代表你的那個專案的 Nginx 設定檔指定的 Port 是權限不足的。
這時候輸入 semanage port --list
找尋 http_port_t 可以看到後面有一串 port 號,如果沒有你的就代表需要自己新增上去。
1 | $ semanage port --add --type http_port_t --proto tcp "你要新增的 Port 號" |
然後再次輸入剛剛的 semanage port --list
就會看見了!
Vue Build 出現錯誤
如果在使用 npm build
或 yarn build
的時候出現類似下圖錯誤:
代表你的 Node 版本有問題,筆者發生這問題是因為自己的 Node 版本太新了,舊的某些套件不支援,所以必須要改變版本或是更新套件,筆者安裝和自己本地一樣的舊版本就解決了。
如果使用 nvm 的話,可以先使用 Node -v 查看自己本地的版本,然後再使用 nvm ls-remote 查看可安裝版本,接著使用 nvm install 版本號 安裝指定版本,最後可以使用 nvm ls 查看目前可使用的版本!
使用 nvm 安裝得好處就不多說了,主要可以想成就是拿來管理 Node 版本的管理工具,推薦安裝一下。
Conclusion & 結論
沒想到 2021 第一篇文章竟然是先記錄環境設定的筆記,其實原本打算先寫一篇完成全端後的心得文,也算是完成自己寫程式兩年的期許,完成電商的小里程碑。
雖然嘴裡常常在寫不出程式碼時不時的咒罵,但其實親身體會一次才是最好的學習,並且會有滿滿德成就感。
最後要說說,上面有提到為什麼後來改用 Linode 了,因為筆者在 DigitalOcean 第一次更改環境時,最後輸入了 Reboot 想重啟機器,但關掉之後就再也連不進去,連 Console 也不行,最後整個砍掉重新在建立一次。
就在今天弄了一天之後筆者在安裝 Mysql 的過程卡住了,索性關閉機器,再度重啟時,又出現了下面這張圖,網站的 Console 也不能開啟,一氣之下就改用其他家主機了。
這邊真的要再度感謝幫助我的各路大神,沒有你們我沒辦法走這麼遠,謝謝你們!
參考網站
Stack Overflow — ssh “permissions are too open” error
Stack Overflow — How to handle 404 error request in vuejs SPA with nginx server
Codebug — node.js:Nodejs Nginx錯誤:(13:權限被拒绝)連線到上遊時