NGINX setup for separate Vue Frontend and Express Backend - node.js

I am wondering about the proper nginx setup when deploying a vue frontend separately from an express backend - not separately in terms of servers or domains, but in terms of how they are served.
During development, I use npm serve in the vue directory, and to build a production build, it is generated via npm run build. The resulting dist folder should be served, and my question is how this is done when the backend is on the same server.
Let's say for the backend, express is exposing routes. Should nginx be in front of express here?
The vue front end is calling those routes, but the static files need to be served. According to the docs this can be done using serve. Is this intended for production? And then again, should nginx be in front of this?
I am wondering, because the route would then be:
Browser Request -> Nginx to Vue Frontend -> Vue Frontend -> Nginx to
Backend
Is this a suitable approach or am I misunderstanding this?

Should nginx be in front of express here?
Yes, it is a very good idea.
You have to use a distinct set of URLs for Vue and Express, so Nginx, while looking at request URL, will be able to understand what to do: give a Vue file or proxy to Express. Nginx has a variety of options how to classify incoming requests: by different hostnames, by paths, by combination of both, etc.
For example, prepend all your Express routes with /api/ path prefix. Then configure nginx like this:
This is not production ready configuration, I'm just trying to give a hint what you should look for in nginx docs
server {
listen 80;
server_name mydomainname.com;
location /api {
proxy_pass http://localhost:8000; # port that Express serves,
# better change to UNIX domain socket
}
location / {
root /vue_root/dist;
}
}

Related

Deploying dynamic Nextjs + Nodejs application inside docker using caddy server

I am currently developing a simple portfolio app and my app structure is like this.
Nextjs/client,
Nodejs/server,
Mongodb/db
Nextjs is hosted locally on port 3001, Nodejs app on 5000. Whenever nextjs needs to fetch any api it calls nodejs application. All the things are configured inside docker. I am very new to deploying nextjs application and have recently used caddy server which has automatic https.
I am able to deploy the nextjs application statically using commands
next build
next export
The statically exported file called index.html inside out directory of nextjs application is pointed to caddy server on port 80 and 443. Statically exported app doesn't support api routes which I recently came to know. I tried next build and next start command to generate a dynamic production build inside .next directory. The main problem is How do I point my dynamically generated nextjs application in caddy configuration inside docker container. My present caddy configuration looks like
www.example.com:443 {
tls xyz#email.com
root * /srv
route {
reverse_proxy /api* api-server:5000
try_files {path} {path}/ /index.html
file_server
}
}
I am looking for hints especially related to proxy server.
Thank you in advance
I'm assuming the api url in your frontend looks like this http://localhost:5000 (based on your youtube comment here) which won't work if you're accessing your dockerized app from a remote computer (in this case your computer, since I'm assuming your app is hosted). Try changing it to https://www.example.com:5000 and rebuild your image.

Nginx reverse proxy to nodeJS. How does Vuejs fit in?

Thanks for helping out!
I'm setting up an API server that will also function as a web-app server. (Debian 10)
I currently have nginx as a reverse proxy to my nodeJS app.
I'm thinking of using VueJS to develop my frontend single page app but I can't figure out how to tie it all together.
Should I :
use a reverse proxy to nodeJS and have my API live there
AND
use nginx to serve my vueJS web app, without the nodeJS overhead
This seems logical but I'm a bit confused, since I've never done it before.
Thanks again for helping!
Regards,
Renato
I have a website running with nodejs and vuejs which is hosted on digital ocean with nginx reserve proxy. I'm using pm2 to call nodejs apis and it works perfectly fine. As far as Vue.js is concerned, you can run build and deploy the dist folder anywhere on the internet.
Just add the following code to run front-end with nginx:
server {
root /path to your dist vuejs folder;
index index.html index.htm index.nginx-debian.html;
server_name domain.com;
location / {
try_files $uri $uri/ =404;
}
}

Not Sure How to Start and Deploy ReactJS App on Production Server with ExpressJS

Locally, I use ExpressJS on port 3001 and then start my react app with npm start which runs the development server on port 3000. This allows me to route requests as a proxy from 3000 to 3001.
For production, I installed Ubuntu NodeJS 6.12.13 on 16.04 on a DigitalOcean Droplet and then installed Nginx and PM2.
In my Nginx default file I have set the following:
location / {
proxy_pass http://localhost:3001;
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;
}
I've moved over my Express and React setup and added the Express server to the PM2 startup. Nginx is being used as a reverse proxy server to use Express on port 3001. Here is the PM2 startup (www is the name of the server file which runs Express).
When I load my domain, I receive the Express default page:
Now I'm not sure how to start the react app, because it doesn't seem logical to start it using npm start and keep the terminal open for a production server. I need to see my React app when I visit the domain instead of the Express message.
I've found articles which mention to use npm run build but they don't explain how to then run the React app. Sorry I'm new to this, but any help would be appreciated. Thank you.
You won't run the React app because there is no such a thing :) After building your app all your files bundled in a single Javascript file. You are using start for your React app in development for development purposes.
After doing:
npm run build
you will have a build directory in your app directory. Just copy all the files and directories from this build directory to your server where your Nginx's default directory points.
If you don't want to open your regular app codes in developer tools of browsers, delete build/static/js/some_file.js.map and build/static/css/some_file.css.map before uploading your files to server. Those are source map files which are for debugging purposes. If you include them, in developer tools everyone can see you files directly. Your code actually open to world, to anybody right now but with a bundled, uglified and minified way. If you include source map files, they will be opened as they are.
This is how you run a static app. Without a backend, means here without Express, just using a web server.
But, since your question involves Express I assume you are using a backend server. So, one method is copying all your project to your server again with all backend and frontend code as you are using in development. Build your React app. But this time instead of starting both an Express server and React development server, on your server you will only run Express. Express will be the one serving your frontend. You should have already configured this in your development and done some production tests.
So, if you don't use a backend server you don't need Express or any other thing apart from a single web server. If you use a backend server then you need something like Express to serve both your backend requests (like to API's) and your React app. In addition you will need something like PM2 to run Express and optionally Express to use proxies for different apps.

How to run Node Express server and Angular on the same port?

I am new to Node and Angular. I need to know whether is it possible to run a Node Express app serving as a backend and an Angular frontend on the same port. I followed Angular Quickstart tips on angular.io and created a Node todo application but both are running on different port which raises the issue of Cross Origin Request Blocked Issue.
To have Node.js serve the Angular app on the same port, your Angular app must be deployed under your Node's directory where the static resources are deployed. But in dev mode, it's more productive to serve your Angular bundles (so they auto-rebuild in memory as you code) from the dev server, e.g. on port 4200, while the Node server runs on another port, e.g. 8080.
To avoid cross-origin issues, you need to configure a simple proxy file in your Angular app to redirect all data requests to your Node server. For example, create a file proxy-conf.json in the root dir of your Angular project:
{
"/api": {
"target": "http://localhost:8080",
"secure": false
}
}
This will redirect all requests that have /api in the URL to your Node server, assuming that it runs on port 8080. Then start your Angular app using the following command:
ng serve --proxy-config proxy-conf.json
An HTTP request in your Angular App can look like this:
http.get('/api/products');
Of course, you need to configure the /api/products endpoint for GET requests on your Node server.
To get Angular and Express running on the same port I've always served my Angular build files by the Express app itself. You should be able to tell Express to serve static content from an Angular build directory like this:
app.use(express.static('../accounting-client/dist'));
Which would work if you had a file structure like so and were running serve.js with Node:
-accounting-server
-serve.js
-accounting-client
-dist/*
You can customize as needed by configuring the Angular build folder to be wherever you need it, or use Grunt/Gulp to move files around to the folders you prefer with a build task.
As mentioned by Yakov this isn't ideal for development since it won't work with the Angular dev server's auto-refresh.
The fact that you need to have access to your client-side project from within Express project, as spacefozzy said, is true. but you still can keep your projects separated.
To do so, you can create a symlink from your client-side project directory in your Express project directory:
// while in Express directory
ln -s ~/path/tp/client-side/build name-in-espress-dir
This way you can maintain projects isolated.

Nginx + node.js configuration

I need the right configuration of nginx for my problem.
Suppose the nginx + nodejs serverprograms are running on the same debian machine.
Domain name for my website is for simplicity just webserver.com (and www.webserver.com as alias)
Now, when someone surfs on the internet to "webserver.com/" it should pass the request to the nodejs application which should run on a specific port like 3000 for example. But the images and css files should get served by nginx as static files and the filestructure should looke like webserver.com/images or webserver.com/css .. images + css should get served by nginx like a static server
Now it gets tricky:
But when someone surfs on webserver.com/staticsite001 or webserver.com/staticsite002 then it should get served by the nginx server only. no need for nodejs then.
And for the nodejs server, I am just setting up my nodejs application with port 3000 for example to receive the bypass from nginx for webserver.com/
to put it in a more understandable language: when someone surfs to webserver.com/staticsite001 it should NOT pass it to the node application. It should only pass it to the node application if its inside of the first webserver.com/ directory that the outsiders can see. The webserver.com/staticsite001 should only get serverd by nginx.
How, how do I do that ? And what should the http and server block look like for the nginx configuration look like?
I am familiar with nodejs. But I am new to nginx and new to reverse proxying.
thanks
the file structure on the debian hard drive looks like:
/home/wwwexample/staticsite001 (for www.webserver.com/staticsite001/) only handled by nginx
/home/wwwexample/staticsite002 (for www.webserver.com/staticiste002/) only handlex by nginx
/home/wwwexample/images
/home/wwwexample/css
and in
/home/nodeapplication is my node js application
This server block should work:
server {
listen 80;
server_name webserver.com www.webserver.com;
root /home/wwwexample;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
}
location /staticsite001 {
}
location /staticsite002 {
}
location /images {
}
location /css {
}
}
First location makes nginx to proxy everything to localhost:3000. Following empty locations instruct nginx to use default behavior, that is to serve static files.
Put this code into file /etc/nginx/sites-available/my-server and create a symlink to it in /etc/nginx/sites-enabled. There is a default config, which you could use as a reference.
After that you could use command sudo /usr/sbin/nginx -t to check configuration. If everything is OK use /etc/init.d/nginx reload to apply new configuration.

Resources