I'm new to this stuff and I have a few questions I couldn't answer through Google.
If I get it right - nginx is my webserver - a request to my server is done and nginx serves my client (Angular) but can I also use my Express app to serve it with res.sendFile()
?
And if I setup nginx with a reverse proxy it works as an instance between my client and backend? So they don't communicate directly with eachother but through nginx and to do so I have to proxy_pass
my Express app?
My nginx sites-available config:
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name blank-agency.org www.blank-agency.org;
return 301 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl on;
ssl_certificate /etc/letsencrypt/live/blank-agency.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blank-agency.org/privkey.pem;
server_name blank-agency.org www.blank-agency.org;
root /var/www/webserver/public/website;
location ~ /.well-known {
allow all;
}
location / {
proxy_pass https://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;
}
As you can see my directory structure is:
/var/www/webserver --> here is my express app.js
/var/www/webserver/public/website --> here are my angular dist files
If I use nginx as a reverse proxy my client is not served anymore (bad gateway 502
) so I suppose I have to serve it via my Express app now?
So now my app.js
:
// require section
var express = require('express'),
mysql = require('mysql'),
bodyParser = require('body-parser'),
cors = require('cors'),
path = require('path'),
app = express();
// middlewares bodyParser + cors
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
var connection = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'whatever',
database: 'whateverDB'
});
connection.connect();
app.use( express.static(__dirname + '/public/website'));
app.get('/', function(req, res){
res.sendFile(path.join(__dirname + '/public/website/index.html'));
});
app.route('/customers').get((req, res) => {
connection.query('SELECT * FROM customers', function (err, rows) {
const results = JSON.stringify(rows);
console.log(req.param("term"));
res.send(results);
})
})
// app listen port
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
Again everything seem to work fine...but why can I access my app through http://blank-agency.org:3000
? First of all HTTP requests should be redirected to HTTPS? Same for https://blank-agency/customers --> my data exposed on an URL seems like an security issue haha
I get that it is served on port 3000
cause I sent it through my Express app which listens on port 3000 but how else should it be served? Because nginx with reverse proxy setting gives 502
error like mentioned and i already opened the ports 80 & 443
on my Firewall through iptables
on linux.
netstat -tlpn
show nginx on ports 80 and 443
systemctl status nginx
and
nginx -t
says all fine.
I suppose I have a deep misunderstanding of the concepts used here or something else isn't right. Let me know if you need more information.
Thanks in advance :)
For the first part:
This will prevent access to
http://blank-agency.org:3000
, because nownode
withexpressjs
won't listen on all addresses, but onlylocalhost
. (assuming that both nginx and node/expressjs run on same server).For the second part:
This will reverse proxy only
https://blank-agency.org/customers
tonode/expressjs
. In order to reduce configuration burden, better to collect allexpressjs
URLs under common path like:/api/customers
,/api/products
,/api/auth
etc. This way, you will have to reverse proxy configure only once from/api
.if you require authentication, your
angular
application andnode/expressjs
should implement that, then you will have more paths for reverse proxy, likelocation /api/auth { ... }
etc. But that part is application specific,nginx
will just handover HTTP requests tonode/expressjs
, and responses to client. Fromnginx
perspective it should be transparent.For future reference, you can absolutely serve files through both Nginx and express-static.
I have this in my server.js, which serves all files within
./public/
when run locally without Nginx.Then in Nginx configuration I have this to serve the same directory. In a production environment, it will be fully handled by Nginx and never hit the Express app for
/assets
.My proxy-pass is a little more complicated due to Prerender.io configuration but you'll want something along these lines. This will send anything except
/assets/
to your Express server.