【发布时间】:2019-02-01 11:12:00
【问题描述】:
我需要找到一种动态部署 Angular 应用程序的方法,以便同一个 docker 映像允许我进行多个部署(开发、登台、生产),其中访问 URL 被修改。
我正在使用 Angular-cli 6.4.1 在 Angular 7 中制作应用程序。 对于部署,我正在创建一个 docker 多级容器,在其中构建映像并使用 nginx 对其进行配置。
问题在于,对于部署,我们使用私有注册表,在该注册表中我们使用处理重定向的代理,因此我的应用程序将按照以下方案进行部署:{SERVER_HOST} : {PORT} / {SERVER_LOCATION}
当我尝试访问该 URL 时,仅加载 index.html,因为其余资源与基本路径“/”相关联。
Angular 在构建中提供了一个参数(--base-href),允许修改整个应用程序的路径,但是它对我没有帮助,因为我需要相同的 Docker 映像来允许我执行不同的部署,以便{SERVER_LOCATION} 参数并不总是相同的。
我也尝试在运行时读取环境变量来修改基本标记的 href 属性,但是很难执行位于索引旁边未加载的文件中的代码。
作为一种解决方法,我决定在索引中创建一个函数,该函数执行一个 ajax 请求,该请求收集配置参数以加载其余资源,但我不喜欢它,因为它破坏了 Angular 的操作。
<-- This is working fine, but is not dynamic: -->
npm run build -- --prod --base-href https://myHost.net:8080/path/app/ --configuration=$configuration
<-- And this is working but is not Angular friendly -->
/** assets/data/appConfig.json */
{
"SERVER_HOST": "https://myHost.net:8080",
"SERVER_PATH": "/path/app/"
}
/** index.html */
<script>
(function() {
if (window.onerror) {
loadConfig();
}
function loadConfig() {
var xhttp = new XMLHttpRequest();
var url = 'assets/data/appConfig.json';
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var data = JSON.parse(this.response);
window.appBaseHref = data.SERVER_PATH;
document.getElementById("base").href = data.SERVER_PATH;
}
};
xhttp.open('GET', url);
xhttp.send();
}
})()
</script>
有人告诉我有一个跳转代理的选项,但我找不到方法,我不知道如何配置它。我认为也许可以在 nginx 配置文件中进行某种调整,以便应用程序从提供的 URL 中“读取”,并且应用程序的基本 href 可以始终保持为“/”。
目前我的 nginx.conf 文件是:
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location /documentation {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /documentation/index.html =404;
}
}
位置路径“/”是我的 Angular 应用程序,位置路径“/documentation”是项目文档的保留路径。
欢迎任何形式的帮助。
这几天我一直在尝试几件事,但事实是我对如何继续感到很困惑,因为似乎没有任何效果。
我已经将 Nginx 配置为添加 env $uri+$basepath 属性,但我意识到关系正好相反。我需要我的 index.html 来向代理路由而不是路径“/”发出请求,因为因此,请求甚至不会进入日志(代理不会重定向我,因为它没有我的前缀应用程序)
我给你举个例子: 我的应用托管在:myHost:8080/myapp/front 当我输入这个 url(myHost:8080/myapp/front) 时,应用程序会加载索引,但相关的资源(样式、运行时、polyfills、脚本和 main)没有加载,因为它们将请求发送到:myHost:8080/ {resourcePath} 而不是 myHost:8080/myapp/front/{resourcePath}
此时我不知道该去哪里。我将能够得到我想要放置标志 --base-href /myapp/front 的结果,但我希望这条路线是动态的,并且取决于我的 VIRTUAL_HOST 系统的环境变量,当然我不知道在构建应用程序时
接下来我粘贴我的 dockerfile 和 nginx 配置文件。
Dockerfile(注释行是没有按预期方式工作的提案)。
### STAGE 0: Based on Node.js, to build and compile Angular ###
FROM node:alpine as node
# Create app directory
WORKDIR /app
# Copy the dependencies to install once and let Docker use the cache for the next builds
COPY package*.json /app/
# Install all dependencies
RUN npm install
# Copy all the project into the image
COPY ./ /app/
# Argument to build the image according to the environment
ARG configuration=production
# Compiles our project
RUN npm run build -- --prod --configuration=$configuration
### STAGE 1: Based on Nginx, to have only the compiled app, ready for production with Nginx ###
FROM nginx:1.13.3-alpine
## 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=node /app/dist/dsa-frontend /usr/share/nginx/html
# Add directive
# COPY nginx-custom.conf.template /etc/nginx/conf.d/default.conf.template
COPY nginx-custom.conf /etc/nginx/conf.d/default.conf
# CMD /bin/bash -c "envsubst '\$VIRTUAL_SERVICE_LOCATION' < nginx-custom.conf > /etc/nginx/conf.d/default.conf"
CMD ["nginx", "-g", "daemon off;"]
nginx-custom.conf
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /myapp/front$uri /myapp/front$uri/;
# try_files $uri $uri/ $uri$VIRTUAL_SERVICE_LOCATION $uri$VIRTUAL_SERVICE_LOCATION/ /index.html;
}
location /documentation {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /documentation/index.html =404;
}
}
但这些似乎都不起作用。
最后,我们决定从代理中删除开发并打开一个新端口来部署此应用程序,因此根路径现在是“/”。
现在一切正常。
【问题讨论】:
-
你不能在 nginx conf 中处理它吗?请简化问题。
-
我刚刚编辑了这个问题。谢谢你的建议。
-
正如你所指出的。您可以通过环境变量动态提供应用程序的上下文根,并将其设置为 nginx env $uri+$basepath,其中 $basepath 将根据部署进行填充。
-
另外别忘了,部署镜像时可以传递 nginx 环境变量。
-
使用 confd 模板配合 nginx 配置。 confd
标签: angular docker nginx deployment