2

I am running my application in a Digitalocean droplet using nginx i have found out that if i run my app with http it works perfectly, but when i run it with https nginx gives me 502 BAD GATEWAY, i have tried other digitalocean guides and searched around stackoverflow and never found the solution so i thought about making this post.

NGINX DEFAULT FILE:

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;

        server_name mydomain.io www.mydomain.io;

        ssl_certificate /home/myapp/ssl/myapp.crt;
        ssl_certificate_key /home/myapp/ssl/myapp.key;

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

MY APP CODE:

const express = require("express");
//const http = require('http');
const https = require('https');
const helmet = require("helmet");
const cors = require("cors");
const fs = require("fs");
const path = require("path");
const app = express();
const config = require("./config");
const passport = require("passport");
const credentials = { key: fs.readFileSync('ssl/myapp.key', 'utf-8'), cert: fs.readFileSync('ssl/myapp.crt', 'utf-8'), ca: fs.readFileSync('ssl/myapp.ca-bundle', 'utf-8') };

app.use(helmet());
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(
  require("express-session")({
    secret: require("./config.json").app.secretKey,
    resave: false,
    saveUninitialized: true,
    cookie: {
      secure: false,
      maxAge: 60 * 60 * 1000 * 24 * 365,
    },
  })
);

app.use(passport.initialize());
app.use(passport.session());
passport.use(require("./service/passport"));

app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "views"));
app.use(express.static(path.join(__dirname, "views")));

app.use('/', require('./api/home'));
app.use("/auth", require("./api/auth"));
app.use("/user", require("./api/user"));

app.get('/tos',(req,res)=>{
  res.render('tos');
});


//var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);

httpsServer.listen(config.app.port,'localhost',()=>{
        console.log("App started on port:"+config.app.port);
});

I am new to nginx can someone explain how to do this?

DRE
  • 263
  • 8
  • 35
  • 1
    this might answer your question:[https://stackoverflow.com/a/2665814/10239185] – Besufkad Menji Sep 22 '20 at 13:29
  • I have read the question you have suggested me and can say that at the moment i have changed the port to 80 and i am using ufw but i already have allowed the port 80 to be used with 'sudo ufw allow 80' and still it is giving me this problem. – DRE Sep 22 '20 at 13:44
  • what is your server, you need to configure reverse proxy if you want to access your 8001 outside your system on the web – Besufkad Menji Sep 22 '20 at 13:49
  • my server is an ubuntu droplet, do you suggest using nginx or what? – DRE Sep 22 '20 at 14:07
  • 1
    I usually use nginx for node api, it's recommended in mot cases. here their own article how to deploy node API:[https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-16-04] – Besufkad Menji Sep 22 '20 at 14:12
  • The link is not correct it gives me 404 not found – DRE Sep 22 '20 at 14:29
  • 1
    [ https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-16-04 ], try this – Besufkad Menji Sep 22 '20 at 14:31
  • So i have tried with nginx and it is now giving me Error 502 Bad Gateway went back using port 8001 and opened nginx with ufw any ideas? – DRE Sep 22 '20 at 14:48
  • nginx gives this error if your node server is not running – Besufkad Menji Sep 22 '20 at 14:50
  • It is running with pm2 start – DRE Sep 22 '20 at 14:51
  • If I recall correctly, 502 in your case could indicate that there is an issue with your certificate. I guess, you could test the app certificate for example by opening 3000 port to outside and opening it in browser. – glock18 Sep 25 '20 at 11:55
  • Also, is there any reason to run your node.js as an https server given that it's on the same physical machine as your nginx reverse proxy? – glock18 Sep 25 '20 at 11:57
  • Appearently it only needed a couple of minutes to start working, the certificate and the key are correct and i only had to use http in the nodejs app not https, i leave the question still cause it may help people in the future with the same problem, i will post the answer in a couple of minutes. – DRE Sep 25 '20 at 15:58
  • I ran into the same problem but didn't get the right solution. So, I went with Cloudflare to connect my server on Digital Ocean with my Domain on another registrar. Cloudflare does this (SSL certification) automatically. Do let me know if you want guidance in thhe same. – kartik tyagi Sep 29 '20 at 06:42
  • please provide the output of `sudo netstat -nlpt` and `sudo iptables-save`. So we can understand which ports are listening and what are your firewall rules – ofirule Sep 29 '20 at 10:27
  • I already found the solution a week ago but forgot to post the answer, my bad sorry! – DRE Sep 30 '20 at 08:50
  • @AndreaDattero if you find the solution I posted to be the one you want, can you mark that as accepted? I was looking for the bounty which is going to expire soon. If you want any help with the solution, do let me know. – architjn Sep 30 '20 at 15:07

3 Answers3

3

Your App Code is running using HTTPS, while NGINX is proxy_pass is using http://localhost:3000.

To fix the issue there are two ways:

  1. Update the proxy_pass with the https://localhost:3000 and restart NGINX
  2. Use HTTP instead of HTTPS at the APP level and restart the application

Any option will fix the issue, least effort would be using option one.

Bharath
  • 390
  • 1
  • 6
  • I recommend using the second one though, cause in my case the first one didn't work i remember. – DRE Oct 10 '20 at 14:09
2

I have multiple servers running node.js applications on 80 as well as 443 perfectly fine.

I will prefer you to use the configuration I use-

server {
    server_name yourdomain.com;
    proxy_buffering off;
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.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
}

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

    listen 0.0.0.0:80;
    server_name yourdomain.com;
    return 404; # managed by Certbot
}

I mainly use Certbot for my SSL certificates you can use anything else you want!

architjn
  • 1,397
  • 2
  • 13
  • 30
1

You no need to change anything in the application and continue using HTTP, Nginx will serve https requests and redirect HTTP to your application.

vitalyster
  • 4,980
  • 3
  • 19
  • 27