前端部署采用 docker 的方式, 实现在容器启动时传递环境变量, 请求不同服务地址

实现思路: 定义.env.xxx 文件(环境变量赋值),在compose.yml中引入.env.xxx 文件,环境变量通过nginx的sub_filter放到html的meta标签里
———————————————————-【etl-ui.env】——————————————————————–

API_REQUEST_ADDRESS=http://xxx.xxx.x.xx:8601

———————————————————-【compose.yml】——————————————————————–

compose.yml中前端容器中添加env_file, 引入环境变量配置文件

version: "6.6"name: myy-systemservices:myy-myy-ui-1:container_name: myy-myy-ui-1image: xxx.xxx.x.xx:8084/myy-app-ui:latestrestart: unless-stoppedports:- "8001:8700"env_file:- etl-ui.envdeploy:resources:limits:memory: 8Genvironment:TZ: Asia/Shanghaidepends_on:- myy-myy-ignite-1

———————————————————-【entrypoint.sh】——————————————————————–
在Dockerfile同级目录下添加entrypoint.sh文件, 获取容器启动时传入的环境变量API_REQUEST_ADDRESS的值保存到变量API_REQUEST_ADDRESS_VAL中

#!/bin/bashsed -i "s|API_REQUEST_ADDRESS_VAL|${API_REQUEST_ADDRESS}|g" /usr/share/nginx/html/index.htmlexec nginx -g 'daemon off;'

———————————————————-【Dockerfile】——————————————————————–
通过nginx的sub_filter放到html的meta: 复制entrypoint.sh,设置执行权限和容器启动入口

COPY entrypoint.sh /# 设置执行权限RUN chmod +x /entrypoint.sh# 设置容器启动时的入口ENTRYPOINT ["/entrypoint.sh"]

Dockerfile完整代码:

# Stage 1: 构建Node.js应用 FROM node:16.14.0 AS builderWORKDIR /app RUN npm cache clean —forceCOPY package*.json ./RUN npm install --force --registry=http://119.3.241.212:8088/repository/npm-groupCOPY . .RUN npm run build:sit# Stage 2: 构建Nginx镜像FROM nginx:latestWORKDIR /usr/share/nginx/html# 将Node.js应用构建结果复制到Nginx镜像中COPY --from=builder /app/dist/ .# 可选:复制Nginx配置文件COPY nginx.conf /etc/nginx/nginx.conf# 暴露端口EXPOSE 8700COPY entrypoint.sh /# 设置执行权限RUN chmod +x /entrypoint.sh# 设置容器启动时的入口ENTRYPOINT ["/entrypoint.sh"]

———————————————————-【nginx.conf】——————————————————————–

usernginx;worker_processes1;error_log/var/log/nginx/error.log warn;pid/var/run/nginx.pid;events {worker_connections1024;}http {include /etc/nginx/mime.types;default_typeapplication/octet-stream;log_formatmain'$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log/var/log/nginx/access.logmain;sendfileon;#tcp_nopush on;keepalive_timeout65;gzip_static on;gzip_proxiedexpired no-cache no-store private auth;gzip_disable"MSIE [1-6]\.";gzip_vary on;gzipon;gzip_min_length 1k;gzip_buffers 4 16k;gzip_comp_level 9;gzip_types text/plain application/javascript application/csstext/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;client_max_body_size 20m;server {listen 8700;listen[::]:8700;server_namelocalhost;location / {root /usr/share/nginx/html;indexindex.html index.htm;try_files $uri $uri/ /index.html;}# 静态资源地址 (其中 /myy/myy-server/为上下文)location ~* ^/myy/myy-server/(.*)$ {rewrite ^/myy/myy-server/(.*)$ /$1 last;}error_page 500 502 503 504/50x.html;location = /50x.html {root /usr/share/nginx/html;}}}

———————————————————-【index.html】——————————————————————–
public目录下的index.html
添加 , 存储容器启动时传入的环境变量API_REQUEST_ADDRESS_VAL

favicon.ico" rel="icon" />static/css/loading.css?random="rel="stylesheet"/><meta content="" name="author" /><script src="static/js/web-report-vue.min.js"><!-- window.Performance({domain: `/api/v1/report/web`,add: {appId: ``}}); -->

(function () {var ua = navigator.userAgent.toLocaleLowerCase();var browserType = "",browserVersion = "";if (ua.match(/msie/) != null || ua.match(/trident/) != null) {browserType = "IE";browserVersion =ua.match(/msie ([\d.]+)/) != null? ua.match(/msie ([\d.]+)/)[1]: ua.match(/rv:([\d.]+)/)[1];if (1 * browserVersion < 12) {document.body.innerHTML = "

请在Chrome浏览器上使用系统

" +"

点击下载

";}}})();

———————————————————-【服务请求】——————————————————————–
axios请求服务时拿到meta标签content 属性里面存储的API_REQUEST_ADDRESS_VAL的值,即为需要请求的后台服务地址

const CUSTOM_API_REQUEST_ADDRESS = document.querySelector(‘meta[name=“API_REQUEST_ADDRESS”]’)?.getAttribute(‘content’)
const API_CONTEXT = ‘/myy/myy-server’
const requestUrl = process.env.NODE_ENV === “development” ? “” : (CUSTOM_API_REQUEST_ADDRESS+API_CONTEXT)
const instance = axios.create({
baseURL: requestUrl,
timeout: requestTimeout
// headers: {
// “Content-Type”: contentType
// }
});