I have an ExtJS application and some different environments (local machine, development, production-like test environment, and production).
The ExtJS application is backed by a Java backend which is also running on either a local machine, in a development environment, a production-like test environment or a production environment (not the same servers as where the front end application lives though).
For the last two environments, I want to build ONE build of the ExtJS app and first deploy it to the test server, then when ready for release deploy the exact same build to the production server.
Question: Is it possible to somehow use the environment where the frontend is deployed, to decide which backend the ExtJS should connect to? Since the ExtJS front-end is executed on the client's machine, it doesn't know if it should connect to the production backend or the test backend.
What is the best way to solve a problem like this? How (in a clean way) is usually a javascript web application built and deployed to several different environments and communicates with their corresponding backend application?
How (in a clean way) is usually a javascript web application built and
deployed to several different environments and communicates with their
corresponding backend application?
Well, the case is not very usual. Usually the backend app would be (at least seemingly) on the same server that the frontend app is loaded from. Therefore, probably the most hassle free way to accomplish your task is to make the frontend server proxy requests from frontend app to corresponding backend server. This way frontend app will still talk to its origin server which allows you to have just one build for all environments.
The "official" way would be to use the per-environment sections in the app.json file like this:
"production": {
"backend": "backend.domain.tld",
// other stuff
},
"testing": {
"backend": "backend.testing.domain.tld",
// other stuff
},
"development": {
"backend": "backend.dev.domain.tld",
// other stuff
}
The backend value will end up in the build's classic.json (and/or modern.json) file. Frontend app will see the value as Ext.manifest.backend. But this way is effectively creating different builds which you wanted to avoid. Therefore, you could just manually create several versions of classic.json/modern.json files for ONE production build like this:
classic.json.testing
classic.json.staging
classic.json.production
and then use rewriting on the frontend server to respond to "/classic.json" requests with whatever json file matches the server purpose.
Yet another way is to the keep the frontend-backend mapping for ALL environments within the frontend app like this:
var ENV_CONF = {
'frontend.testing.domain.tld': 'backend.testing.domain.tld',
'frontend.staging.domain.tld': 'backend.staging.domain.tld',
'domain.tld': 'backend.domain.tld' // production
};
The app would use location.host as the key and talk to the corresponding backend.
Related
Some application server with an administration interface where I can deploy node.js application, view log files, start/stop/restart/monitor running applications?
Tomcat and Node are completely different beasts, although you can get Node to serve the same purpose as Tomcat if you're agnostic to the programming language you're going to use and you add the right stuff on top of it.
Tomcat is a web server for web applications written in java.
Node is a runtime environment for applications in javascript.
But for monitoring you can you PM2 (https://www.npmjs.com/package/pm2)
PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.
Starting an application in production mode is as easy as:
$ pm2 start app.js
Credits and Read More: How Node.js is different from Tomcat
I'm building SPA with Vue and serve it with nodejs and wrapping it in docker container.
Here is the problem, I'm trying to stick to 12 factor app where for configuration it says keep in env file.
VueJS provides configs for different environment in config folder. But, according to 12 factor app config should not be in files based on environment.
In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as “environments”, but instead are independently managed for each deploy.
So how can I access nodejs environment variables in VueJS app?
EDIT:
Thanks for the answers.
The whole idea is to change for example api url on run time trough providing different env variable. If I commit the config file with api url, I would have to rebuild the container on commit and deploy it just for this small change.
I could also have a api access key that is different in dev and prod.
I'm looking for the best way possible to do this kind of things in SPA.
SPA applications nowadays usually go through a build step. This means compiling all of your files into [near to] one dist file and an index.html which may be served statically. This creates a clear separation between front-end (VueJS) and backend (NodeJS). The index.html and js files themselves continue to be static files nonetheless.
This is usually what you want since you can scale server and client independently: Serve static files, say, through s3 + cdn and run your nodejs server independently.
I think what you want is a way to pass runtime configuration to the client. I wouldn't get too caught up on the details of actually sharing the envvars per se.
In your case, I see two possible solutions:
1) Implement an API to access whitelisted envvars from your server - You can think of this as a /config endpoint
2) Render the index.html dynamically via nodejs with something like ejs with the prepopulated envvars - You'll have more coupling between frontend and server but you could extend this to much more than envvars and, say, preopolute the frontend with prefetched data.
Regardless on how you do it, you can consider this runtime configuration for the frontend which should not be attempted to be fixed at build time since otherwise you may be expose sensitive data into static files and it is not always guaranteed that you have all the data at this time.
The way you access the env variables should be the same no matter which OS you are using. The way you set them is different though. On windows I would set an environment variable like so
set PASSWORD=somepassword
And then in the code I can access this variable by doing the following
var pw = process.env.PASSWORD;
You should be able to use this the same way in VueJS.
EDIT:
If you use docker-compose you can set the endpoint on the fly by using environment variables too. Then whenever you docker-compose up the endpoint will be updated with the current value of your environment variable. In your shell update the api endpoint to whatever you want it to be.
set API_URL=http://my-api-endpoint
Then in the docker-compose.yml you would access this value like so
version: '3'
services:
app:
image: 'myapp'
environment:
- API_URL=${API_URL}
You would still access the variable in your code using process.env.API_URL as I mentioned in my example above.
our devops team will use https://github.com/tinou98/vue-12factor
However it's really a big question mark how VueJs does not consider that as a mature frontend/spa framework.
We used to build React Apps since more than 6 years with a built-in support of externalizing env.js file ( create-react-app )
I think I haven't understood this concept right . If I am using Django as a backend to run server side code , is there a way to include the packages of Node.js also .
Isn't Node.js kind of another environment or language for server side code ?
If I can use Node packages with Django , how to go about it. What does it mean when people say "Node js is a platform and Django is a framework" ?
I would be very greatful if you include some indepth details about these two environments ( new to web development here:))
Can I use the Node.js packages along with Django?
No. Django is a Python framework and thus runs in a Python interpreter. That interpreter cannot run node.js modules because those are Javascript and rely on the node.js Javascript engine.
If you want to compare things:
node.js <==> python (runtime language engines with built-in libraries)
express <==> django (frameworks that run in a given runtime)
This is kind of confusing because Node.js is a server-side javascript platform
Node.js is a Javascript programming environment. It can be used to write servers, but it can also be used as a general purpose scripting environment to do anything you may want to do on your computer, such as implement various build tools.
webPack is one such build tool that is written in Javascript to be run in node.js. Its function happens to be packaging client-side Javascript files, but it could be any type of tool.
There are many tools written in node.js, particularly tools that are often used by node.js developers (since they already have that environment installed).
If you really needed to combine functionality from both node.js and django, then you would have to create two separate programs 1) a python program using django and 2) a node.js program using whatever Javascript libraries you want and then you could communicate between the two programs using whatever IPC mechanism you choose (TCP, stdio, files, etc...).
While you'd need two different environments to use nodejs as a server along with django as a server, node.js has a critical role in managing packages for client Javascript in modern web development.
As an example, tools like Webpack will bundle a series of Javascript modules for a client. One of the more convenient ways to package these modules and their dependencies is using npm, the Node package manager.
So, it would be entirely reasonable to use Node to bundle the Javascript for your client and even to install the modules for bundling. This is especially true if you're using a framework like Angular on the client. So, if you had an Angular application backed by a Django server, your work flow might look like the following:
Create a node project with your Angular App
use npm to install and manage its dependencies
use ng build --prod to call webpack to produce a bundle that could be sent to the client.
All the above would use Node.
Then:
Write your models and business logic for the server in Django
use some Django restful framework to present a REST API that your client application can call.
This is kind of confusing because Node.js is a server-side javascript platform, but it's being used to:
Provide packaging for client modules
provide server-side transformations to prepare the content that your particular site sends to the client.
We are making a PhoneGap app and trying to use a data service as follows:
$.post(rooturl + '/data/something', { a: 1 }, (res) => {});
The issue: when the app runs on PhoneGap, it is a single page application with no customized server backend. This means I have no way sending across some kind of environment indicator to change the rooturl and direct it at the local NodeJS development server data service, versus the production server.
In other words, how can I have the Javascript on the client-side detect whether or not it is being run in the development environment to properly set the appropriate root url (development / production)?
Unfortunately PhoneGap doesn't address this.
Depending on what tools you are using, looks like your options are:
Cordova hooks that check an env var in the process to determine how to set variables. Example here: http://www.kdmooreconsulting.com/blogs/build-a-cordova-hook-to-setup-environment-specific-constants/
Ionic env config package https://github.com/geeklearningio/gl-ionic2-env-configuration or wait for Ionic to support this feature directly https://github.com/driftyco/ionic-cli/issues/1205
Have a build tool (i.e. Gulp) take care of the variable replacing for you and presumably run the tool manually or somehow have your build pipeline run the appropriate command for the env. Example here: http://geekindulgence.com/environment-variables-in-angularjs-and-ionic/
right now I'm running an ember-cli application on heroku by serving it with the ember server command (not sure if this is the best method) and I'd like to integrate it with New Relic, but I have no idea how to do it.
Careful, ember server starts a live-reload server for development purposes — you edit a file, save it, and the application gets rebuild in an instant — you should not use it to serve an Ember app in production, it's a potential security risk. Normally you run ember server only on your local computer where you develop the code.
For production, build your app with ember build --environment=production, that will create a set of static files in your project's dist/ directory. You can upload these as you would upload any HTML/CSS/Javascript.
Keep in mind that Ember (and other frameworks of this kind like Angular and Backbone) is a single page application (SPA) framework; there is no server-side code at all, it all runs in the browser. Usually you would provide some sort of API (like a REST-API) on the server to provide and process data from a database or to provide other server-side services. That way you can develop the front and back-end separately.
I'm not too familiar with New Relic, but as far as I can tell it is analytics software that runs on the back-end, so it has nothing to do with your browser-side framework.
At the server folder, just find the index.js file and add require('newrelic'); at the beginning of the file. Of course you should also follow the instructions when you setup New Relic at you Heroku App, setting your application as a node.js app, which means you'll have to run npm install --save newrelic, go to your node_modules folder, find newrelic, copy newrelic.js file to the root of your application and edit the file with your app_name and license_key.
I recently removed my code from <meta ... in app/index.html and started to use this addon Ember-new-relic.
Get the JavaScript snippet.
And add it below <meta http-equiv="X-UA-Compatible"... in app/index.html.