前后端分离,如何在前端项目中动态插入后端API基地址?(in docker)
开门见山,本文分享前后端分离,容器化前端项目时动态插入后端API基地址,这是一个很赞的实践,解决了前端项目容器化过程中受制后端调用的尴尬。
尴尬从何而来
常见的web前后端分离:前后端分开部署,前端项目由nginx承载打包文件,反向代理请求。
应用的某些部分必须是可配置的,比如API调用基地址
,
前端打包的时候需要统一插入该地址形成完整chunk files。
# ------------------------------------------------------
# generate chunk file
# ------------------------------------------------------
FROM node:10-alpine as builder
# install and cache app dependencies
COPY package.json package-lock.json ./
RUN npm install && mkdir /react-frontend && mv ./node_modules ./react-frontend
WORKDIR /react-frontend
COPY . .
RUN npm run build
# ------------------------------------------------------
# Production Build
# ------------------------------------------------------
FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /react-frontend/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
当在Docker中打包前端,或许会尝试用镜像构建参数Arg/Env
来传递后端API调用基地址,但这样是很不理想的:
打包时参数被统一插入,打包结果chunk files作为最终镜像的一部分,导致最终的前端镜像会与后端API地址强关联。
或许你会针对不用的后端环境(canary、staging、production)构建不同的前端镜像,但这是一次又一次的工作量,并不是最佳实践。
下面分享一个容器执行阶段动态插入后端API基地址的实践
前端独立部署,动态插入后端API基地址(in Docker)
我希望将API基地址延迟到生成容器
阶段(与构建镜像的过程解耦), 这样我就可以使用一个镜像,针对不同的环境传参形成不同的前端容器。
前端项目插入配置的脚本如下:
// FILE: set-env.ts
...
export const environment = {
production: ${isProd},
apiBaseUrl: 'API_BASE_URL',
version: 'v${require('../package.json').version}'
};
...
我们在前端配置中写入API_BASE_URL
占位符,按照既定流程前端打包;
Dockerfile CMD指令指示容器如何运行:
- 用真实值替换前端chunk files中原插入的
API_BASE_URL
占位符 - 使用nginx承载替换后的chunk files
# FILE: Dockerfile
...
EXPOSE 80
COPY --from=builder /react-frontend/replace_api_url.sh /
CMD ["sh", "replace_api_url.sh"]
下面是replace_api_url.sh的内容:
#!/usr/bin/env sh
find '/usr/share/nginx/html' -name '*.js' -exec sed -i -e 's,API_BASE_URL,'"$API_BASE_URL"',g' {} \;
nginx -g "daemon off;"
正常构建镜像之后;现在生成容器时,可通过环境变量传参替换原前端chunk files的API_BASE_URL字符串
docker build -t front .
docker run -p 3000:3000 -e API_BASE_URL=http://somebackend.com/api front
总结输出
这是一个巧妙的设计,让我们在前端独立容器化部署时,能解耦后端API基地址,避免了一次又一次的构建镜像工作量。
Dockerfile CMD指令包装的容器启动脚本:让我们在nginx承载前端打包文件之前,做一次字符串替换,成功将后端API基地址“延迟”到容器运行阶段。
前后端分离,如何在前端项目中动态插入后端API基地址?(in docker)的更多相关文章
- 前后端分离之Web前端架构设计
架构设计:前后端分离之Web前端架构设计 在前面的文章里我谈到了前后端分离的一些看法,这个看法是从宏观的角度来思考的,没有具体的落地实现,今天我将延续上篇文章的主题,从纯前端的架构设计角度谈谈前后端分 ...
- Spring Boot + Vue 前后端分离开发,前端网络请求封装与配置
前端网络访问,主流方案就是 Ajax,Vue 也不例外,在 Vue2.0 之前,网络访问较多的采用 vue-resources,Vue2.0 之后,官方不再建议使用 vue-resources ,这个 ...
- dotnetcore+vue+elementUI 前后端分离 三(前端篇)
说明: 本项目使用了 mysql employees数据库,使用了vue + axois + element UI 2.0 ,演示了 单页程序 架构 ,vue router 的使用,axois 使用, ...
- [Vue 牛刀小试]:第十六章 - 针对传统后端开发人员的前端项目框架搭建
一.前言 在之前学习 Vue 基础知识点的文章中,我们还是采用传统的方式,通过在 html 页面上引用 vue.js 这个文件,从而将 Vue 引入到我们的项目开发中.伴随着 Node.js 的出现, ...
- 前端项目中使用jsencrypt进行字段加密
前端项目中使用jsencrypt进行字段加密. 使用步骤:①获取公钥②实例化对象③设置公钥④将所需数据进行加密然后返回. 进行一个简单的封装如下 /** * npm install jsencrypt ...
- 在Vue&Element前端项目中,使用FastReport + pdf.js生成并展示自定义报表
在我的<FastReport报表随笔>介绍过各种FastReport的报表设计和使用,FastReport报表可以弹性的独立设计格式,并可以在Asp.net网站上.Winform端上使用, ...
- 在Vue&Element前端项目中,对于字典列表的显示处理
在很多项目开发中,我们为了使用方便,一般都会封装一些自定义组件来简化界面的显示处理,例如参照字典的下拉列表显示,是我们项目中经常用到的功能之一,本篇随笔介绍在Vue&Element前端项目中如 ...
- 在Vue前端项目中,附件展示的自定义组件开发
在Vue前端界面中,自定义组件很重要,也很方便,我们一般是把一些通用的界面模块进行拆分,创建自己的自定义组件,这样操作可以大大降低页面的代码量,以及提高功能模块的开发效率,本篇随笔继续介绍在Vue&a ...
- 架构设计:前后端分离之Web前端架构设计
在前面的文章里我谈到了前后端分离的一些看法,这个看法是从宏观的角度来思考的,没有具体的落地实现,今天我将延续上篇文章的主题,从纯前端的架构设计角度谈谈前后端分离的一种具体实现方案,该方案和我原来设想有 ...
随机推荐
- Word转pdf,再转图片插入PDF
WORD转PDF所需jar包: https://yangtaotao.lanzous.com/ice1jlc PDF转图片所需jar包: https://yangtaotao.lanzous.com/ ...
- JavaWebCase
目录 案例:用户登录 用户登录案例需求 分析 开发步骤 创建项目 创建数据库环境 创建包 com.my.domain,创建类User 创建包 com.my.dao,创建类UsesrDao,提供logi ...
- Anaconda 常用命令大全
帮助目录 检查conda版本 升级当前版本的conda 创建一个新环境 激活新环境 Linux,Mac: Windows: 列出所有的环境 切换环境(activate/deactivate) Linu ...
- Spring杂谈 | 什么是ObjectFactory?什么是ObjectProvider?
在Spring的学习过程中,总是学的越多,不懂的越多.本来只是想将ApplicationContext的相关内容全部梳理一遍,结果发现涉及的东西越来越多,比如上篇文章中的ResolvableType, ...
- 多线程测试时的辅助类--CountDownLatch
多线程时,很多时候由于mian线程与多线程结束时间不可控,造成无法测试 辅助测试类---CountDownLatch 我看的视频教程匿名内部类无法使用外部的变量,所以CountDownLatch定义为 ...
- Web_php_include
0x01 函数分析 <?php show_source(__FILE__); echo $_GET['hello']; $page=$_GET['page']; while (strstr($p ...
- mybatis 插入数据返回ID
hibernate中插入数据后会返回插入的数据的ID,mybatis要使用此功能需要在配置文件中显示声明两个属性即可:
- JTextpane 添加行号
最近项目需求,需要在JTextPane上添加行号等信息,网上找了好久只找到JTextArea添加行号信息,copy网上的程序研究了下,发现自己改改就可以让JTextPane显示行号! 代码: pack ...
- Tomcat session的实现:线程安全与管理
本文所说的session是单机版本的session, 事实上在当前的互联网实践中已经不太存在这种定义了.我们主要讨论的是其安全共享的实现,只从理论上来讨论,不必太过在意实用性问题. 1. sessio ...
- Dockerfile-Namespace
Docker核心-Namespaces(命名空间) 1)概念: 命令空间是Linux内核的一个强大的特性.每个容器都有自己单独的命令空间,运行在其中的应用都是独立在操作系用中运行一样.命名空间保证了容 ...