I have two different Environment development and production
production.js
var config = {
production: {
session: {
key: 'the.express.session.id',
secret: 'something.super.secret'
},
database: 'mongodb://localhost:27018/test',
twitter: {
consumerKey: 'consumer Key',
consumerSecret: 'consumer Secret',
callbackURL: 'http://yoururl.com/auth/twitter/callback'
}
},
}
development.js
var config = {
development: {
session: {
key: 'the.express.session.id',
secret: 'something.super.secret'
},
database: 'mongodb://localhost:27018/testdata',
twitter: {
consumerKey: 'consumer Key',
consumerSecret: 'consumer Secret',
callbackURL: 'http://yoururl.com/auth/twitter/callback'
}
},
}
I have stored these files under environment folder now i want to call these two files in server.js
server.js
var config = require('./environment');
console.log(config);
mongoose.connect(config.database);
mongoose.connection.on('error', function (err) {
console.error('MongoDB connection error: ' + err);
process.exit(-1);
});
How can i call those file in server.js .if i run set NODE_ENV=production in command prompt these should run production database and if i run set NODE_ENV=development in command prompt development database should run .help me out
When require is given the path of a folder, it'll look for an index.js file in that folder; if there is one, it uses that, and if there isn't, it fails.
It would probably make most sense (if you have control over the folder) to create an index.js file and then test process.env :
if (process.env.NODE_ENV === 'production') {
require('production.js');
} else {
require('development.js');
}
node.js require all files in a folder?
https://www.twilio.com/blog/2017/08/working-with-environment-variables-in-node-js.html
Related
I have my Node.js project having environment file setup like below
let config = {
apiVersion: "/api/v1",
PORT: 3001,
mongodb: {
url: "mongodb://localhost:27017/BTracker",
},
};
module.exports = { config: config };
As i deploy my application , i need to change mongodb url and port fields as per my Prod URL.
How can i change these variables based on the environment?
Here is snippet of my index.js
let { config } = require("./app/config/appConfig");
app.listen(config.PORT, () => {
mongoose.connect(config.mongodb.url, { useMongoClient: true });
console.log("App is listening on " + config.PORT);
});
First of all create 2 .env file where you store all the configurations and keep it at the level of your index.js and make sure its not added in your git repository, one for the development and another for production.
Sample .env file for development:
#ENVIRONMENT
ENV="DEVELOPMENT"
#URI
MONGO_URI="mongodb://localhost:27017/BTracker"
Then in your index.js load this env file. You can use the dotenv package to do that.
Code to load the env file.
The first line of your index.js should be this:
require('dotenv').config();
Then you can read all the keys from the env file using
const enviromentValue = process.env[KEY_VALUE];
For your code, you can use this:
let urlDB = process.env.MONGO_URI;
This will set the value of urlDB="mongodb://localhost:27017/BTracker". You will need change the .env file according to your setup, whether you are in production or development environment.
Set enviroment variables for configuration
process.env.PORT = process.env.PORT || 3001;
process.env.NODE_ENV = process.env.NODE_ENV || 'dev';
let urlDB;
if (process.env.NODE_ENV === 'dev') {
urlDB = 'mongodb://localhost:27017/BTracker'
} else {
urlDB = process.env.MONGO_URI;
}
process.env.URLDB = urlDB;
and for your index
require('./app/config/appConfig')
mongoose.connect(process.env.URLDB, { useNewUrlParser: true, useCreateIndex: true }, (err, res) => {
console.log(process.env.URLDB);
if (err) throw err;
console.log();
});
app.listen(process.env.PORT, () => {
console.log(App is listening on , process.env.PORT));
})
Here are my files.
knexfile.js
require('dotenv').config();
module.exports = {
development: {
client: process.env.DB_CLIENT,
connection: {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
},
migrations: {
directory: __dirname + '/db/migrations'
},
seeds: {
directory: __dirname + '/db/seeds'
}
}
};
knex.js
const environment = process.env.NODE_ENV || 'development';
let config = require('../knexfile')[environment];
module.exports = require('knex')(config);
index.js
require('babel-register');
import express from 'express';
const port = process.env.PORT || 5000;
const app = express();
app.listen(port, () => {
console.log('Server running on portt:', port); // eslint-disable-line
});
export default app;
Now when i run following command:
knex migrate:make create_employee_and_company_tables
It gives folllowing error
Error: knex: Required configuration option 'client' is missing.
at new Client (/Users/sujin.v2px/NodeJS/nodees6/node_modules/knex/lib/client.js:99:11)
at Knex (/Users/sujin.v2px/NodeJS/nodees6/node_modules/knex/lib/index.js:56:34)
at initKnex (/usr/local/lib/node_modules/knex/bin/cli.js:73:10)
at Command.<anonymous> (/usr/local/lib/node_modules/knex/bin/cli.js:139:22)
at Command.listener (/usr/local/lib/node_modules/knex/node_modules/commander/index.js:315:8)
at emitTwo (events.js:126:13)
at Command.emit (events.js:214:7)
...
Am I missing some configurations? What does the client missing actually refer to?
This is an answer that may be helpful for some people that land here, because of the same issue where they are using typescript. (beyond the point of dotEnv issue (check the other answer for that)).
'client' is missing error and Typescript
The problem is that your typescript export default is not supported by knex cli by default.
To illustrate:
This doesn't work throwing the error above:
And this work:
As you can see, you can use typescript normally, even the import syntax and all. Then when you export you need to use the commonjs syntax directly.
If not appreciated, you can check this github issue for solution:
https://github.com/tgriesser/knex/issues/1232
I don't know how knex resolve for tsconfig.json. It may matter. And you may add a new tsconfig.json where knexfile.ts is located.
In my case i had that in my config (it was in my project root and not where knexfile.ts [for the project compilation])
"compilerOptions": {
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "ES2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
"allowJs": true,
you may like to change the target.
Another important point, you must have node-ts installed, as it is used under the hood. However if you don't you may have another complete error. And don't forget to install your clients Çıpm i --save pg sqlite3 node-ts typescript knex. (you may like to separate dev dependencies).
I will update after more investigation. To explain deeply the why!
In order to use environment variables from your .env file, pass a path argument to config like this:
require('dotenv').config({path: 'path-to-.env'})
https://github.com/tgriesser/knex/issues/590
What solved this problem for me was in my Knexfile I was using a non-standard environment name:
let dbConnection = {
client : "pg",
connection: connectionObject,
migrations: {
directory: './db/migrations'
},
useNullAsDefault: true
};
module.exports = {
connection: dbConnection
};
So I had to run knex migrate:make --env connection migration_name and it worked as expected.
I advise placing the client immediately below module.exports >>>
module.exports = {
client: 'postgresql',
connection: {
database:'nomedobanco',
user:'user',
password:'senha'
}
You have mentioned require('dotenv').config();
require('dotenv').config();
module.exports = {
development: {
client: process.env.DB_CLIENT,
connection: {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
},
migrations: {
directory: __dirname + '/db/migrations'
},
seeds: {
directory: __dirname + '/db/seeds'
}
}
};
Please make sure you have .env file in the root folder which contains your environmental variables.
# Application
APP_PORT=3000
APP_HOST=127.0.0.1
# Environment
NODE_ENV = development
# Database
DB_CLIENT=mysql
DB_HOST=localhost
DB_USER=myuser
DB_PASSWORD=*******
DB_NAME=vts
DB_PORT=3308
Once you have ".env" file in the root folder, you will see your this error would be gone. Also make sure you have mentioned a correct DB_CLIENT in your .env file.
Just another possibility here since I didn't see anyone mention it yet:
If you are also using knexfile and you are sure your client is set properly, e.g. "pg".
Then make sure your environment variable matches with the knexfile.
What I mean is that, run echo $NODE_ENV to see what your NODE_ENV is.
In my case, mine is actually dev not development(default in knexfile).
Your process.env.DB_CLIENT is undefined. You can verify it by hardcoding
client: 'pg',
without trying to use environment variables / dotenv.
In case where all configuration reading was failed and configuration would have been undefined, different error would have been thrown (cannot read client of undefined).
I Observed knexfile.js does not support env config without path.
So use as below :
require('dotenv').config({path: './'});
The simple answer of this error is you are missing client.
You just need to define all three environment development staging and production
module.exports = {
development: {
client: "mysql",
connection: {
user: process.env.DB_USER,
host: process.env.DB_HOST,
password:process.env.DB_PASSWORD,
database: process.env.DB_NAME
},
migrations: {
directory: __dirname + '/db/migrations',
},
seeds: {
directory: __dirname + '/db/seeds'
}
},
staging: {
client: "mysql",
connection: {
user: process.env.DB_USER,
host: process.env.DB_HOST,
password:process.env.DB_PASSWORD,
database: process.env.DB_NAME
},
migrations: {
directory: __dirname + '/db/migrations',
},
seeds: {
directory: __dirname + '/db/seeds'
}
},
production: {
client: "mysql",
connection: {
user: process.env.DB_USER,
host: process.env.DB_HOST,
password:process.env.DB_PASSWORD,
database: process.env.DB_NAME
},
migrations: {
directory: __dirname + '/db/migrations',
},
seeds: {
directory: __dirname + '/db/seeds'
}
}
};
I have an hapi app that is in development. Upon running my usual node-foreman with Procfile, the app loads in the command line with no errors, but upon browsing to the configured port, the page errors, no connection, or specifically, connection refused. Back to the CLI, no errors. simple message from the server.start "Server running on http://localhost:3000"
I tried directly launching with gulp (no errors). No browser access.
I tried directly launching with node (no errors). No browser access.
I tried creating a hello world app with hapi, and express, both had no errors and DID load in the browser.
I even version controlled the code back to a version I know worked. Starts server fine from CLI, but no browser loading/access.
I'm a little stuck, would love any thoughts on even a path to go down to trouble shoot.
Thank you in advance.
Here is the app JS:
var config = require('./config');
hapi = require('../lib/hapi'),
chalk = require('chalk'),
module.exports.init = function (callback) {
//init app bserver
server = hapi.init();
callback(server, config );
};
module.exports.start = function (callback) {
var _this = this;
_this.init(function (server, config) {
// Start the app by listening on <port>
server.start(function () {
// Logging initialization
console.log('+-----------------------------------------------------------+');
console.log(chalk.green('| ' + config.app.title+ '\t\t\t|'));
console.log('+-----------------------------------------------------------+');
console.log(chalk.green('| Environment:\t' + process.env.NODE_ENV));
console.log(chalk.green('| Standard Port:\t' + config.port));
if (config.https.ssl === true ) {
console.log(chalk.green('| Secure Port:\t' + config.https.port));
console.log(chalk.green('| HTTPs:\t\ton'));
}
console.log(chalk.green('| App version:\t' + config.version));
console.log(chalk.green('| App url:\t\t' + ((config.https.ssl === true ? 'https' : 'http')+"://"+config.url)));
console.log('+-----------------------------------------------------------+');
console.log('| Database Configuration\t\t\t\t\t|');
console.log('+-----------------------------------------------------------+');
console.log(chalk.green(JSON.stringify(config.db, null, 4)));
console.log('+-----------------------------------------------------------+');
if (callback) callback(server, db, config);
});
return server;
});
};
AND HERE IS THE HAPI INCLUDE:
var config = require('../general/config'),
Hapi = require('hapi'),
Good = require('good'),
Hoek = require('hoek'),
Inert = require('inert'),
Vision = require('vision'),
Path = require('path'),
Boom = require('boom'),
Bell = require('bell'),
Cookie = require('hapi-auth-cookie'),
Url = require('url'),
hapiAuthSessions = require('./sessions'),
Promise = require('bluebird'),
fs = require('fs');
/* Initialize ORM and all models */
module.exports.initDBConnections = function( server ) {
server.register([
{
register: require('hapi-sequelize'),
options: [
{
sequelize: new Sequelize(process.env.DATABASE_URL),
name: config.db.connection.database,
models: config.files.server.models,
sync: true,
forceSync:false
}
]
}
], function(err) {
Hoek.assert(!err, err);
});
}
/**
* Initialize rendering engine
*/
module.exports.initRenderingEngine = function (server) {
var paths = [];
var layouts = [];
var partials = [];
var helpers = [];
/* add each module paths to rendering search, assume if route, there is a view fr module */
config.files.server.routes.forEach(function (routePath) {
var rp = Path.relative(Path.join(__dirname,'../../'),Path.resolve(Path.dirname(routePath)+'/../../'))
if(fs.existsSync(rp+'/server/views/'+config.theme+'/content'))
paths.push(rp+'/server/views/'+config.theme+'/content');
if(fs.existsSync(rp+'/server/views/'+config.theme+'/errors'))
paths.push(rp+'/server/views/'+config.theme+'/errors');
if(fs.existsSync(rp+'/server/views/'+config.theme+'/layouts'))
layouts.push(rp+'/server/views/'+config.theme+'/layouts');
if(fs.existsSync(rp+'/server/views/'+config.theme+'/partials'))
partials.push(rp+'/server/views/'+config.theme+'/partials');
if(fs.existsSync(rp+'/server/views/'+config.theme+'/helpers'))
helpers.push(rp+'/server/views/'+config.theme+'/helpers');
});
server.views({
engines: {
html: require('handlebars')
},
path: paths,
layoutPath: layouts,
partialsPath: partials,
helpersPath: helpers,
layout: 'base.view'
});
}
/**
* Initialize local variables
*/
module.exports.initLocalVariables = function (server) {
// Setting application local variables
for (var property in config) {
if (config.hasOwnProperty(property)) {
if (!server.app[property]) {
server.app[property] = config.app[property]
}
}
}
};
/**
* Initialize static routes for browser assets
*/
module.exports.initStaticRoutes = function (server) {
server.route([{
method: 'GET',
path: '/{param*}',
handler: {
directory: {
path: Path.join(__dirname, '../../public'),
redirectToSlash: true,
listing: false,
defaultExtension: 'html'
}
}
},{
method: 'GET',
path: '/assets/vendor/{param*}',
handler: {
directory: {
path: Path.join(__dirname, '../../node_modules'),
redirectToSlash: false,
listing: false,
defaultExtension: 'js'
}
}
}]);
}
/**
* Initialize server logging
*/
module.exports.initLogging = function (server) {
return {
ops: {
interval: 1000
},
reporters: {
myConsoleReporter: [{
module: 'good-squeeze',
name: 'Squeeze',
args: [{ log: '*', response: '*' }]
}, {
module: 'good-console'
}, 'stdout']
}
};
}
/**
* Initialize App Tenant
*/
module.exports.initAppTenant = function (server) {
server.ext('onRequest', function (req, res) {
server.app['tenant'] = req.info.hostname;
res.continue();
});
};
/**
* Initialize ensure SSL
*/
module.exports.initSSL = function(server) {
server.select('http').route({
method: '*',
path: '/{p*}',
handler: function (req, res) {
// redirect all http traffic to https
console.log('redirecting',config.url + req.url.path);
return res.redirect('https://' + config.url + req.url.path).code(301);
},
config: {
description: 'Http catch route. Will redirect every http call to https'
}
});
}
/**
* Initialize static routes for modules in development mode browser assets
*/
module.exports.initModulesStaticRoutes = function(server) {
if (process.env.NODE_ENV === 'development') {
server.route({
method: 'GET',
path: '/modules/{param*}',
handler: {
directory: {
path: Path.join(__dirname, '../../modules'),
redirectToSlash: false,
listing: false,
defaultExtension: 'html'
}
}
});
}
}
/**
* Configure the modules server routes
*/
module.exports.initModulesServerConfigs = function (server) {
config.files.server.configs.forEach(function (routePath) {
require(Path.resolve(routePath))(server);
});
};
/**
* Configure the modules server routes
*/
module.exports.initModulesServerRoutes = function (server) {
config.files.server.routes.forEach(function (routePath) {
require(Path.resolve(routePath))(server);
});
};
/**
* Configure Socket.io
*/
module.exports.configureSocketIO = function (server) {
// Load the Socket.io configuration
var server = require('./socket.io')(server);
// Return server object
return server;
};
/**
* Initialize hapi
*/
module.exports.init = function init() {
var server = new Hapi.Server({
connections: {
routes: {
files: {
relativeTo: Path.join(__dirname, 'public')
}
},
state: {
isSameSite: 'Lax'
}
},
debug: {
'request': ['error', 'uncaught','all','request']
},
cache: [
{
name: 'cacheMem',
engine: require('catbox-memcached'),
host: '127.0.0.1',
port: '8000',
partition: 'cache'
},{
name : 'cacheDisk',
engine : require('catbox-disk'),
cachePath: '/var/tmp',
partition : 'cache'
}
]
});
server.connection({
labels: 'http',
port: config.port
});
if(config.https.ssl == true) {
server.connection({
labels: 'https',
port: config.https.port,
tls: {
key: config.https.key,
cert: config.https.cert
}
});
/* redirect ssl */
this.initSSL(server);
}
server.register([Vision,{register: Good, options: this.initLogging(server)},Cookie,Bell,Inert], function(err) {
Hoek.assert(!err, err);
var _this = module.exports;
var _thisServer = server.select((config.https.ssl == true ? 'https' : 'http'));
/* Initialize sessions */
hapiAuthSessions._init(_thisServer);
/* detect app tenant */
_this.initAppTenant(_thisServer);
/* app local variables */
_this.initLocalVariables(_thisServer);
/* logging */
_this.initLogging(_thisServer);
/* static file serving */
_this.initStaticRoutes(_thisServer);
/* module config, routes, static routes */
_this.initModulesStaticRoutes(_thisServer);
_this.initModulesServerConfigs(_thisServer);
_this.initModulesServerRoutes(_thisServer);
/* rendering engine */
_this.initRenderingEngine(_thisServer);
// Configure Socket.io
server = _this.configureSocketIO(_thisServer);
//server.start located in ../general/app.js
});
return server;
}
HERE IS THE CLI OUTPUT:
[13:58:31] [nodemon] starting `node --inspect server.js`
[13:58:31] [nodemon] child pid: 5596
Debugger listening on ws://127.0.0.1:9229/e2f5837f-b552-4156-b004-e7adb3d30d05
For help see https://nodejs.org/en/docs/inspector
+-----------------------------------------------------------+
| APP - Development Environment |
+-----------------------------------------------------------+
| Environment: development
| Standard Port: 3000
| Secure Port: 3001
| HTTPs: on
| App version: 0.3.0
| App url: https://localhost:3001
+-----------------------------------------------------------+
| Database Configuration |
+-----------------------------------------------------------+
{
"client": "postgresql",
"connection": {
"host": "localhost",
"port": "5432",
"database": "database",
"user": "user",
"password": "password",
"ssl": true
},
"pool": {
"min": 2,
"max": 10
},
"migrations": {
"tableName": "knex_migrations"
},
"debug": true
}
+-----------------------------------------------------------+
Ok. I found the answer (this is twice in a week over looking small detail -- Shame on me).
The smaller problem, that lead me to the larger problem, was upon server.start(callback) I didn't have any error checking, similar to:
server.start(function(err) {
if(err) {
throw err;
}
});
Once I added the err logging, it exposed the reason the server was quietly failing.
My Hapi config was requiring a memcached module, and I had not started my memcached server locally.
All back to to working as designed :)
I have my server.js file working. at localhost:8080 it will serve the file i give it from the the corresponding url name like so http://localhost:8080/about.html, as long as the file exists in public/pages. I'm wondering if I can somehow set a wildcard to leave of extensions for all html files in the url so that I don't have to individually specify each file as an alias in the routes like - ['about','about.html'].
Here is my working code -
'use strict';
const Path = require('path');
const Hapi = require('hapi');
const server = new Hapi.Server();
server.connection({
port: Number(process.argv[2] || 8080),
host: 'localhost'
});
server.register(require('inert'), (err) => {
if (err) {
throw err;
}
server.route({
method: 'GET',
path: '/{param*}',
handler: {
directory: {
path: 'public/pages',
listing: true
}
},
config: {
state: {
parse: false, // parse and store in request.state
failAction: 'ignore' // may also be 'ignore' or 'log'
}
}
});
server.start((err) => {
if (err) {
throw err;
}
console.log('Server running at:', server.info.uri);
});
});
Any help is greatly appreciated, thank you.
I'm using the ftps module and I've got lftp installed on Cygwin. I'm having trouble because my node js app looks like it's connecting fine but none of my commands are running. The documentation for the module isn't very detailed so I've just been trying what ever I can to get this running. I'm tying to get a file from the ftp site.
Here is my code:
var ftps = require('ftps');
// ftps connection
var ftp = new ftps ({
host: 'test.ftpsite.com',
username: 'test',
password: 'test',
protocol: 'sftp'
});
// look at remote directory
console.log(ftp);
ftp.cd('TestDir/').get('/UploadTest.txt', '/cygdrive/c/Users/Administrator/UploadTest.txt').exec(console.log);
Output:
CMO-Application-Server>node app.js
{ options:
{ host: 'test.ftpsite.com',
username: 'test',
password: 'test' },
cmds: [] }
At this point in the output, the app just hangs up like it's attempting to run the commands. I've been letting it run for about 10 minutes now and still nothing.
For sftp, here's how you could do it with the ssh2 module:
var Connection = require('ssh2');
var ssh = new Connection();
ssh.on('ready', function() {
ssh.sftp(function(err, sftp) {
if (err) throw err;
sftp.fastGet('TestDir/UploadTest.txt',
'/cygdrive/c/Users/Administrator/UploadTest.txt',
function(err) {
if (err) throw err;
ssh.end();
});
});
}).connect({
host: 'test.ftpsite.com',
port: 22,
username: 'test',
password: 'test'
});