Hi! First time user of DigitalOcean, and really beginner at setting up all this server stuff. So I have a NextJS front deployed with Vercel, and it communicates with an Node.JS Express backend REST API that I have created. I’m trying to host the express server on my droplet, and I went ahead and used the NodeJS 1 Click Droplet to set up nginx and pm2. I believe those parts are working. However, I’m having issues with setting the server with HTTPS. I have bought a custom domain, set up all the necessary DNS stuff in digital ocean networking tab and in namecheap(where I got the domain). To set up certbot with my domain I used this guide from digitalocean: https://www.digitalocean.com/community/tutorials/how-to-use-certbot-standalone-mode-to-retrieve-let-s-encrypt-ssl-certificates-on-ubuntu-22-04.
I believe it is an issue with my nodejs / nginx setup, but I’m not sure what is going on, and I’m not sure if I’m missing something. Here is where I setup the express server in nodejs:
_if_ (process.env.NODE_ENV === "production") {
const privateKey = fs.readFileSync('/etc/letsencrypt/live/domain/privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/letsencrypt/live/domain/cert.pem', 'utf8');
const ca = fs.readFileSync('/etc/letsencrypt/live/domain/chain.pem', 'utf8');
const credentials = {
key: privateKey,
cert: certificate,
ca: ca
};
_// create the HTTPS server on port 443_
var https_server = https.createServer(credentials, app).listen(443, function(err){
console.log("Node.js Express HTTPS Server Listening on Port 443");
});
_// HTTP server on port 80 and redirect to HTTPS_
var http_server = http.createServer(function(req,res){
_// 301 redirect (reclassifies google listings)_
res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
res.end();
}).listen(80, function(err){
console.log("Node.js Express HTTPS Server Listening on Port 80");
});
_// create a_
} _else_ {
app.listen(process.env.PORT || 3000, () => {
console.log(`Running app backend on Port ${process.env.PORT}`);
})
}
and here is what /etc/nginx/sites-enabled/default
looks like:
# HTTP — redirect all traffic to HTTPS
server {
listen 80;
listen [::]:80 default_server ipv6only=on;
return 301 https://$host$request_uri;
}
# HTTPS — proxy all requests to the Node app
server {
# Enable HTTP/2
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name domain;
# Use the Let’s Encrypt certificates
ssl_certificate /etc/letsencrypt/live/domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain/privkey.pem;
# Include the SSL configuration from cipherli.st
include snippets/ssl-params.conf;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
when I run the app in NODE_ENV=development it actually works fine (going to www.domain.com works and returns the right thing), however trying to run it production i get a 502 bad gateway, any ideas what I might be doing wrong in my setup?
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!
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.
Hi there,
There is no need to run your Node.js app on port 443 as you can have only 1 service listening on a specific port. You would get an error saying that the port is already in use.
What you could do is just leave your Node.js app running on the standard port and do the SSL termination via Nginx as you’ve done already.
Let me know how it goes!
Best,
Bobby