How to set proccess.env in Node express app on heroku - node.js

I have a simple node with mongo (via mongojs) app that is developed locally and deployed on heroku. In my development environment, i want to use a local instance of mongo, while in production, I would like to use the instance heroku provides to me via "process.env.MONGOLAB_URI".
My current approach is that I would set the datavase url depending on the environment variable, but how do i actually go into production mode? Moreover, how can i configure this so that when i develop on my local machine its development mode, when i upload to heroku its production mode?
app.configure('production', function(){
// ...
databaseUrl = "mydb"; // the default
});
app.configure('development', function(){
// ...
databaseUrl = process.env.MONGOLAB_URI;
});
db = require("mongojs").connect(databaseUrl);

Set the NODE_ENV environment variable to "development" on your local environment, and set it to "production" on Heroku. https://devcenter.heroku.com/articles/nodejs#setting-node-env

You can also access your online database locally by starting your app by adding the following:
var mongoose = require( 'mongoose' );
var dbURI = 'mongodb://localhost/Loc8r';
if (process.env.NODE_ENV === 'production') {
dbURI= process.env.MONGOLAB_URI;
}
mongoose.connect(dbURI);
And starting your app with "NODE_ENV=production nodemon bin/www"

Related

seting up production database on heroku with sequelize migration error

I want to set up my node express sequelize API on heroku. All the set up was going step by step, until I made this command to migrate:
heroku run npx sequelize-cli db:migrate --app happysunnyhour --env production
and gives that error:
ERROR: Could not find migration method: up sequelize-cli db:migrate
I realise that I dont have anything in the migrations forlder. How can I set it up quickly, since all my models are done ?
Or is it possible to synchronize everything like I did in my localhost ?
const express = require('express');
require('dotenv-flow').config();
const { PORT, NODE_ENV } = process.env;
const app = express();
const db = require('./models'); //all done already
db.sequelize.sync({ alter: true });
If someone know what I am missing ?

Elastic Beanstalk Problem: Connection timing out when running my Node.js Express server

I'm trying to deploy my MERN app on Elastic Beanstalk, and I seem to be running into a final problem that I just cannot solve.
My app works fine when running my server locally (running node server), but when running on elastic beanstalk, the page never loads.
Upon inspection, the static elements are not being loaded, as seen in Dev Tools:
Image showing ERR_CONNECTION_TIMED_OUT in dev tools
I checked all the EB logs and did not find any errors or helpful messages.
I'm thinking the problem is with EB not being able to find my static files somehow. It should however, my build files are not ignored by git and are deployed to EB.
Here's some background about my project:
My backend and client code are in one project, with the following structure:
project
server.js
frontend
build
static
index.html
I run my app by building the react site, then running "node server" which runs great
Here is the relevent code from my server.js :
const port = process.env.PORT || 8081;
app.use(express.static(path.join(__dirname, 'frontend/build')));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'frontend/build/index.html'));
});
app.listen(port, () => {
console.log(`Server is running on port: ${port}`);
});
The server is successfully sending logs that the server is running and that the database has established a connection. So it seems the server is fine, it's just that the front-end is the problem.
eb config file:
option_settings:
aws:elasticbeanstalk:container:nodejs:
NodeCommand: "npm start"
aws:elasticbeanstalk:application:environment:
PORT: 8081
NODE_ENV: production
aws:elasticbeanstalk:container:nodejs:staticfiles:
/static: /frontend/build/static
I'm at a loss on how to solve this. The EB was deployed through the CLI and I haven't messed with any settings. I'm letting EB know where my static files are, and I believe it would say not found, rather than timing out.
Any help would be appreciated
Solved.
The problem was with using Helmet in my express server. I had ommited the code, thinking it not relevant, but here is the top portion of server.js, with the last line being the relevant portion:
const AWS = require('aws-sdk');
const cors = require('cors');
const express = require('express');
const helmet = require('helmet');
const mongoose = require('mongoose');
const path = require('path');
let Download = require('./models/Download.js');
require('dotenv').config();
const app = express();
const port = process.env.PORT || 8081;
app.use(helmet());
Not using helmet solves the issue.
To be honest, I'm not sure why this is the problem.
I assume that the problem is that helmet provides some security that my bare bones EB simply is not providing.
EDIT: Specifically, the problem is with CSP. Setting contentSecurityPolicy to false in Helmet is enough to fix the issue.

How to deploy NextJS application to Linux Server (CentOS 7) - VPS

I've got a question regarding building applications. I'm using simple VPS with node.js support. Now I do not know how to build my next.js application to production.
I want to deploy my application as static files.
I thought that I should use next build && next export then copy out dir to the server but during this process, I faced some issues - when I change route - everything is okay, but if I refresh the page - the page is not found because the server is looking for this file in directories. So how can I deploy my nextjs application in production mode with VPS server and static files?
I tried one thing which is not working fine probably or I did something wrong.
I added nodejs express server with
const express = require('express');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next({dev});
const router = express.Router();
const handle = app.getRequestHandler();
app.prepare()
.then(() => {
const server = express();
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen(3000, (err) => {
if (err) throw err;
console.log('> Ready on http://localhost:3000');
});
});
and start server with forever library NODE_ENV=production node server.js and it's working fine, but seems this is working in a wrong way - seems it's normal server like in dev mode - so it shouldn't be like that. (I see thunder icon on the right-bottom corner and I see all files which are same as in dev mode).
I want to deploy everything as static files.
Thank you for your help!
After you build and export you need to serve those files somehow. The reason the Express server works is because you are starting a HTTP server to serve the files.
So you need to serve those files either by using a static hosting provider (i.e. Vercel or Amazon S3). Otherwise you should start a server on your linux machine using something like serve to serve it at a port, similar to your Express server serving it as localhost:3000 which is then exposed on your VPS.

Node.js how to set server environment PORT and NODE_ENV?

How do I set the server environment to a certain port?
For instance,
const app = require('express')()
const isProd = (process.env.NODE_ENV === 'production')
const port = process.env.PORT || 3000
I will always get false for isProd and 3000 for port
I don't see the usefulness of these two lines and I can just set them below manually:
app.get('/', function (req, res) {
const data = {message: 'Hello World!'}
return res.status(200).json(data);
})
app.listen(3000, function () {
console.log('listening on port 3030!')
})
Do I need some config file in my root?
Any ideas?
I am using Linux/ Ubuntu/ Kubuntu.
Try running your server using below command
set NODE_ENV=production && set PORT=7000 && node server.js
Or for Linux
NODE_ENV=production PORT=7000 node server.js
This will set environment and port for your Node server.
Depends a bit on where you're hosting (e.g. windows or *nix) and how you're running your app (as a Windows or Linux service, using pm2, using systemd, etc).
The simplest way is to just change the command line call you start your app with, eg (linux):
NODE_ENV=prod PORT=34567 node myapp.js
or Windows
set NODE_ENV=prod && set PORT=34567 && node myapp.js
If you're using systemd or pm2 (and you should be), then they each have config files that allow you to set those variables for the environment the server is running in.
Pm2 docs: http://pm2.keymetrics.io/docs/usage/application-declaration/
Locally, you can just set defaults in your environment through normal means (in *nix that means exporting them in your shell config)

Node.js app 404 errors for public directory in Google App Engine Flexible production environment

I've been working with the Node.js Google App Engine for some months and have always successfully used the express.static solution to access static files in the public folder when i deployed my node.js app.
For some (to me not so obvious) reason I struggle to get this working lately in the Google Flexible production environment. On my local development environment everything is fine.
In order to narrow down the problem I created a very basic test app listed here:
'use strict'
const express = require('express')
const app = express()
const path = require('path')
const os = require('os')
const PORT = process.env.PORT || 8080
const ENV = process.env.NODE_ENV
//app.use(express.static('public'))
//app.use(express.static(path.resolve(__dirname, 'public')))
app.use(express.static(path.join(__dirname, 'public')))
app.listen(PORT, () => {
console.log(`SYSTEM: App listening on port ${PORT}`)
console.log(`SYSTEM: Press Ctrl+C to quit.`)
})
app.get('/', (req,res) => {
res.status(200).send('\
<h1>TEST app.use(express.static("public")) in Google Cloud Flexibel App Engine environment </h1>\
<hr/>\
<h4>YAML settings: runtime: nodejs env: flex</h4>\
<h4>HOST : '+`${os.hostname()}`+'</h4>\
<h4>PORT : '+`${PORT}`+'</h4>\
<h4>__dirname : '+`${__dirname}`+'</h4>\
<h4>mountpath : '+`${app.mountpath}`+'</h4>\
<h4>env : '+`${ENV}`+'</h4>\
<h4>path resolved: '+`${path.resolve(__dirname, 'public')}`+'</h4>\
<h4>path joined : '+`${path.join(__dirname, 'public')}`+'</h4>\
<hr/>\
<h2>If you see me <img src="./HB.png"> you can access "./HB.png" in the "public" directory.</h2>\
<h2>If you see me <img src="/HB.png"> you can access "/HB.png" in the "public" directory.</h2>\
<h2>If you see me <img src="HB.png"> you can access "HB.png" in the "public" directory.</h2>\
<hr/>\
')
})
I tried various settings of the express.static settings (see those commented out). However each time after deploying using
gcloud app deploy
to Google production I get 404 (also in the google logs). On local development environment everything is fine.
Does anyone have a clue ? Thanks in advance !
Strange, I solved it by reinstalling the Google Cloud SDK.

Resources