gpt4 book ai didi

docker - 如何使用 Docker 将环境变量动态分配给 Angular cli 项目?

转载 作者:IT老高 更新时间:2023-10-28 21:22:08 26 4
gpt4 key购买 nike

我有运行两个单独的 docker 容器的 angular cli 项目和节点项目。

这是我的 Dockerfile

### STAGE 1: Build ###

# We label our stage as 'builder'
FROM node:carbon as builder

COPY package.json package-lock.json ./

RUN npm set progress=false && npm config set depth 0 && npm cache clean --force

## Storing node modules on a separate layer will prevent unnecessary npm installs at each build
RUN npm i && mkdir /ng-app && cp -R ./node_modules ./ng-app

WORKDIR /ng-app

COPY . .

## Build the angular app in production mode and store the artifacts in dist folder
RUN $(npm bin)/ng build --aot --build-optimizer --environment=test

### STAGE 2: Setup ###

FROM nginx:1.13.3-alpine

## Copy our default nginx config
COPY nginx/default.conf /etc/nginx/conf.d/

## Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*

## From 'builder' stage copy over the artifacts in dist folder to default nginx public folder
COPY --from=builder /ng-app/dist /usr/share/nginx/html

CMD ["nginx", "-g", "daemon off;"]

节点容器 URL 存储在 environment.ts(角度)中。

环境.ts 文件

declare var require: any;
const pack = require('../../package.json');

export const environment = {
production: false,
API_URL: 'http://localhost:3000/',
socket: 'http://localhost:3200',
appName: pack.name,
version: pack.version,
envi: 'test'
};

节点 API_URL 是在 Angular 项目的构建期间获取的。但我想在 docker run 命令期间修改环境变量。 (即)我想在 docker 容器运行时动态地将环境变量值添加到 environment.ts 文件中

例如,docker run -e API_URL=192.168.10.147:3000 -p 4200:80 --name=angular angular_image

我怎样才能做到这一点?

最佳答案

我将尝试总结我与一位开发 Angular 应用程序的同事制定的解决方案,以准确解决这个问题。为了更好地说明解决方案,我首先描述了我们的 Angular 应用程序的 dev 文件夹树(文件夹名称在方括号中),其中的每个相关元素如下所述:

+---[my angular cli project]
¦ ¦
¦ +---[src]
¦ ¦ +---[assets]
¦ ¦ ¦ +---[json]
¦ ¦ ¦ ¦ +---runtime.json
¦ ¦ ¦ ¦
¦ ¦ ¦ ..other angular application assets files ...
¦ ¦
¦ ¦ ...other angular application source files...
¦ ¦
¦ +---[dist]
¦ ¦ ...built angular files
¦ ¦
¦ +---[docker]
¦ ¦ +---[nginx]
¦ ¦ ¦ +---default.conf
¦ ¦ +---startup.sh
¦ ¦
¦ +---Dockerfile
¦
... other angluar cli project files in my project ...

在您的 Angular cli 项目中,需要在运行时用环境变量的值替换的配置数据保存在应用程序 Assets 中的静态 json 文件中。例如,我们选择将其定位在 assets/json/runtime.json。在此文件中,要替换的值的处理方式类似于以下示例中的 ${API_URL} 变量:

./src/assets/json/runtime.json:

{
"PARAM_API_URL": "${API_URL}"

...other parameters...
}

在运行时,角度代码将从该文件中读取 PARAM_API_URL 的值,其内容将在运行时使用环境值进行修改,如下所述。从技术上讲,json 是由一个 Angular 服务通过 http 读取的,也就是说,Web 应用程序对上面的静态 Assets json 文件的 URL 执行 HTTP GET 操作。

@Injectable()
export class MyComponent {

constructor( private http: Http ) {
}

...

someMethod() {

this.http.get( 'assets/json/runtime.json' ).map( result => result.PARAM_API_URL ).subscribe(
api_url => {
... do something with the api_url
eg. invoke another http get on it ...
}
);
}

}

要创建一个在运行时启动时执行环境替换的 docker 容器,将在其中放入一个脚本 startup.sh(参见下面的 Dockerfile),该脚本在容器中startup 在启动 nginx 网络服务器之前对上述文件执行 evnsubst:

./docker/startup.sh:

echo "Starting application..."
echo "API_URL = ${API_URL}"
envsubst < "/usr/share/nginx/html/assets/json/runtime.json" > "/usr/share/nginx/html/assets/json/runtime.json"
nginx -g 'daemon off;'

如下图,Dockerfile执行如下操作:将编译好的angular文件复制到./dist)中,然后将startup.sh脚本定义为CMD起点(host /dist 文件夹在 /usr/share/nginx/html 中被复制,这就是为什么这是用于定位的路径上面的 envsubst 调用中提到的 runtime.json 文件)。请注意,与您的 Dockerfile 不同,这里我们不包括 Angular cli 源的构建阶段,相反,ng build 应该由开发人员在容器镜像创建之前执行 -并且这种构建的结果预计会在 ./dist 文件夹中找到。不过,对于手头问题的解决方案而言,这是一个很小的区别。

./Dockerfile:

FROM nginx:1.13.3-alpine

## Copy our default nginx config
COPY docker/nginx/default.conf /etc/nginx/conf.d/

## Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*

## copy over the artifacts in dist folder to default nginx public folder
COPY dist /usr/share/nginx/html

## startup.sh script is launched at container run
ADD docker/startup.sh /startup.sh
CMD /startup.sh

现在,当您构建容器时,您可以运行它:

docker run -e "API_URL=<your api url>" <your image name> 

在启动 nginx 之前,给定的值将在 runtime.json 中被替换。

为了完整起见,虽然与具体问题无关,但我还包含 docker/nginx/default.conf 文件来配置 nginx 实例

./docker/nginx/default.conf:

server {

listen 80;

sendfile on;

default_type application/octet-stream;

gzip on;
gzip_http_version 1.1;
gzip_disable "MSIE [1-6]\.";
gzip_min_length 256;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 9;

root /usr/share/nginx/html;

location / {
try_files $uri $uri/ /index.html =404;
}

}

关于docker - 如何使用 Docker 将环境变量动态分配给 Angular cli 项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49650115/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com