Angular App 在 nginx 上运行并在附加的 nginx 反向代理后面
Posted
技术标签:
【中文标题】Angular App 在 nginx 上运行并在附加的 nginx 反向代理后面【英文标题】:Angular App running on nginx and behind an additional nginx reverse proxy 【发布时间】:2019-02-16 20:25:22 【问题描述】:我目前正在尝试为两个 Angular 应用程序创建反向代理。 我希望这些应用程序都可以通过启用 SSL 的 docker 主机的 443 端口访问(如https://192.168.x.x/app1 和https://192.168.x.x/app2),这样用户就不必为每个应用程序输入端口号。
我的设置是,应用程序的每个部分都在其自己的 Docker 容器中运行: - 容器 1:Angular App 1(端口 80 在端口 8080 上暴露给主机) - 容器 2:Angular App 2(端口 80 在端口 8081 上暴露给主机) - 容器 3:反向代理(443 端口暴露)
Angular 应用程序和反向代理都在 nginx 上运行。应用程序是这样构建的:ng build --prod --base-href /app1/ --deploy-url /app1/
应用的nginx设置是这样的:
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;
index index.html index.htm;
location /
try_files $uri $uri/ /index.html =404;
反向代理的nginx配置是这样的:
server
listen 443;
ssl on;
ssl_certificate /etc/nginx/certs/domaincertificate.cer;
ssl_certificate_key /etc/nginx/certs/domain.key;
location /app1/
proxy_pass http://192.168.x.x:8080;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
location /app2/
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_pass http://192.168.x.x:8081;
如果我尝试在 url 'https://192.168.x.x/app1' 上打开应用程序,则会到达应用程序,但我收到所有静态文件的错误消息 'Uncaught SyntaxError: Unexpected token Errormessages from chrome
似乎返回的是应用程序的 index.html 而不是静态的 js 和 css 文件。我相信这是应用程序本身的 nginx 配置的问题。
我花了很长时间试图弄清楚如何解决这个问题,但还没有运气。我希望这里有人可以帮助我。
【问题讨论】:
我有同样的错误。有什么想法吗? 这不是一个错误,它返回 404 定义为 `try_files $uri $uri/ /index.html =404;` 我正在尝试轻推baseHref
和 deployUrl
angular.json 中的参数,但我尝试的每个排列都会导致意外行为。
类似,baseHref: "/app2/" 和它的排列...有时更改它会重定向到包含路径!!!
您能告诉我们客户端资产调用的 URL 是什么吗?
所以问题是它在另一个角度应用程序 inside 的子目录中,并且 proxy_pass 是 URL 重写,但是应用程序正在“加载”,因此添加了 deployUrl和 baseHref “hack”,因为它不能按预期工作,应用程序可以加载。问题是我必须在所有路由中添加 /basepath/ 前缀,因为不需要的基本 href 与 proxy_pass 更改路径的方式发生冲突。
【参考方案1】:
首先,我更喜欢一种服务,一个容器通过 nginx 提供重定向的方法。它还使用带有证书的dockerized nginx reverse proxy 几乎自动涵盖https。如果需要,您也可以使用letsencrypt certificates。您可以将 Angular 应用程序部署到容器 behind the reverse proxy。
下面我描述了 docker 部署的步骤。我还包括portainer,这是一个用于容器部署的 GUI:
在端口 443 中运行 nginx,使用选项 -v $HOME/certs:/etc/nginx/certs 共享为 your.domain 生成的证书。将证书放在主机上的某个位置,例如 /etc/nginx/certs。需要选项 --restart=always 来在服务器重启时自动运行容器:docker run -d --name nginx-proxy --restart=always -p 443:443 -v /root/certs:/etc/nginx/certs -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
您的应用 1 和 2 应部署在 appX.yourdomain 中,并且必须重定向到 docker IP(这样 nginx 可以将子域重定向到您的容器)。
Dockerfile 必须在不同的端口(8080 和 8081)中公开 Web 服务。该组件也应该部署在该端口上
最重要的是应用程序 1 和 2 容器必须包含选项 -e VIRTUAL_HOST=appX.yourdomain 和 PROXY_ADDRESS_FORWARDING=true:
docker run --name app1 --restart=always -d -e PROXY_ADDRESS_FORWARDING=true -e VIRTUAL_HOST=app1.yourdomain yourcontainer
Portainer 也已启动,为 docker 容器提供仪表板:
docker run --name portainer --restart=always -v ~/portainer:/data -d -e PROXY_ADDRESS_FORWARDING=true -e VIRTUAL_HOST=portainer.yourdomain portainer/portainer -H tcp://yourdockerip:2376
所以基本上当一些请求(子域)到达 nginx 时,它会自动重定向到 angular 容器应用程序(由 appX.yourdomain 引用)。最好的是 jwilder/nginx-proxy 在不同容器启动时会自动更新 nginx.conf。我们的微服务架构是在 Spring(自动部署)中实现的,所以我在这里介绍了如何使用 angular and nginx 构建容器,但我想你已经解决了这个问题。 我也会考虑使用 docker-compose。
【讨论】:
当你谈到 angular 容器时,会变成一个带有 ngnix 的容器或者你怎么能暴露内部 url 的?【参考方案2】:问题是:8080 和 8081 容器可以打开 localhost:8080/styles.css 或 localhost:8080/bundle.js 之类的资源。但在当前配置下,他们会得到 localhost:8080/app1/styles.css 请求。尝试将rewrite /?app1/(.*)$ /$1 break;
规则添加到反向代理,这样他们就会得到正确的请求
【讨论】:
以上是关于Angular App 在 nginx 上运行并在附加的 nginx 反向代理后面的主要内容,如果未能解决你的问题,请参考以下文章
用于在 nginx 上运行的 Angular 应用程序的 nginx 反向代理
如何在同一端口 4200 上运行 angular 4 app 和 nodejs api 用于生产和开发?
带有自定义 --base-href 和 Nginx 路由的 Angular SPA