I am trying to deploy my test Express.js app on Heroku using GitHub for resources and mlab for my database. In development th app doesn't have problems when I pass mLab connection string but in production... How must my production environment look?
Here is my config.js:
const env=require('dotenv').config();
module.exports = {
development: {
port: process.env.PORT|| 3000,
dbPath: process.env.DB_CONNECTION,
},
production: {
port: process.env.PORT|| 3000,
dbPath: process.env.DB_CONNECTION_MLAB,
}
};
Your .env file probably isn't (and shouldn't be) used in production. It should be ignored in your Git repository.
This means your production database configuration needs to come from somewhere else. If you're using the official mLab addon you can access your connection string via the MONGODB_URI environment variable, which the addon sets automatically.
If you're not using the official addon you should set the appropriate environment variable yourself, e.g. via
heroku config:set MONGODB_URI=...
In either case, make sure the name of the environment variable in your code matches what's set in the environment. Generally there is no need for separate development and production variables since they are set in different environments. I recommend using MONGODB_URI everywhere.
Related
I'm relatively new to Node, and especially new to moving an app from dev to production environment.
I have a Node + Express + Sequelize client app hosted on Heroku, as well as a Postgres db resource connected to the app. The client runs fine for certain routes, and I have the Postgres database in the "resources" of my app. But the client returns undefined on the first SQL query (e.g. a GET request to /books route simply returns undefined).
I have tried setting process.env.DATABASE_URL in app.js to the database URI like this:
const postgres =
"postgres://foo:bar#xxx.compute-1.amazonaws.com:5432/yyy";
process.env.DATABASE_URL = postgres;
I also tried manually changing "production" to test the production env in a development setting const env = process.env.NODE_ENV || "production".
I've read through Heroku docs and various articles, but I'm not sure why I can't access the database except during development.
What am I not understanding here?
I have the following code which works fine locally, but when I deploy to an Azure function it fails to read in the contents of the .env file at runtime, when debugging each of the config items is "undefined". .Env file is deployed to Azure with correct entries and the function executes correctly when I hard code the config variables to test. I assume I need to do something differently to get this to work on Azure?
const sql = require('mssql')
require('dotenv').config();
const dbConfig = {
server: process.env.databaseServer,
database: process.env.databaseName,
user: process.env.databaseUser,
password: process.env.databasePassword,
port: 1433,
options: {
encrypt: true,
"enableArithAbort": true
}
};
Azure function is a packed service, its process.env has reloaded properties of the Azure function environment, by default, it will not load your .env file.
It is recommended that defining all your .env content in Azure function application settings:
Simple demo to get this value:
Related doc sees here.
I am building some application with NODEJS and Mongodb.
I push my commits to github (development) and to Heroku (Production).
It is frustrating to have to change every time I need to make my push the database connection:
const mongoose = require('mongoose');
// process.env.MONGODB_URI => for PRODUCTION HEROKU
// `mongodb://localhost/myProject` => for Local Development + GitHub Repo
mongoose.connect(**process.env.MONGODB_URI**, {family:4,useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify:false, useCreateIndex:true })
.then(ok => {
console.log(`Connected to Mongo! Database name: "${ok.connections[0].name}"`)
})
.catch(err => {
console.error('Error connecting to mongo', err)
});
I would like to make some kind of function to set connections when I push commits, for each situation.
For example, this logic:
mongoose.connect(if process.env.MONGODB_URI works, get it. If not, get this one: `mongodb://localhost/myProject`)
Or even better:
if request is in http://localhost:3000/ => get this connection `mongodb://localhost/myProject
if not get this one => process.env.MONGODB_URI
I don't really want a solution, just I would like to know if that is possible, and first step to reach it.
Thanks.
Take a look at dotenv
https://www.npmjs.com/package/dotenv
Be sure to include the .env file in your .gitignore.
you should not commit the .env file. It is common for developers to list the environment variables necessary to run the program in a README or similar internal documentation.
Some developers create and maintain a .sample-env file in the source code repository. This sample file would list all the environment variables used by the app, for example:
HOST=
PORT=
A developer would then clone the repository, copy the .sample-env file into a new .env file and fill in the values.
If your app is running on a physical machine or a virtual machine (for example, Digital Ocean droplets, Amazon EC2 and Azure Virtual Machines), then you can create a .env while logged into the server and it would run just as it is done on your local machine.
I've been developing a nodejs app on C9 for some time and now I'm trying to make a copy of it on my remote host. So far, in the new environment node app.js works in the console but I am unable to view the website in my browser.
It seems that it is a port issue.
My app.js file goes like this :
var express = require("express"),
app = express();
(...)
app.listen(process.env.PORT, process.env.IP, function(){
console.log(process.env.PORT);
console.log("The YelpCamp Server Has Started!");
});
In the C9 environment, the log tells me that process.env.PORT is 8080. But in the new environment, the log tells me that process.env.PORT is undefined.
How can I fix this ?
This is similar to this older question except that my remote OS is Linux not Windows. The answer to this question says that one should "modify the web.config file", but I couldn't find it on my remote host and I'm not sure it works the same way under Linux and under Windows.
process.env variables are set by the "Environment". Basically, they act as access to your systems environment variables. When trying to access process.env.PORT it'll return undefined if you've not setup that environment variable in the shell that you're trying to run your system.
You can set the environment variable up before you run node app.js with the following.
$ PORT=8080
$ node app.js
In this case we set the environment variable within the existing shell, then we call node with the app.js file. Environment variables are passed from parent processes into processes they start, if you run those two in sequence, you'll be setting up an environment variable within the current shell, and node will then receive that when it starts up (along side all other environment variables).
To see all environment variables avalible to the existing node process you can run console.log(process.env);.
This will be the same for process.env.IP as well.
Side note: C9 and other similar environments often have a lot of pre-set environment variables. This is why it was available on C9. The same is true for Heroku as well, this is because their system must dictate the port your service should use so that their load balancers / reverse proxies can be pre-configured for that port.
I ran into something similar and ended up providing a default port number if one couldn't be read from the environment.
const PORT = process.env.PORT || 8080;
app.listen(PORT, ...)
After deploying your node project files, you'll need to make sure any env variables are also transferred.
1. Manually copy-paste env variables
From the original host config to the new host config. Use the dashboards on either end. Simple and secure.
--- or ---
2. Manually transfer .env file from project root
(Not recommended for production environments) Node projects often have a .env file in the root, which is commonly excluded from file transfers (for obvious security reasons). You'd need to make sure the new host also has the identical .env file in root. For production environments, this is usually not desired for security reasons, and it's better to use option #1.
Projects using this method are likely using the dotenv package which detects .env and makes the parameters available to your app. It's mainly for development convenience.
Historically on most large projects I have worked on we have a build script of some sort which is run by a developer to setup their environment, such as setting up iis, database migrations, templating configuration files etc.
As each environment is different, I would generally have a set of configuration files for each environment, such as dev.config, qa.config or release-candidate.config, then when the build process runs it would use the <environment>.config file to find out what its settings should be. This way my dev environment can build fine and the build server can do its stuff fine too in an automated fashion.
Anyway in .net we have configuration files such as web.config which can be templated, is there any notion of this within the nodejs world? as I want to have a file which contains all the configuration values required for the application to run without putting them in the application code.
You can do that very simple, actually. Just place all your configuration in .js file, like
{
mongodb: {
connection: 'http://mongodb.com/mydb:12323/user/password',
options: {
keepConnection: true
}
},
app: {
deploymentKey: '1234'
},
// etc
}
So, you will have 2-3 files, depending on the number of environments you have.
/config/development.js
/config/production.js
/config/test.js
/config/staging.js
The environment type is typically exposed by NODE_ENV variable. Then you have really simple module, to load the configuration:
var util = require('util');
var env = process.env.NODE_ENV || 'development';
var config = util.format('/%s.config.js', env);
module.exports = require(__dirname + config);
Checkout some real code here;
This is why I created the properties module.
Check the environment example.