My question is more of a query as to how people deploy production web apps now / best methods etc.
Currently, we are looking to put into production a web app with a NodeJS backend using express as well as a frontend we have made.
Does it make sense to split the frontend and backend onto their own separate server, or to render the HTML files directly from the NodeJS backend on one server?
If you have any other suggestions please list the pros/cons and how a dev team of multiple people can easily manage the source code as there are separate people split up to just frontend and just backend.
Note: This is the actual web app, not a static site or landing page
I went through this decision process recently, and I chose to deploy static and dynamic parts of my system together.
How to decide this question?
Are your front- and back- ends tied closely together? Do many front-end changes require corresponding back-end changes? If so, that's a reason to deploy both in a single server. That was my situation.
Does it make any sense to serve your static HTML / Javascript / CSS / image resources using express's static-object server functionality? It might: Express lets you do good things like .js minification, on-the-fly translation of .less or .sass files, and so forth. It also has good facilities for handling CORS, rate-limiting, and other infosec features. If you want those things, that's a reason to deploy both in a single server. That, too, was my situation.
Will you rig up a reverse proxy (nginx) server facing the network? That's a tricky enough configuration task that you probably want to do it once rather than twice. That's a reason to deploy both in a single server. My situation.
Do you have many many static objects to serve? That's a reason to deploy the static objects and the web app separately: Pure apache or nginx is more suitable for serving static stuff than node. I only had a few static objects.
Is there a chance, in your devops, that two separate deployments will make things more complex and less reliable? (Will somebody forget to deploy both static and dynamic?) That's a reason to deploy both in a single server. I did that because I want test, staging, and production deployments to work identically.
Git and other source-control systems are robust enough to allow teams to contribute to a single repo without stomping each others' work.
Related
We have a web app (CRM type) working on Linux (Debian) with Apache, MariaDb and PHP for the backend, and AngularJS (1.x) for the frontend.
Thinking about a redesign, I need advices on a solution I have in mind, but I'm not sure it would be relevant...
A new website (e-commerce) will come along the CRM and use directly or not (API) the same database.
So my first take would be to put the MariaDb on a dedicated VM. It uses much ressource right now, so much more with another app using it.
Then the CRM and website could connect directly in remote (too risky?) or call an API. I guess the second solution would be better and means I could put my backend PHP part (already working as an API for AngularJS) along with the database, on that new VM.
I guess Debian + Nginx would be a good choice to go with them.
I prefere PHP to handle databases 'cause I'm used to it.
On the other hand I would still have AngularJS alone, a deprecated JS framework.
One thing that was hard to work with, about AngularJS/PHP, was that sometimes I needed to format data for Angular from PHP, and vice versa. It wasn't very clear where to put that formating, 'cause the backend was more about the database and not the frontend, and the frontend more about layout than PHP ORM ans design.
Furthermore, we'd like to keep the CRM as a SPA (Single Page Application).
My take on that would be to go on a MEAN stack, without de M (MongoDB), starting from scratch, just keeping Debian and installing NodeJS, ExpressJS and Angular or another JS framework (Vue, React...).
A hole JS stack to have the same language and gain speed and performance with many little transactions with the server (assets, calls and promises to retrieve data from database). Also to learn more on JS and NodeJS particularly.
NodeJS to create the environnement and a web server, in place of Apache.
Angular (or another) to put data into HTML, and have the less treatments possible.
ExpressJS to be that intermediate part I was talking to, the place where formating can be performed: retrieving data from the views, formating them, sending them to the API, handling the response, formating it if necessary and returning it to the view.
It means I would go from one VM with:
AngularJS (frontend) -> PHP framework (backend) -> Database
To two VM with:
Angular (app frontend) -> Express (app backend) -> PHP API (database backend) -> Database.
What do you think of my use-case and the solution?
There are several benefits to splitting up your services, but almost equally many different solutions, so you need to ask yourself what your goal is. Performance? High availability/failover? You might need a lot of VMs, geo-redundancy, load-balanced VIPs, etc.
You can also look into making containerized services with Docker.
You talk about moving the database onto a separate VM, but that it might be risky. Why? If they are both on an isolated network, it should not be an issue.
If you're looking for stack advice, since you're talking about a full remake, I would recommend something both stable and modern like Laravel + VueJS for the web/API part. You're already comfortable with PHP, and a setup with Nginx will probably be much faster. But of course, there are almost infinite combinations to choose from these days.
As for the "direct or not" DB access: Having a versioned API is always a benefit.
Serving the SPA frontend will require very few resources, so your bottleneck will be between the API backend and DB. You can make it scalable by putting the API behind a VIP and load balance with something like HAProxy/Nginx.
I am working on a learning project. I have build an authentication system in nodejs using local and Google strategy. Front end is a react app. There are two options for hosting
Deploy front end on static hosting providers like netlify or github pages and backend node app to heroku.
Deploy both backend and front end on heroku with front end code in the public folder and use express.static('public')
I am confused about both these approaches and could not find the answer on the internet. It will be a lot of help if you can explain the pros and cons of both the method and which one is suitable in what conditions. Links to the articles are also appreciated. Thank you in advance.
First approach
Pros:
Static content served from a different server has more optimization potential (using S3/CloudFront edge caching), nginx is blazingly fast for serving static files
Less network traffic on one server (content can be served from multiple points in parallel)
The nodejs application doesn't have to "waste" time serving static files that never change as has more time for actual dynamic content
Cons
Needs more configuration, since it's running on a different origin (dealing with CORS, appropriate security settings)
Premature optimization
More maintenance
Second approach
Pros:
Easier to deploy
Fast enough in most cases
I can give you an example based on the company I work for. We separate back and front on different servers for security and convenience. We block all ip's from making requests to our backend and only release the ip of the front server. We create specific rules for each server separately and if one of the servers stops for any reason, it does not affect the other one.
But this decision depends a lot on the type of application you develop and also the structure you need for your project. But consider the following: security, maintainability, and convenience.
I have seen tons of examples and read tons of articles about nodejs express app deployment. Almost always after implementing all logic (including serving static files) in express, the next step is to forget all the claims about how incredibly fast node.js is and how amazing it is in all benchmarks for concurrent requests. After you no longer remember the reasons why you learnt this amazing new technology which changes the world and how we think of web applications, there you go and install good old nginx to act as an entry gate to your express app.
Don't get me wrong, I understand all the features of nginx, having deployed tons of PHP apps with nginx in my days. But simply put, why? Why not let my app be balanced by pm2 e.g., run it on all cores of my VPS and have node.js native clustering support handle the load balancing?
Obviously, I am talking about the case of using a single machine for the app, not deploying it to multiple VPSs. Then a load balancer of some sort again does make some sense.
Thank you anybody who can explain the reasons for using a web server to forward traffic to another webserver.
You can use nginx server to serve static content of your application instead of nodejs.
As nginx is better at serving static content like html, css, js & image files than nodejs.
And another thing is in case of crashing of any node service, you can show proper error pages using nginx.
I'm new to Node JS development. As an ASP.NET MVC developer, I normally use Repository Design Pattern where I have separate projects for Front-End and Database access in one solution. In addition, when creating a REST api, this can be added to the existing solution. So when publish, it api and front-end is separated by a different route.
I've just created a REST Service in Node JS and it's really simple and I like it. However, when it comes to Front-end I was looking at ReactJS, I've seen a blog (unfortunately, I can't find the link) where it separates the process between the REST service and react front end. I'm just wondering if this is a common design pattern in nodeJS using ReactJS. And if there's a benefit on doing this. Specially nowadays, Full Stack developers are a common thing. I can see the benefit of it from a maintenance stand point but I'm just wondering if there's a benefit in terms of server resources i.e. memory, cpu. Should the OS handle 1 vs 2 nodejs process? Will this differ from using linux vs windows?
I see a huge benefit of separating the frontend from the backend so I would propose you to have your Node backend running in its own project and let's say a React solution running on its own. The React client can then consume that API together with other APIs later. By separating you have the benefit of scaling later.
If you've already built the REST service in node, you can access it via proxy in the React project's package.json by adding
"proxy": "http://127.0.0.1:5001/"
It helps manage CORS issues.
I currently manage a cluster of VMs on a number of dedicated hosts to provide apache, nginx and node live and development servers. This of course requires constant and time consuming maintenance to ensure security and reliability. I've found more time is spent looking after this platform then coding new and exciting projects. So I've been looking into the Google App Engine to remove the need of managing any VMs but I'm struggling to work out how to get it to function for me!
Currently I find myself developing mostly in Angular (v4-5) for my frontend and nodejs for backend. My development nginx server powers my angular apps and routing to ng-serve and to a separate vm that runs my node apps. I use PM2 to manage the apps on both servers.
This works great! I can code locally push my changes via an rsync script to the servers, the app restarts and changes updated. More importantly, I can affectively code between the front and backend! When ready I can comfortably switch the code to the live servers with little effort - nice!
This is where I am struggling...
I can't seem to work how I would develop and publish versions of both the front and backend code in one App Engine project.
Is this possible? How would I go about deploying/publishing both aspects?
Would I be better having two projects such as example.com & api.example.com? If so, can I get the two projects to talk to one another when developing?
I have and can create a angular/nodejs app in the App Engine but I can't work the basics of front and backend development in this managed service.
I'd like to use the great features of the App Engine such as versioning, easy scaling and importantly deployment of apps and updates. Also, to move all my websites including some older ones in PHP to the App Engine.
Any help surrounding this would be much appreciated. Thanks!
As #Yandrak3 suggested, a microservices architecture is what you need. But keep in mind that that document relates to the App Engine Standard environment which does not support Node.js as a runtime environment. But keep the microservices architecture in mind when deploying to App Engine Flexible.
On backend and frontend
Frontend and backend are no longer used to describe the presentation layer and the data access layer of an App Engine application. The only reference in the documentation is here. The (VM) instances managing a service of your app which are configured with automatic scaling are considered part of the frontend infrastructure, while the ones configured with manual scaling are considered backend infrastructure.
The reason for this is that automatic scaling is one of App Engine's
great features [...] easy scaling,
automatically presenting your app's frontend in a manner scaled with the number of external requests incoming to your app.
Manual scaling is more suited for backend operations, where you might want to run operations dependant on the state of the memory over time, or other scenarios. You can find some more information on scaling types here. Keep in mind that this latter document is under App Engine Standard documentation and it includes basic scaling, a feature not available in the App Engine Flexible environment.
On services and versioning
In your case, your frontend and backend modules of your application will become two separate services in App Engine Flex. For each service you can deploy multiple versions. More, explained here.
Communication between services, in this case between your frontend and backend, can be done through HTTP requests between them.
If the next question is how HTTP requests from users reach the appropriate version of a service (or a service), check this document.
To deploy multiple services, you will use the same commands and you will separate each deployment and service through their afferent configuration file, app.yaml.
Your question requires a response with a pretty wide (and deep) spectrum of concepts. Hopefully, this answer is good to start with.