Question

Proxy Pass Fails for Port 3000

I have been trying to get my production url to work without adding port number to it e.g. app.domain.com/login does not work (site can’t be reached) while app.domain.com:3000/login works.

Here is my reverse proxy settings in the sites-available folder;

server {

  server_name app.domain.com;



    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/app.domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/app.domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location /login {
        proxy_pass http://localhost:3000/login;
        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;
    }
}
server {
    if ($host = app.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


  listen 80;
  server_name app.domain.com;
    return 404; # managed by Certbot


}

running sudo nginx -t says test is successful so I am wondering what the problem could be.


Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Bobby Iliev
Site Moderator
Site Moderator badge
November 27, 2023
Accepted Answer

Hi there,

The Nginx configuration you’ve provided shows that you’ve set up a reverse proxy specifically for the /login path to pass requests to http://localhost:3000/login. If you want your entire application to be served without specifying the port in the URL, you should set up a more general reverse proxy configuration that handles all paths, not just /login.

You can modify your location block to handle requests to the root of the domain (/) and any other paths accordingly. Here’s an example of how you can adjust your configuration:

server {
    server_name app.domain.com;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/app.domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/app.domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

server {
    if ($host = app.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name app.domain.com;
    return 404; # managed by Certbot
}

With this setup, any requests to app.domain.com will be passed to http://localhost:3000, where your Node.js application is presumably running.

Here are some additional tips to make sure your setup works correctly:

  • Ensure that your Node.js app is configured to listen on the correct port (3000 in this case) and is set up to accept connections from localhost.

  • Verify that any firewall running on your server is configured to allow traffic on port 443 for HTTPS and port 80 for HTTP.

  • After making changes to your Nginx configuration files, always reload Nginx to apply the changes:

    sudo systemctl reload nginx
    
  • If you encounter issues after updating the configuration, check the Nginx error logs for any detailed error messages that could help you troubleshoot the problem:

    sudo tail -f /var/log/nginx/error.log
    
  • Ensure that there are no conflicting server blocks for app.domain.com that could be interfering with your reverse proxy setup.

Let me know how it goes!

Best,

Bobby

KFSys
Site Moderator
Site Moderator badge
November 27, 2023

Heya,

Your Nginx configuration seems to be set up for reverse proxying requests to a Node.js app running on port 3000, but there are a few adjustments needed to ensure it works correctly for all paths, not just /login.

The issue you’re facing, where app.domain.com/login doesn’t work while app.domain.com:3000/login does, suggests that Nginx is not correctly forwarding requests to the Node.js app unless the port is explicitly specified. This is typically a configuration issue.

Here’s how you can adjust your configuration:

1. Modify the Location Block

Instead of proxying only /login, you should proxy all requests to the Node.js application. Replace the specific /login location block with a more general one.

server {
    server_name app.domain.com;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/app.domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/app.domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

In this configuration, any request to app.domain.com (on port 443, which is the standard for HTTPS) will be proxied to localhost:3000.

2. Redirect HTTP to HTTPS

Your second server block is intended to redirect HTTP traffic to HTTPS. It’s mostly correct, but the return 404; line is unnecessary. You can simplify it like this:

server {
    listen 80;
    server_name app.domain.com;

    if ($host = app.domain.com) {
        return 301 https://$host$request_uri;
    }
}

This configuration redirects all HTTP traffic to HTTPS, which is what you generally want for security purposes.

3. Restart Nginx

After making these changes, restart Nginx to apply them:

sudo systemctl restart nginx

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel