Frontend is accessible via Nginx, but backend APIs are not reachable externally

Problem with Accessing Backend APIs from External Network

I have an Nginx server that operates correctly on the local network where it is deployed. However, when I attempt to access it externally using my domain name (rassd.media), the frontend loads normally, but I cannot connect to any backend APIs.

Here is my current Nginx configuration:

user www-data;
worker_processes auto;

error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # Configuration for serving Frontend
    server {
        listen 3000;
        server_name abcc.com www.abcc.com;

        root /home/fe/build;
        index index.html;

        location / {
            try_files $uri /index.html;
        }
    }

    # Configuration for External Domain
    server {
        listen 80;
        server_name rassd.media;

        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, PATCH, DELETE' always;
        add_header 'Access-Control-Allow-Headers' 'DNT, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Range' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range' always;

        root /home/fe/build;
        index index.html;

        location / {
            try_files $uri /index.html;
        }
    }

    server {
        listen 80 default_server;
        server_name rassd.media _;
        root /;

        client_body_timeout 60s;
        client_header_timeout 60s;

        location /search-engine/ {
            rewrite ^/search-engine/(.*)$ /$1 break;
            proxy_pass http://172.30.30.66:8084/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            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-Proto $scheme;
        }

        location /user-service/ {
            rewrite ^/user-service/(.*)$ /$1 break;
            proxy_pass http://172.30.30.56:8191/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            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-Proto $scheme;
        }
    }
}

I attempted to combine both server blocks while keeping the root directory as “/home/fe/build;” but that caused issues. I understand that the frontend and backend configurations may differ and I’m unsure if I am missing something essential. Any advice would be greatly appreciated as I am new to configuring Nginx. Thanks!

hmm, is your frontend hitting the right endpoints externally? when you say “can’t connect to backend APIs” - what’s actually happening? getting 404s, timeouts, or CORS errors? also, have you checked if those internal IPs (172.30.30.66, 172.30.30.56) are reachable from your nginx server when accessed externally vs locally?

You’ve got multiple server blocks fighting over the same domain. Your third block with default_server is grabbing rassd.media requests instead of your second block, but it’s using root / which breaks your frontend. Here’s what you need to do: merge your second and third server blocks into one. Get rid of the duplicate server_name rassd.media entries and put everything under a single server block on port 80. Keep your API proxy locations but change the root back to /home/fe/build. Also, make sure those backend services on your internal IPs are actually running. Test them locally with curl first before assuming Nginx is the problem.

Your frontend server block isn’t handling API routes. The rassd.media block only serves static files - no proxy configs for /search-engine/ or /user-service/. Add those location blocks to the rassd.media server, otherwise it’ll try serving them as static files from your build folder and fail.