首页 >> 大全

在Dockerized环境中应用Angular运行时配置

2023-09-16 大全 36 作者:考证青年

随着向云优先的转变以及托管基础架构和业务流程(例如EWS,Azure AKS或GCP群集)的兴起,应用程序环境需要进行准备和调整以适应新出现的需求。 这不是什么新鲜事,也不是未知数,但是承认这一事实是第一步,而且可能是第一步。

由内而外的深潜

让我们从用户的角度出发,分解技术架构。 从用户在浏览器中输入应用程序URL的位置开始访问精心设计的应用程序时,幕后的技术设置是什么样的?

应用配置并行不正确__应用配置发生问题怎么办

图片来自

启动的第一个配置是将URL映射到IP地址的DNS配置,在这些情况下,负载平衡器的IP。 负载平衡器几乎没有其他工作可以满足该名称,它会将用户的请求重定向到Web服务器正在侦听的业务流程。 当我们运行环境时,通过将此Web服务器指定为集群的入口控制器,我们将局限于此。 有多种类型的入口控制器。 我们决定使用Nginx控制器使用默认选项。

作为副节点,此层将成为可能需要特定于应用程序配置的第一层,例如,当应用程序应传输更大的数据(代理体大小)和/或支持持久操作(代理超时)时),因为nginx入口控制器具有隐式默认配置。

在入口控制器的下方,进行编排,因为 pod通过部署为应用程序容器提供服务。 在这里,可以将部署配置为指定应在其中服务容器的环境。我们再次做出了一个明确的设计决定,即容器。

我们的容器是映像,不仅包含内置的应用程序(静态),而且还包含nginx Web服务器,因为我们希望能够独立于基础架构及其编排,开发和维护而独立运行容器。 /或测试目的。 我们采用这种方法,并优先考虑灵活性和舒适性而不是性能。 镜像是完全正常构建的,使用多阶段构建来编译角度源代码并将输出与配置的nginx Web服务器捆绑在一起。

由内而外的深潜

描述了上述“从外而内”的角度之后,现在让我们集中讨论及其默认特征。 的概念确实包括环境,旨在用于这些场景的配置或定义,其中应根据您是本地开发还是在生产环境中将不同的配置应用于应用程序。 概念的缺点是,它仅是构建时配置。

这意味着在运行应用程序时,首先将其编译为静态,并且在编译时也将环境配置固定。 由于无法避免使用此静态代码,因此,除非事先知道并进行操作,否则无法根据其所运行的基础结构来配置应用程序。

如何将配置更改为运行时配置

重新设计应用程序以使其与和完美结合的第一步是将环境策略更改为运行时配置。 这可以通过使用Ajax / XHR调用来代替动态获取配置来摆脱默认的环境概念来实现。 @在中对此进行了更详细的描述。

简而言之,我们实现了一个配置服务,该服务在应用程序启动时使用实例化,该服务通过XHR调用获取配置。 解析程序已作为防护注册到。 应用程序的模块可以简单地注入配置。

app..ts

import { AppResolverService } from '@app/resolvers/app-resolver.service' ;
import { IndexComponent } from '@views/index/index.component' ;export const routes: Routes = [{path : '' ,canActivate : [AppResolverService],children : [{path : '' ,component : IndexComponent,pathMatch : 'full'}]}
];

app-..ts

import { Injectable } from '@angular/core' ;
import { ConfigService } from '@services/config/config.service' ;
import { EMPTY, Observable } from 'rxjs' ;
import { catchError, map } from 'rxjs/operators' ;
import { CanActivate, UrlTree } from '@angular/router' ;@Injectable({providedIn : 'root'
})
export class AppResolverService implements CanActivate  {constructor (private config: ConfigService) {}canActivate(): Observable | Promise  | boolean | UrlTree {return this .config.loadAppConfig().pipe(map( () => true ),catchError( () => EMPTY));}
}

..ts

import { Injectable } from '@angular/core' ;
import { HttpClient, HttpHeaders } from '@angular/common/http' ;
import { map } from 'rxjs/operators' ;
import { Observable } from 'rxjs' ;@Injectable({ providedIn : 'root' })
export class ConfigService  {private _config: any = {};constructor (private http: HttpClient) {}get data(): any {return this ._config ? { ...this._config } : {};}loadAppConfig(): Observable {const headers = new HttpHeaders().set( 'Content-Type' , 'application/json; charset=utf-8' );return this .http.get( `/_ngx-rtconfig.json?cb= ${ new Date ().getTime()} ` , { headers }).pipe(map( data => { for ( const key in data) {if (data.hasOwnProperty(key)) {this ._config[key.replace( 'NGX_' , '' ).toLowerCase().split( '_' ).map( ( el, i ) => (i > 0 ? el.charAt( 0 ).toUpperCase() + el.slice( 1 ) : el)).join( '' )] = data[key];}}return this .data;}));}
}

如果您仔细观察一下,我们将在方法上更进一步,也将要获取的json键的结构形式化。 这是有充分理由的,这将是非常关键的一步。

通过为json键添加一个唯一的前缀,我们以后可以利用此键为来自各个环境的键动态分配值。 对于本地开发,此设置非常简单,因为我们可以简单地将这些值直接放入.json文件中。

更进一步,将有角度的应用程序包装在容器中,我们需要根据容器环境调整.json。 因此,我们将shell脚本添加为-,在此期间,将(重新)生成具有当前环境值的.json。

-.sh

#!/usr/bin/env sh
set -eujq -n env | grep -E '\{|\}|NGX_' | sed ':begin;$!N;s/,\n}/\n}/g;tbegin;P;D' > /usr/ share/nginx/html/_ngx-rtconfig.jsonexec "$@"

文件

FROM node: 12.6 .0 -buster-slim AS builderARG NODE_ENV
ENV NODE_ENV ${NODE_ENV}
RUN mkdir -p /app
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
COPY . .
RUN yarn buildFROM nginx: 1.15 -alpineRUN apk update && apk add jq
COPY -- from =builder build/ /usr/ share/nginx/html
COPY ./ops/config/nginx-custom.conf /etc/nginx/conf.d/ default .conf
EXPOSE 80
# generate dynamic json from env
COPY ./ops/config/docker-entrypoint.sh /
ENTRYPOINT [ "/docker-entrypoint.sh" ]
CMD [ "nginx" , "-g" , "daemon off;" ]

我们在这里使用了jq和一些基本的脚本,但是当然有很多方法可以实现相同的目的。 这种方法确实允许我们在-和部署清单中将角度配置值指定为env变量。

-.yml

version: "3.5"
services:ngx-app:container_name: ngx-appbuild:context: .dockerfile: Dockerfileenvironment:NGX_API_ENDPOINT: http: //localhost:3000ports:- '4200:80'

.yml

---apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: {{ CI_PROJECT_NAME }}spec:replicas: 3revisionHistoryLimit: 3template:spec:containers:- name: {{ CI_PROJECT_NAME }}image: {{ CI_REGISTRY_IMAGE }}:{{ CI_COMMIT_SHA }}imagePullPolicy: Alwaysenv:- name: NGX_API_ENDPOINTvalue: https: //foo.com/api/ports:- name: httpcontainerPort: 80

最后,我们已经完成了建立一个灵活而一致的机制来动态管理不同情况下的角度配置/环境的工作。 到目前为止,我们还没有意识到这种方法的任何缺点!

参考文献:

From:

tags: angular

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了