Обратный прокси-сервер nginx для угловых приложений, работающих на nginx - PullRequest
1 голос
/ 30 апреля 2019

У меня есть докер-контейнер для углового приложения, работающего на nginx, с именем "website".Я хочу получить доступ к этому контейнеру из другого контейнера обратного прокси nginx с именем «test.nginx».Но я не знаю, как настроить nginx.conf для обратного прокси.

Во-первых, я создаю образ докера для углового приложения.Dockerfile:

FROM nginx:alpine
COPY default.conf /etc/nginx/conf.d/default.conf
COPY angular /usr/share/nginx/html

Здесь угловая папка включает файл угловой сборки (index.html, main.js, runtime.js ...)

default.conf:

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

docker-compose.yml

version: '3.4'

services:

  nginx:
    image: nginx:latest
    container_name: test.nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 2020:80
    environment:
      - NETWORK_ACCESS=internal

  website:
    image: website
    container_name: website
    restart: on-failure       
    ports:
      - 2121:80

и контейнер test.nginx используют этот nginx.conf

worker_processes 1;
events { worker_connections 1024; }

http {
    server {
        location /client/ {
            proxy_pass         http://website/;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }    
    }

}

Когда я пытаюсь добраться до углового приложения с помощью http://localhost:2121все отлично работает.но если я попробую это http://localhost:2020/client/, я получу эти ошибки

website    | 192.168.208.2 - - [30/Apr/2019:15:11:18 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36" "192.168.208.1"
test.nginx | 192.168.208.1 - - [30/Apr/2019:15:11:18 +0000] "GET /client/ HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
test.nginx | 2019/04/30 15:11:18 [error] 6#6: *5 open() "/etc/nginx/html/runtime.js" failed (2: No such file or directory), client: 192.168.208.1, server: , request: "GET /runtime.js HTTP/1.1", host: "localhost:2020", referrer: "http://localhost:2020/client/"
test.nginx | 192.168.208.1 - - [30/Apr/2019:15:11:18 +0000] "GET /runtime.js HTTP/1.1" 404 556 "http://localhost:2020/client/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
test.nginx | 2019/04/30 15:11:18 [error] 6#6: *3 open() "/etc/nginx/html/polyfills.js" failed (2: No such file or directory), client: 192.168.208.1, server: , request: "GET /polyfills.js HTTP/1.1", host: "localhost:2020", referrer: "http://localhost:2020/client/"
test.nginx | 192.168.208.1 - - [30/Apr/2019:15:11:18 +0000] "GET /polyfills.js HTTP/1.1" 404 556 "http://localhost:2020/client/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
test.nginx | 2019/04/30 15:11:18 [error] 6#6: *4 open() "/etc/nginx/html/styles.js" failed (2: No such file or directory), client: 192.168.208.1, server: , request: "GET /styles.js HTTP/1.1", host: "localhost:2020", referrer: "http://localhost:2020/client/"
test.nginx | 192.168.208.1 - - [30/Apr/2019:15:11:18 +0000] "GET /styles.js HTTP/1.1" 404 556 "http://localhost:2020/client/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
test.nginx | 2019/04/30 15:11:18 [error] 6#6: *1 open() "/etc/nginx/html/vendor.js" failed (2: No such file or directory), client: 192.168.208.1, server: , request: "GET /vendor.js HTTP/1.1", host: "localhost:2020", referrer: "http://localhost:2020/client/"
test.nginx | 192.168.208.1 - - [30/Apr/2019:15:11:18 +0000] "GET /vendor.js HTTP/1.1" 404 556 "http://localhost:2020/client/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
test.nginx | 192.168.208.1 - - [30/Apr/2019:15:11:18 +0000] "GET /main.js HTTP/1.1" 404 556 "http://localhost:2020/client/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
test.nginx | 2019/04/30 15:11:18 [error] 6#6: *6 open() "/etc/nginx/html/main.js" failed (2: No such file or directory), client: 192.168.208.1, server: , request: "GET /main.js HTTP/1.1", host: "localhost:2020", referrer: "http://localhost:2020/client/"

Когда я использую только файл index.html вместо файлов угловой сборки, я могу получить доступ к файлу index.html из обоих http://localhost:2020/client/ и http://localhost:2121

Пожалуйста, кто-нибудь может мне помочь?Спасибо:)

*** Редактировать:

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

1 Ответ

1 голос
/ 01 мая 2019

Вы не можете просто сделать обратный прокси, используя только NGINX и Angular.

Нам нужно было добавить haproxy (http://www.haproxy.org/) как отдельный сервис и настроить его так, чтобы он смотрел на сервер nginx.

Этот образ докера может быть хорошим началом (https://hub.docker.com/_/haproxy)

Для нашей конфигурации nginx это выглядит примерно так:

        # Api Endpoint
        location /api/{
        proxy_pass https://api.company.com:1234/;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        }

Затем в нашем прокси-сервере высокой доступности (с использованием HTTPS). Я добавил комментарий, чтобы помочь вам в этом.

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private


    server=haproxy
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
    ssl-default-bind-options no-sslv3

frontend server1  #Where the user is coming from (anywhere) 
        mode http
        bind 0.0.0.0:443 ssl crt /etc/ssl/certificate.pem

        acl api url_reg ^\/API/.*  # Check the contents of the URL from the user's browser

        use_backend api_server if api  # If the ACL above is true:
                                       # Use the api_server desription below


backend api_server # Define the api_server
        mode http  
        server appsrv-1 10.1.1.3:443/API/ check ssl verify none
                             # appsrv-1 is just a title of the server.
                             # Use the IP to where the Backend is
                             # specify the port and the location.  In your case
                             # you would use /client/

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http

Затем, когда вы закончили настройку прокси-сервера HA и указали на свой сервер nginx, убедитесь, что ваш пользователь сначала заходит на haproxy либо с его IP-адресом полного доменного имени. HA Proxy будет обрабатывать вас как обратный прокси.

Что касается вашего вопроса о SPA, я понимаю, что внутри конфигурации NGINX вы добавляете:

proxy_pass http://api.company.com:1234/; # Where the proxy is
proxy_intercept_errors on;               # IF there is a problem
error_page 404 = /index.html;              # Serve the index.html as the 404 page
...