Why does React not seem to recognize Heroku's PORT env variable? - javascript

I am trying to deploy a frontend react application with a django backend. I am able to get Heroku's PORT environment variable just fine for the Django backend, but no matter what I do or try, process.env.PORT keeps returning undefined. I have tried adding a temporary variable that begins with REACT_APP that just reads the PORT variable in the procfile. Env files won't work because the PORT variable is dynamically allocated.
Every resource I have found have said to either try a .env file or exporting the variable, but like I said, that is unrealistic because Heroku dynamically allocates the port. Any ideas?

Environment variables aren't available in the client. That's running in the user's browser, not the server. For that matter there isn't a Node process running on the server, either. Given you're using an NGINX buildpack the Django app is presumably in a different dyno entirely, you don't need to know which PORT it's bound to. - #jonrsharpe
In the Heroku deployed environment, the project should be oriented such that the frontend will make a request to the backend through a specific url configuration, not through a different port call.

Related

Struggling to understand how React determines address of API server

I have a project with a client folder containing a React app bootstrapped with create-react-app. I also have a server folder with an express API server running on localhost:80.
Originally, I ran my frontend and backend as separate servers, making requests to the API server by making requests with fetch("url") and using "proxy": "localhost:80" in my package.json
I have recently altered the project so that my server serves the static frontend files like so: app.use(express.static(path.resolve(__dirname, "../client/build")))
I then tested running the server on two different ports 80 and 3000, and the frontend and backend both worked perfectly but I believed it would only work when the server was run on port 80
How does my frontend now know where to call the API server when it is running on different ports?
Proxy is used in the development environment and after that when you make build then its convert into the static HTML, CSS and JS files and that can be run in any port using node if you try that in a different port than it will also work as same
Proxy is not made for the production environment
https://github.com/facebook/create-react-app/issues/1087

Environment variables returning undefined when connecting Firebase Firestore to a node.js server hosted on Heroku

I am quite new to the node.js way of doing things coming from using PHP and SQL to do everything. I was recently trying to set up a node server on Heroku in order to do some back end logic on my google firestore database.
I didn't want my private key to be publically accessible as a file and I saw that the easiest way was to store the variables as environment variables and use them to set up the certificate to initialise firebase-admin from a previous stack overflow question.
I have now tried to set this up and hosting it on heroku. Having defined my environment variables I double checked that the names are correct and have been set by heroku config:set and then checking using heroku config. I would show this but it obviously contains my private key!
So when i try to run this segment of code:
//requires firebase module
var admin = require('firebase-admin');
const private_key = process.env.FIREBASE_PRIVATE_KEY_ID;
console.log(private_key);
//initialises a firebase app with the credential
admin.initializeApp({
credential: admin.credential.cert({
"private_key": process.env.FIREBASE_PRIVATE_KEY_ID,
"client_email": process.env.FIREBASE_CLIENT_EMAIL,
"project_id": process.env.FIREBASE_PROJECT_ID,
"private_key_id": process.env.FIREBASE_PRIVATE_KEY_ID
}),
databaseURL: "https://MY_APP.firebaseio.com"
});
//get access to firestore from initialised app
var db = admin.firestore();
With MY_APP changed out from what it is in the source code.
So when i run this and console log the key I get:
[1
I am sorry if this is a trivial problem, as I say I am definitely a beginner with node. I have done a bit with the HTTP module for handling some requests but not connecting up to firebase. Any advice or help would be greatly appreciated!
heroku config:set sets environment variables on Heroku, but heroku local runs your application on your local machine:
Heroku Local is a command-line tool to run Procfile-backed apps. It is installed automatically as part of the Heroku CLI. Heroku Local reads configuration variables from a .env file. Heroku Local makes use of node-foreman to accomplish its tasks.
heroku local will automatically read a file called .env and set environment variables for you based on what it finds there. This file should not be tracked by Git (it's for your local environment, not for Heroku, and as you mentioned it will contain sensitive information that shouldn't be checked in anyway).
If you want to copy a configuration variable that you currently have on Heroku you can add it to your .env by running
heroku config:get CONFIG-VAR-NAME -s >> .env
(There are actually many ways to set environment variables on your local machine, and any of them will work with heroku local. If you prefer another method, go for it.)

How to query local dynamoDB using dynamoose?

As a developer, i don't want to connect all the time to Amazon web services, and I installed DynamoDB in my local computer referring the AWS Docs. I am using node.js in the backend.
I am using dynamoose as the modeling tool for Amazon's DynamoDB in my production, How can I use the same dynamoose for querying my local DynamoDB tables for development?
You just use this in your code:
dynamoose.local();
Assuming you have a properties file in your application, you probably want a property flag to indicate whether you are in Development or Production. Then in your code, get the property, if you are in Development, run the dynamoose.local() line.
EDIT: I don't code in javascript but it will be something like:
const { NODE_ENV } = process.env
if (NODE_ENV == "DEV") {
dynamoose.local();
}
This assume you have a properties file in your application where you set a system property called "environment" to have a value of say "DEV" or "PROD".
There may be a version thing, but I had to do
var dynamoose = require('dynamoose');
dynamoose.aws.ddb.local();
The code below should allow you to setup Dynamoose for use locally.
var dynamoose = require('dynamoose');
dynamoose.local('http://localhost:8000');
This assumes DynamoDB is running locally on port 8000. If you are not running DynamoDB Local on port 8000 you will have to update the second line above to reflect the correct port.
Edit
As mentioned in the comments you don't need to specify 'http://localhost:8000' as those are the defaults. You can of course change the port or host to be what you want if you are not using the default options of port being 8000 and host being localhost.
If you are looking for newer versions of dynamoose the correct syntax is.
dynamoose.aws.ddb.local(http://localhost:8000)
https://dynamoosejs.com/guide/Dynamoose/#dynamooseawsddblocalendpoint

Point domain to node express server on Azure

This must be an extremely common problem. I've seen various answers for this but none seem to work for me.
I have node installed on an apache server on Windows Azure. My app is built and ready to go (snippet below):
var express = require("express");
var app = express();
//example api call
app.get("/api/example", function(req, res){
//do some process
res.send(data);
});
app.listen(8080);
console.log("App listening on port 8080");
Now, when testing on my own computer, I could then go to localhost:8080, which works great. But now I've put it on the azure server I can't get an external domain to point to it properly. So for example, I have the domain:
framework.example.com
I've added this to my hosts file in Azure:
XXX.0.0.01 framework.example.com
Initially I tried also editing the http-vhosts.conf to point the domain to the correct directory. This worked for loading the frontend, but the app couldn't talk to the backend. API calls returned 400 not found errors.
I've also tried an Express vhost method but think I'm doing it wrong and don't fully understand it. What is the correct method?!
My app structure is like this:
- package.json
- server.js
- server
- files used by server.js
- public
- all frontend files
So to boot the server I run server.js which runs the code at the top. The server.js uses the below Express config to point to the public folder.
app.use(express.static(__dirname + "/public"));
Adding it to the hosts file in Azure won't help. You'll need to configure your domain's DNS to point to Azure. I'd recommend using the DNS Name of your Cloud Service instance. Your underlying VM IP address could change if you need to stop it for some reason, but your Cloud Service DNS name is configured to always route to your underlying VMs. That means you'll need to setup a CNAME with your DNS.
Read more about that here: Cloud Services Custom Domain Name
Next, you'll either need to host the node app on port 80, or put a proxy in front of it to handle that for you. Otherwise you'll be stuck typing framework.example.com:8080 which is not ideal. On linux, you'll likely need to be a privileged user to host on port 80, but you never want your node app to have root privileges. You can use authbind to work around this problem.
See an example of how to use it with node here: Using authbind with Node.js
All that being said, it seems like you're somewhat new with linux server management. If that's the case, I'd strongly recommend trying to use something like Azure Websites instead of a VM. You no longer have to manage the virtual machine OS. You simply tell it to host your application and it takes care of the rest. If you're using github, this is incredibly easy to test and iterate with. It does host on Windows under the hood, and that might problems for some applications, but I host all my node sites there (developed on Mac) without any issues.

Node.js /socket.io/socket.io.js not found express 4.0

So I'm trying to get chat working on my website, and when I was testing locally it worked great, because port 8080 on my localhost was available and all that good stuff. But now I pushed my code to my Heroku app, and when I try and load my chat page, I get the error stating that it can't get localhost:8080/socket.io/socket.io.js.
I've seen node.js /socket.io/socket.io.js not found
and tried the suggestions, but none worked, even moving the socket.io.js file into a resource file did not work. I'm guessing this is because I'm using express 4.0?
Any help would be appreciated
Thanks
Edit:
So to add more details, since my question could seem a little vague, here is my relevant app.js code:
var client = require('socket.io').listen(8080).sockets;
In my jade file for the chat page, I have:
script (src = `'http://localhost:8080/socket.io/socket.io.js`')
and later on
var socket = io.connect(`'http://localhost:8080`');
and all this works on localhost (I load up on port 5000, socket.io is connected to port 8080). I do this using 'foreman start' with the heroku toolbelt.
When I try and change these to work on heroku, it breaks and I'm not sure how to fix it. I hope this clarifies the question a bit.
Edit 2:
I'm running:
express 4.0.0
socket.io 0.9.16
node 0.10.x
Thanks
Do you have an explicit route in express which catches all other routes? Something like this perhaps:
app.get("/", handlers.home);
app.get("/..." ...);
...
app.get("*", handlers.error);
This might keep socket.io from being able to host it's own js file for the client. There is an easy way to fix this, since you probably already have a public or static folder setup in express. Something like:
app.use(express.static("public"));
Make a new folder called socket.io and copy over the appropriate socket.io.js file into said folder, and all should be well. However note that there are two files named socket.io.js!! So, if you see something like "Uncaught ReferenceError: require is not defined" it means you copied the "node-ey" server side file. Here is the correct client file to copy:
app_dir/node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.min.js
Note #BHendricks: I would have just posted as a reply to your comment, but I currently lack the required reputation.
Edit:
The OPs question probably has more to do with the "localhost" issue. When connecting from a client (say your home IP), as far as your browser knows - localhost implies a connection with the machine which is locally hosting stuff. Since your home machine (or phone) does not host socket.io, this is failing.
What you need to do is have your server embed the socket connection information (either a fully qualified hostname, ip etc). This can be done when the server "renders" the page with the client connection.
What happens when you go to http://localhost:8080/socket.io/socket.io.js?
Does it 404? If it does you need to make sure you have it in a directory that Express is set to serve statically.
app.use(express.static(__dirname + '/public'));
Then put your socket.io.js file in public/socket.io/socket.io.js (relative to your app.js file)
Restart your server and see if that fixes it.
Basically, Express doesn't serve files statically from the file system unless you explicitly tell it where to map from.

Categories

Resources