配置介面代理
前後端分離情況下,前端請求後端介面最常用的一種方式就是使用反向代理,反向代理會讓瀏覽器認為是同源路徑,也就實現了跨域操作。
目前流行的前端打包器,webpack
、vite
在開發模式,都具有反向代理的配置。
Nginx
伺服器,反向代理也是最重要的功能之一,之前的 閘道器
實現方式就是使用了反向代理。此篇中主要是配置介面代理 和 通過映象引數 配置 Nginx
介面代理
Dev 測試
當前使用的 web 模板專案中對於開發環境的 API 代理和訪問介面請求都已經設定好了。只需要設定一下配置地址。
介面是在網上找的一個,介面地址為: http://jsonplaceholder.typicode.com/posts/1
-
.env.development 檔案中配置代理域名地址
-
使用 Http 模組請求
配置完畢後使用 npm run dev
執行便可以看到請求結果。
Nginx 代理介面
Nginx
中使用代理也極為簡單,只需要配置 location
events {
worker_connections 1024;
}
http {
include mime.types;
default_type text/html;
sendfile on;
keepalive_timeout 65;
charset utf-8;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ~* /api/(.*) {
resolver 8.8.8.8;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://jsonplaceholder.typicode.com/$1$is_args$args;
}
}
}
第二個 location 就是配置 API 介面代理。
location 配置了監聽路由以 /api 開頭的請求路由。將 /api 開頭的請求路由轉發到 proxy_pass 屬性值
監聽路由使用了正則匹配, proxy_pass 屬性值中的 $1 是 location 監聽路由中 (.*) 的匹配項。
注意:
- 使用域名做反向代理地址時,需要新增 resolver 解析。 https://developer.aliyun.com/article/486252
- 使用域名訪問時,需要改變 Host 請求頭,否則會報 403。https://blog.csdn.net/liyyzz33/article/details/95340765
新增成功後可以重新打包映象然後本地部署測試。正常的情況下就如下圖可以正常訪問。
映象版本改為 1.0.1
代理地址引數化
接下來完成一個操作:將 API 代理地址變為啟動容器引數化配置。
引數化可以將 API 代理地址作為一個變數的形式脫離於映象。具有更好的擴充套件性。
代理地址引數化思路
代理地址引數化這個操作可以分為兩個步驟思考
使用 Nginx
變數
第一步是將 Nginx
中 proxy_pass 屬性值變數化,Nginx
配置中是支援變數的,變數定義是以 $ 開頭的。
Nginx
自身有許多變數提供,例如 $host。 Nginx
還支援自定義變數。 可以使用 set 定義變數,使用變數可以設定屬性值。
proxy_pass 屬性值可以使用一個變數設定 $SERVER_URL。
location ~* /api/(.*) {
resolver 8.8.8.8;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass $SERVER_URL/$1$is_args$args;
}
$SERVER_URL 這個變數怎麼定義呢?
Nginx
支援在配置檔案中定義變數,也支援在一個檔案中定義變數,nginx.conf 中使用 include 引入定義變數的檔案。
配置檔案中可以引用一個檔案(/etc/nginx/conf.d/*.variable),然後將變數定義在這個檔案。
server {
listen 80;
include /etc/nginx/conf.d/*.variable;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ~* /api/(.*) {
resolver 8.8.8.8;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass $SERVER_URL/$1$is_args$args;
}
}
定義 Nginx 變數
第二步是定義建立 /etc/nginx/conf.d/*.variable 檔案邏輯
這個邏輯需要在 Dockerfile
定義。可以直接寫在 Dockerfile
中。
在此我定義了一個 .sh 檔案, Dockerfile
中定義執行 .sh 檔案。
#/bin/bash
# 設定多個環境變數到 environment variable
# echo -e "set \$variable1 $PATH;
# set \$variable2 $PATH;
# set \$variable3 $PATH;" >
# 設定單個環境變數到 environment variable
echo set \$SERVER_URL $SERVER_URL\; > /etc/nginx/conf.d/server.variable
deploy 目錄中建立一個 variable.sh 檔案,此檔案中寫入 建立變數檔案
echo
命令將設定變數寫入到 /etc/nginx/conf.d/server.variable 檔案中。
第一個 $SERVER_URL 是 Nginx
變數名稱,第二個 $SERVER_URL 是 Nginx
變數值,而這個變數值又是一個變數,這個變數由 Docker
提供。
此 .sh 執行配置寫在 Dockerfile
FROM nginx:latest
COPY ./dist /usr/share/nginx/html
COPY ./deploy/nginx.conf /etc/nginx
# 建立存放sh檔案目錄
RUN mkdir /etc/nginx/sh
# 將 sh 檔案 copy 到 映象檔案內
COPY ./deploy/variable.sh /etc/nginx/sh
# 設定環境變數初始值
ENV SERVER_URL=http://jsonplaceholder.typicode.com
# 設定variable.sh 執行許可權
RUN chmod a+x /etc/nginx/sh/variable.sh
# 執行sh檔案
RUN ["sh", "/etc/nginx/sh/variable.sh"]
# 容器應用埠
EXPOSE 80
在 Dockerfile
檔案中新增了
- 建立了存放 sh 目錄。
- 將 varibale.sh 檔案拷貝到映象內
- 使用 ENV 命令提供一個環境變數的預設值
- 設定 sh 執行許可權
- RUN 命令執行 sh 檔案
新增的命令是將 sh 檔案寫入到映象中,進行執行。並設定了環境變數初始值。
代理地址引數化部署
測試部署
此時可以構建映象進行本地測試,在此直接貼出測試結果。
進入容器內部檢視 /etc/nginx/conf.d/server.variable 檔案已經成功寫入。
啟動容器時沒有設定 -e 屬性,預設使用的是映象內部預設值。可以啟動容器時指定環境變數。有興趣朋友可以將預設值改為其它值就行測試。
docker run --name web -p 7777:80 -itd -e SERVER_URL=http://jsonplaceholder.typicode.com yxs970707/deploy-web-demo:1.0.1
伺服器部署
測試成功後,將映象推送到 Docker Hub
, 進行重新部署
注意:重新部署前注意要清除原容器和 Volume,以保持整潔
version: '3.9'
volumes:
web-html:
name: web-html
driver: local
driver_opts:
o: bind
type: none
device: /volumes/web/html
web-nginx:
name: web-nginx
driver: local
driver_opts:
o: bind
type: none
device: /volumes/web/nginx
services:
nginx:
image: yxs970707/deploy-web-demo:1.0.1
container_name: web
restart: always
ports:
- 7777:80
volumes:
- web-html:/usr/share/nginx/html
- web-nginx:/etc/nginx
environment:
SERVER_URL: http://jsonplaceholder.typicode.com
以上是新的 YMAL 配置檔案,
配置檔案中新增了一個新增了一個新的 Volume,用於將容器內 /etc/ninx 目錄檔案暴露。
啟動時配置了 SERVER_URL 環境變數。
PS: 需要建立 /volumes/web/nginx 和 /volumes/web/html 目錄
使用此檔案進行啟動,啟動成功後進行訪問。
因為使用了 Volume 掛載了 /etc/nginx,可以在宿主機目錄檢視 .sh 和 .variable 檔案
設定閘道器
部署完 web 專案後,接下來設定這個服務的閘道器
。
當前服務要部署到主域名。
第一步
申請並上傳伺服器 SSL 證照,並且建立 /volumes/gateway/logs/web 目錄
第二步
閘道器(Nginx)
檔案中配置 web 專案,代理到 7777 埠。
events {
worker_connections 1024;
}
http {
include mime.types;
default_type text/html;
sendfile on;
keepalive_timeout 65;
charset utf-8;
# 開啟壓縮
gzip on;
# 檔案壓縮型別
gzip_types text/plain text/css application/javascript application/json application/xml;
#設定壓縮比率
gzip_comp_level 5;
server {
#SSL 訪問埠號為 443
listen 443 ssl http2;
#填寫繫結證照的域名
server_name mwjz.live;
#日誌
error_log /var/log/nginx/web/error.log;
access_log /var/log/nginx/web/access.log;
#證照檔案
ssl_certificate /etc/nginx/conf.d/ssl/mwjz/mwjz.live_bundle.crt;
#證照金鑰檔案
ssl_certificate_key /etc/nginx/conf.d/ssl/mwjz/mwjz.live.key;
ssl_ciphers SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!3DES:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://10.0.24.12:7777;
}
}
server {
#SSL 訪問埠號為 443
listen 443 ssl http2;
#填寫繫結證照的域名
server_name portainer.mwjz.live;
#日誌
error_log /var/log/nginx/portainer/error.log;
access_log /var/log/nginx/portainer/access.log;
#證照檔案
ssl_certificate /etc/nginx/conf.d/ssl/portainer/portainer.mwjz.live_bundle.crt;
#證照金鑰檔案
ssl_certificate_key /etc/nginx/conf.d/ssl/portainer/portainer.mwjz.live.key;
ssl_ciphers SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!3DES:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://10.0.24.12:9000;
}
}
server {
listen 80;
return 307 https://$host$request_uri;
}
}
第三步
上傳配置檔案並且重新載入配置檔案
docker exec -it gateway nginx -s reload
重新載入 閘道器(Nginx)
配置後可以使用域名訪問。