私有化輕量級持續集成部署方案–03-部署web服務(下)


提示:本系列筆記全部存在於
Github
可以直接在
Github 查看全部筆記

配置介面代理

前後端分離情況下,前端請求後端介面最常用的一種方式就是使用反向代理,反向代理會讓瀏覽器認為是同源路徑,也就實現了跨域操作。

目前流行的前端打包器,webpackvite 在開發模式,都具有反向代理的配置。

Nginx 伺服器,反向代理也是最重要的功能之一,之前的 網關實現方式就是使用了反向代理。此篇中主要是配置介面代理 和 通過鏡像參數 配置 Nginx 介面代理

Dev 測試

當前使用的 web 模板項目中對於開發環境的 API 代理和訪問介面請求都已經設置好了。只需要設置一下配置地址。

介面是在網上找的一個,介面地址為: //jsonplaceholder.typicode.com/posts/1

  1. .env.development 文件中配置代理域名地址

  2. 使用 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 //jsonplaceholder.typicode.com/$1$is_args$args;
        }
    }
}

第二個 location 就是配置 API 介面代理。

location 配置了監聽路由以 /api 開頭的請求路由。將 /api 開頭的請求路由轉發到 proxy_pass 屬性值

監聽路由使用了正則匹配, proxy_pass 屬性值中的 $1location 監聽路由中 (.*) 的匹配項。

注意:

  1. 使用域名做反向代理地址時,需要添加 resolver 解析。 //developer.aliyun.com/article/486252
  2. 使用域名訪問時,需要改變 Host 請求頭,否則會報 403//blog.csdn.net/liyyzz33/article/details/95340765

添加成功後可以重新打包鏡像然後本地部署測試。正常的情況下就如下圖可以正常訪問。

鏡像版本改為 1.0.1


代理地址參數化

接下來完成一個操作:將 API 代理地址變為啟動容器參數化配置。

參數化可以將 API 代理地址作為一個變數的形式脫離於鏡像。具有更好的擴展性。

代理地址參數化思路

代理地址參數化這個操作可以分為兩個步驟思考

使用 Nginx 變數

第一步是將 Nginxproxy_pass 屬性值變數化,Nginx 配置中是支援變數的,變數定義是以 $ 開頭的。

Nginx 自身有許多變數提供,例如 $hostNginx 還支援自定義變數。 可以使用 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_URLNginx 變數名稱,第二個 $SERVER_URLNginx 變數值,而這個變數值又是一個變數,這個變數由 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=//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 文件中新增了

  1. 創建了存放 sh 目錄。
  2. varibale.sh 文件拷貝到鏡像內
  3. 使用 ENV 命令提供一個環境變數的默認值
  4. 設置 sh 執行許可權
  5. RUN 命令執行 sh 文件

新增的命令是將 sh 文件寫入到鏡像中,進行執行。並設置了環境變數初始值。

代理地址參數化部署

測試部署

此時可以構建鏡像進行本地測試,在此直接貼出測試結果。

進入容器內部查看 /etc/nginx/conf.d/server.variable 文件已經成功寫入。

啟動容器時沒有設置 -e 屬性,默認使用的是鏡像內部默認值。可以啟動容器時指定環境變數。有興趣朋友可以將默認值改為其它值就行測試。

docker run –name web -p 7777:80 -itd -e SERVER_URL=//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: //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 //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 //10.0.24.12:9000;
        }
    }
    server {
        listen 80;
        return 307 //$host$request_uri;
    }
}

第三步

上傳配置文件並且重新載入配置文件

docker exec -it gateway nginx -s reload

重新載入 網關(Nginx) 配置後可以使用域名訪問。

Tags: