6

I have a docker container for angular app working on nginx named "website" . I want to reach this container from other nginx reverse-proxy container named "test.nginx". But i don't know how configure nginx.conf for reverse-proxy.

Firstly i am creating docker image for angular app. Dockerfile:

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

Here angular folder include angular build file(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

and test.nginx container use this 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;
        }    
    }

}

When i try to reach angular app with http://localhost:2121 everyhing work great. but if i try this http://localhost:2020/client/ i get these errors

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/"

When i am using just a index.html file instead of angular build files, i can reach index.html file from both http://localhost:2020/client/ and http://localhost:2121

Please can some one help me? Thanks :)

***Edit:

I think i am getting this error because angular is a single page application. Now the question is how can i configure location and proxy_pass for a spa?

1 Answer 1

1

You can't just do a reverse proxy with just NGINX and Angular.

What we've had to do was add haproxy (http://www.haproxy.org/) as a separate service and configure it so that it would look at the nginx server.

This docker image might be a good start(https://hub.docker.com/_/haproxy)

For our nginx configuration, it looks similar to:

        # 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;
        }

Then, in our HA Proxy (using HTTPS). I added some comment to help guide you through this.

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

Then, when you finished having HA proxy configured and pointing to your nginx server, make sure that your user goes to the haproxy first either with it's IP address of FQDN. HA Proxy will then handle being the reverse proxy for you.

Regarding your question on the SPA, my understanding is that inside of the NGINX configuration you add:

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
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot. Do you have any idea about how can i configure location and proxy_pass for a spa?
@ErtuğrulGAMGAM, I updated my answer to include your SPA question at the bottom. I personally have not done this, but I hope it helps.
@mthola: "You can't just do a reverse proxy with just NGINX and Angular.", sorry, why is that? There should be a reason for this, but I cannot getting it from you subsequent answer...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.