Угловое приложение работает на nginx и за дополнительным обратным прокси-сервером nginx

В настоящее время я пытаюсь создать обратный прокси-сервер для двух приложений Angular. Я хочу, чтобы оба приложения были доступны через порт 443 хоста докера с включенным протоколом SSL (например, https://192.168.xx/app1 и https://192.168.xx/app2), чтобы пользователи не имели ввести номера портов для каждого приложения.

Моя настройка заключается в том, что каждая часть приложения запускается в своем собственном контейнере Docker: - Контейнер 1: приложение Angular 1 (порт 80 открыт для хоста на порту 8080) - Контейнер 2: приложение Angular 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.xx/app1 ", приложение работает, но я получаю сообщения об ошибках для всех статических файлов "Uncaught SyntaxError: неожиданный токен <": сообщения об ошибках из chrome

Кажется, что вместо статических файлов js и css возвращается index.html приложения. Я считаю, что это проблема конфигурации nginx самих приложений.

Я потратил довольно много времени, пытаясь понять, как решить эту проблему, но пока не повезло. Я надеюсь, что кто-то здесь может помочь мне с этим.

Ответ 1

Во-первых, я предпочитаю подход один сервис, один контейнер, обеспечивающий перенаправление с nginx. Он также покрывает почти автоматически https с помощью докеризованного обратного прокси-сервера nginx с сертификатами. Вы также можете использовать letsencrypt сертификаты, если хотите. Вы можете развернуть ваши приложения Angular в контейнерах за обратным прокси.

enter image description here

Ниже я опишу шаги для развертывания вашего докера. Я также включаю portainer, который представляет собой графический интерфейс для развертывания вашего контейнера:

  • Запустите nginx в порту 443, предоставив общий доступ к сертификатам, сгенерированным для вашего домена, с помощью опции -v $ HOME/certs: /etc/nginx/certs. Положите сертификаты где-нибудь на хосте, например /etc/nginx/certs. Опция --restart = всегда необходима для автоматического запуска контейнера при перезагрузке сервера:
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 и должны быть перенаправлены на IP-адрес докера (таким образом, nginx может перенаправить поддомен в ваш контейнер).
  • Dockerfile ДОЛЖЕН предоставлять доступ к веб-службе через разные порты (8080 и 8081). Компонент также должен быть развернут на этом порту
  • Самое важное, что контейнеры приложения 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 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, он автоматически перенаправляется в приложение углового контейнера (на которое ссылается appX.yourdomain). Лучше всего то, что jwilder/nginx-proxy автоматически обновляет nginx.conf при запуске разных контейнеров. Наша архитектура микросервисов реализована в Spring (автоматическое развертывание), поэтому я привожу здесь, как вы можете собрать контейнер с помощью angular и nginx, но я думаю, вы уже решили эту проблему. Я также хотел бы использовать docker-compose.

Ответ 2

проблема заключается в том, что контейнеры 8080 и 8081 могут открывать ресурсы, такие как localhost: 8080/styles.css или localhost: 8080/bundle.js. но с текущей конфигурацией они получают запросы localhost: 8080/app1/styles.css. попробуйте добавить rewrite/?app1/(.*)$/$1 break; правило обратного прокси, чтобы они получали правильные запросы