2023-08-02
如何使用Nginx設置二個不同網站
今天要來教大家的是如何在Ubuntu上面設置二個專案,一個是前端框架使用的是Next.js,在React環境下,另一個是後端框架使用的是Node.js。
前端的專案教學會再另外寫一篇文章,今天這篇文章會專注在如何部署Next.js跟Node.js,並二個專案都可以有自己專屬的網址,以及加上SSL保護網址設定。
這些內容都是我自己實際部署和設定的結果,如果有其它的問題,可以問ChatGPT,或google搜尋相關教學設定。
那我們來開始吧!
SSH連線
打開電腦的Terminal,找到.pem檔案(當初建立的EC2時,會下載的一份ssh連線檔),後面的ec2-url
是ssh要連線的網址,請查AWS EC2的Server顯示連線網址。
$ ssh -i connect.pem ubuntu@ec2-url
連線成功後,會進入到ubuntu@ip
使用者的console,新建立好的Ubuntu系統是沒有任何工具,所以要先安裝一些部署工具。
安裝Nginx
$ sudo apt update
$ sudo apt install nginx
Nginx常用的指令如下
檢查狀態
$ sudo systemctl status nginx
開啟
$ sudo systemctl start nginx
停止
$ sudo systemctl stop nginx
修改配置後,重新啟動
$ sudo systemctl restart nginx
修改配置後,重新裝載
$ sudo systemctl reload nginx
禁用Nginx
$ sudo systemctl disable nginx
啟用Nginx
$ sudo systemctl enable nginx
當Nginx安裝和啟動後,就可以直接打開瀏覽器,並輸入IP址,測試網站是不是成功。
這時候應該會看到Nginx的成功畫面,如果沒有成功,請檢查看看/var/www/html
底下是否有nginx的index.html檔案,或是檢查看看nginx是否有正常啟動。
Nginx的port預設為80。
設定防火牆(ufw)
查看可以設定的內容
$ sudo ufw app list
輸出結果如下:
Output
Available applications:
Nginx Full (port: 80, 443)
Nginx HTTP (port: 80)
Nginx HTTPS (port: 443)
OpenSSH (port: 22)
啟用防火牆
$ sudo ufw enable
在這裡加入Nginx Full, OpenSSH,因為Nginx Full包含80跟443的port,OpenSSH是包含22的port,所以這裡只要用Nginx Full就可以允許使用http或是https外連進來。
請記得,一定要啟用OpenSSH或是sudo ufw allow ssh
,不然無法從外部使用SSH連進AWS EC2哦!
$ sudo ufw allow 'Nginx Full'
$ sudo ufw allow 'OpenSSH'
$ sudo ufw status
輸出結果如下:
Output
Status: active
To Action From
-- ------ ----
Nginx Full ALLOW Anywhere
OpenSSH ALLOW Anywhere
Nginx Full (v6) ALLOW Anywhere (v6)
OpenSSH (v6) ALLOW Anywhere (v6)
確認上面的Status
是否為active
的狀態,表示防牆已經正常啟用。
接下來安裝curl,並使用curl來下載安裝nvm,nvm是用來切換並安裝不同版本的node,有一些專案會因為node的版本不同,需要進行系統切換,這裡使用nvm的原因,是因為AWS EC2的Ubuntu沒辦法直接更新到最新的node版本,所以要用nvm來安裝。(因為我畢竟不是AWS EC2的專家)
安裝curl
$ sudo apt update
$ sudo apt upgrade
$ sudo apt-get install curl
$ curl --version
成功安裝curl後,下面是如何使用curl來執行命令。
Usage
Once installed you can use it as follows to see the headers:
$ curl -I https://www.google.co.in/
$ curl -I https://www.cyberciti.biz/
Sample outputs:
HTTP/2 200
date: Mon, 29 Jul 2019 13:13:08 GMT
content-type: text/html; charset=UTF-8
set-cookie: __cfduid=d5292058141c28e3cda2d9501688cff531564405988; expires=Tue, 28-Jul-20 13:13:08 GMT; path=/; domain=.cyberciti.biz; HttpOnly; Secure
vary: Accept-Encoding
strict-transport-security: max-age=15552000
x-whome: l-cbz02
cf-cache-status: HIT
age: 102433
x-content-type-options: nosniff
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 4fdf59334ab9dcb5-MAA
Or download a file from a server using curl itself:
$ curl -o output.file http://server1.cyberciti.biz/bar.foo.txt
安裝nvm
$ sudo apt update
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
說明 | 指令 |
---|---|
查看版本清單 | nvm ls |
查看目前版本 | nvm --version |
安裝node | nvm install node |
安裝最新版本 | nvm install -lts |
安裝穩定版本 | nvm install stable |
指定安裝node版本 | nvm install 8.16.2 |
變更node版本 | nvm use v14.10.0 |
移除node版本 | nvm uninstall 11.5 |
安裝node
$ nvm install node
安裝gh
這邊我是使用gh來下載遠端的git repository,如果習慣用git的人,也可以直接跳過這個步驟,請直接安裝git。
sudo apt update
sudo apt upgrade
sudo apt install gh
使用方法
安裝完畢後,要進行帳號驗證登入,才能使用gh下載遠端的repository
gh auth login
從網頁輸入驗證碼
打開瀏覽器,並將下面的網址貼上
https://github.com/login/device
在auth login的時候,應該會看到一串數字,First copy your one-time code: D61D-2887
,將數字拷貝,然後貼到欄位上。
按下continue按鈕,會跳出詢問是否要Authorize github
,按下之後,會轉頁並詢問帳號密碼。
輸入帳號密碼後,看到此頁就表示驗證完整,可以開始使用gh了!
恭喜!可以使用gh命令了
gh --version
gh repo clone {github網址} {新的資夾名稱}
下載Github repository
這邊的範例是下載我自己的後端node.js專案
$ gh repo clone bxbdev/next-chat-server-side server
安裝 git
$ sudo apt-get install git-all
安裝yarn
$ npm i yarn -g
安裝pm2
這邊我是使用pm2的方式,來管理執行不同的專案,下面是啟動程式或是專案的方法 啟動js
$ pm2 start app.js
啟動python
$ pm2 start python-app.py
啟動使用不同的port
$ pm2 start binary-file -- --port 1520
說明 | 指令 |
---|---|
全域安裝pm2 | npm i -g pm2 yarn global add pm2 |
顯示管理程序狀態 | pm2 [list|ls|status] |
清空 log | pm2 flush |
輸出logs | pm2 logs |
啟動專案 | pm2 start name |
停止專案 | pm2 stop name |
停止所有專案 | pm2 stop all |
刪除專案 | pm2 delete name |
刪除所有專案 | pm2 kill |
監聽系統和專案執行狀態 | pm2 monit |
監聽資料變更時,自動重啟 | pm2 start --watch folder |
如果terminal出現下面的訊息時,可改用npx pm2
就可以正常使用指令
pm2: command not found
或是退出AWS EC2的連線,再重新使用ssh連線,就可以正常使用pm2命令了。 一般安裝完畢後,需要關閉Terminal,再重新開啟,才可以使用。
建立新專案到Nginx底下
$ sudo mkdir -p /var/www/html/app_name/
從git下載repository後,會直接在最外層的目錄,所以要用拷貝的方法,將檔案拷貝到/var/www/html
底下,因為沒有修改html底下的目錄權限,這邊可自行查詢如何修改Ubuntu的目錄權限。
搬移資料夾並覆蓋內容的指令
$ sudo cp -rT server /var/www/html/server
$ cd /var/www/html
進到html的目錄底下後,執行pm2,因為我的server底下只有一個index.js,所以只要在外層的目錄直接執行,就會自動啟動了。
$ pm2 start server
$ pm2 ls
讓PM2在系統重啟時,自動啟動
$ pm2 startup
把目前的執行狀態存起來,下次重啟後,會自動啟動一樣的專案,如果內容還有可能會變更的話,就需要將logs清除掉,不然修改的專案內容會因為pm2重新啟動,不會看到新的修改內容。
$ pm2 save
如果不希望啟動的名稱和資料夾名稱一樣的話,可以使用下面指令流程
$ cd /var/www/html/server
$ pm2 start index.js --name server.seekdecor.online
網站設定
新增設定檔
$ sudo touch /etc/nginx/sites-available/site_name
編輯設定檔
$ sudo nano /etc/nginx/sites-available/site_name
Nginx網站設定檔的命名方式,可以是名稱,也可以是網址方式來命名
/etc/nginx/sites-available/app
/etc/nginx/sites-available/www.domain.com
/etc/nginx/sites-available/sub1.domain.com
/etc/nginx/sites-available/sub2.domain.com
以下是我的後端server的範例設定,proxy_pass是反向代理位置,啟動後的project port。
http://localhost:5000
這邊的port,要看專案使用的port是指定哪一個,比如next.js預設是3000,那這裡的port就要換成http://localhost:3000
。
server {
listen 80;
listen [::]:80;
root /var/www/html/server;
index index.html index.htm index.nginx-debian.html;
server_name server.seekdecor.online;
location / {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
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;
}
}
將文件同步連結到/etc/nginx/sites-enabled/
,可方便日後修改同步
$ sudo ln -s /etc/nginx/sites-available/server /etc/nginx/sites-enabled/
這個動作完成後,需要指定server.seekdecor.online
的ip位址,需要檢查一次nginx的狀態後,確定新增的內容沒有任何問題,然後再重新啟動nginx
$ sudo nginx -t
出現下面的訊息,表示nginx正常沒有問題,如果有問題,就表示文件設置有問題。
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
沒有問題,就可以重新啟動nginx了,這裡也可以使用reload
$ sudo systemctl restart nginx
瀏覽器打開後,輸入網址連線http://server.seekdecor.online
,看到頁面輸出的內容就表示所有設定都成功了,第一個專案就設定完成了,重複建立新的nginx網站設定檔。
設定SSL
Let's Encrypt Client
$ sudo apt install -y certbot
# stop nginx service, this is a must
$ sudo systemctl stop nginx
# generate an ssl certificate
$ sudo certbot certonly -d sub1.domain.com -d sub2.domain.com
可以一次新增二個不同的subdomain網站,這裡的sub1.domain.com跟sub2.domain.com請直接換成其它網址。
文件設置SSL
再次編輯文件
$ sudo nano /etc/nginx/sites-available/server
新增SSL設定
server {
listen 443 ssl;
# ssl configuration;
ssl_certificate /etc/letsencrypt/live/server.seekdecor.online/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/server.seekdecor.online/privkey.pem;
}
SSL完整設定
注意這裡的ssl configuration,如果subdomain使用的是同一個檔案,另一個新增的檔案,也要設置一模一樣的檔案。
第一個server的內容,是一般http的連線,如果不希望使用者用一般的網址進到網站的話,可以加上return 301 https://example.domain.com$request_uri;
,會自動轉址到https。
第二個server的內容,root的位置是指定專案的目錄,比如目錄的位置是在/app/my_blog的話,那就要將root的修改為root /app/my_blog
server {
listen 80;
listen [::]:80;
server_name server.seekdecor.online;
return 301 https://server.seekdecor.online$request_uri;
}
server {
listen 443 ssl;
server_name server.seekdecor.online;
root /var/www/html/server;
index index.html index.htm index.nginx-debian.html;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
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;
}
# ssl configuration;
ssl_certificate /etc/letsencrypt/live/server.seekdecor.online/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/server.seekdecor.online/privkey.pem;
}
重新測試並重新啟動nginx服務器
$ sudo nginx -t
$ sudo systemctl restart nginx
打開瀏覽器測試網址,如果Chrome的網址旁邊有出現鎖頭,就表示設定成功。
結語心得
這是經過不斷嘗試好幾次AWS EC2整個掛掉後,不得已終止Instance,然後又重新建立新的Instance,最後實測的結果,最完整的紀錄。
還得感謝水球軟體學院的大佬們幫忙提點,才能夠這麼順利的架好二個不同網址的網站,自己一個人光設定Nginx就失敗好多次,最後終於理解,並且知道怎麼設定網站。