Set Heroku environment variable without restarting app - node.js

Is it possible to set a Heroku environment variable without restarting the app?
My app connects out to different online services via OAuth2. For each service I connect to, I need to set an OAuth2 ID and secret. To keep these configuration variables outside of my code, I'm using environment variables, and reading them in on process.env (node.js).
Each time I add a new service to my app, I need to add the corresponding environment variables for the ID and secret. I need to do this before pushing the latest code, so that when the app next starts up with the new service connection, the OAuth2 ID and secret variables are available.
Currently my workflow is as follows:
Set the environment variables using the Heroku toolbelt: heroku config:set <SERVICE>_ID=foo <SERVICE>_SECRET=bar
Push the latest code: git push heroku master
Currently, both of these operations will restart the app. I'd really prefer the first operation to not restart the app, as the changes to these config vars don't need to take effect until step 2). By restarting at step 1) my app will experience unnecessary downtime.
So, is there any way to prevent step 1) from restarting the app?

According to this article it pretty explicitly states that
Whenever you set or remove a config var, your app will be restarted.
Personally I also wish there was a way to do what you're asking. On larger apps, a system-wide hard restart can be painful when you have many process types running. Many times I set environment variables that aren't crucial for the app to grab ahold of immediately, such as that involving future functionality, or settings that are OK having the old value but you want the new value to take effect in a rolling-restart fashion.

At the present, is not possible to avoid the app restart. But you can use the command heroku config:edit to edit your env at once or even paste a new env set, avoiding many restarts.
In according to the heroku config help:
(...)
COMMANDS
config:edit interactively edit config vars
config:get display a single config value for an app
config:set set one or more config vars
config:unset unset one or more config vars
So you can run
heroku config:edit
Additionally, you might want to take a look on this issue (proposal):
https://github.com/heroku/cli/issues/1570

Related

Change a redis password without external downtime

I would like to refresh redis server password. The issue is that there are some external services using it so until I propagate this change thing will eventually stop working.
From my research I have only seen the requirepass command + the server restart, but this has downtime.
With other databases like Postgres, I would create new user-password, migrate permissions, change at application level and then invalidate the previous access.
How can I do this process in redis?
You can change the password without downtime by issuing:
redis> CONFIG SET requirepass <your new password>
To persist the changes for next restart, edit your .conf file or issue a CONFIG REWRITE.

Doing tasks before heroku nodejs server is ready

When deploying a new release, I would like my server to do some tasks before actually being released and listen to http requests.
Let's say that those tasks take around a minute and are setting some variables: until the tasks are done I would like the users to be redirected to the old release.
Basically do some nodejs work before the server is ready.
I tried a naive approach:
doSomeTasks().then(() => {
app.listen(PORT);
})
But as soon as the new version is released, all https request during the tasks do not work instead of being redirect to old release.
I have read https://devcenter.heroku.com/articles/release-phase but this looks like I can only run an external script which is not good for me since my tasks are setting cache variables.
I know this is possible with /check_readiness on App Engine, but I was wondering for Heroku.
You have a couple options.
If the work you're doing only changes on release, you can add a task as part of your dyno build stage that will fetch and store data inside of the compiled slug that will be deployed to virtual containers on Heroku and booted as your dyno. For example, you can run a task in your build cycle that fetches data and stores/caches it as a file in your app that you read on-boot.
If this data changes more frequently (e.g. daily), you can utilize “preboot” to capture and cache this data on a per-dyno basis. Depending on the data and architecture of your app you may want to be cautious with this approach when running multiple dynos as each dyno will have data that was fetched independently, thus this data may not match across instances of your application. This can lead to subtle, hard to diagnose bugs.
This is a great option if you need to, for example, pre-cache a larger chunk of data and then fetch only new data on a per-request basis (e.g. fetch the last 1,000 posts in an RSS feed on-boot, then per request fetch anything newer—which is likely to be fewer than a few new entries—and coalesce the data to return to the client).
Here's the documentation on customizing a build process for Node.js on Heroku.
Here's the documentation for enabling and working with Preboot on Heroku
I don't think it's a good approach to do it this way. you can use an external script ( npm script ) to do this task and then use the release phase. the situation here is very similar to running migrations you can require the needed libraries to the script you can even load all the application to the script without listening to a port let's make it clearer by example
//script file
var client = require('cache_client');
// and here you can require all the needed libarires to the script
// then execute your logic using sync apis
client.setCacheVar('xyz','xyz');
then in packege.json in "scripts" add this script let assume that you named it set_cache
"scripts": {
"set_cache": "set_cache",
},
now you can use npm to run this script as npm set_cache and use this command in Procfile
web: npm start
release: npm set_cache

Centralized access for config value management

We are using NodeJS as our codebase and all our config value is stored as process.env.variable1
Since our codebase is managed by AWS opsworks it takes almost 10 minutes to deploy config change on 1 machine and we have 23 machine likewise, is there any way through which all config values are stored at a centralised place and code access them without having latency also if there is any auto-refresh mechanism present so that we access the new config value in realtime.

Scripts executed multiple times running on Google Managed VM's

I'm fairly new at google cloud and node. Based on Google's recommendation (the requirement to watch Firebase at all times) I deployed managed VM node app, instead of just app engine. There are now 22-23 instances every time I deploy. Is this expected? I thought it would only scale when necessary.
This node app has a method which watches Firebase variables and change, in turn, the script fires off a notification.
What happens now is that multiple notifications are being fired and I only expect one. I suspect it's because there are multiple instances of this app.
What is the right way to do this so that only one is watching?
Thanks.
You can use the method suggested by google for flexible server environments and firebase. https://cloud.google.com/solutions/mobile/mobile-firebase-app-engine-flexible and https://cloudplatform.googleblog.com/2016/06/learn-to-build-a-mobile-backend-service-with-Firebase-and-App-Engine.html .
Have the instance "claim users" by transactioning it's instance ID at a location where the user can reach it and send updates to that instance by setting the instanceID in the path.

Node.JS with forever on Heroku

So, I need to run my node.js app on heroku, it works very well, but when my app crashes, i need something to restart it, so i added forever to package.json, and created a file named forever.js with this:
var forever = require('forever');
var child = new (forever.Monitor)('web.js', {
max: 3,
silent: false,
options: []
});
//child.on('exit', this.callback);
child.start();
forever.startServer(child);
on my Procfile (that heroku uses to know what to start) i put:
web: node forever.js
alright! Now everytime my app crashes it auto restarts, but, from time to time (almost every 1 hour), heroku starts throwing H99 - Platform error, and about this error, they say:
Unlike all of the other errors which will require action from you to correct, this one does not require action from you. Try again in a minute, or check the status site.
But I just manually restart my app and the error goes away, if I don't do that, it may take hours to go away by itself.
Can anyone help me here? Maybe this is a forever problem? A heroku issue?
This is an issue with free Heroku accounts: Heroku automatically kills unpaid apps after 1 hour of inactivity, and then spins them back up the next time a request comes in. (As mentioned below, this does not apply to paid accounts. If you scale up to two servers and pay for the second one, you get two always-on servers.) - https://devcenter.heroku.com/articles/dynos#dyno-sleeping
This behavior is probably not playing nicely with forever. To confirm this, run heroku logs and look for the lines "Idling" and " Stopping process with SIGTERM" and then see what comes next.
Instead of using forever, you might want to try the using the Cluster API and automatically create a new child each time one dies. http://nodejs.org/api/cluster.html#cluster_cluster is a good example, you'd just put your code into the else block.
The upshot is that your app is now much more stable, plus it gets to use all of the available CPU cores (4 in my experience).
The downside is that you cannot store any state in memory. If you need to store sessions or something along those lines, try out the free Redis To Go addon (heroku addons:add redistogo).
Here's an example that's currently running on heroku using cluster and Redis To Go: https://github.com/nfriedly/node-unblocker
UPDATE: Heroku has recently made some major changes to how free apps work, and the big one is they can only be online for a maximum of 18 hours per day, making it effectively unusable as a "real" web server. Details at https://blog.heroku.com/archives/2015/5/7/heroku-free-dynos
UPDATE 2: They changed it again. Now, if you verify your ID, you can run 1 free dyno constantly: https://blog.heroku.com/announcing_heroku_free_ssl_beta_and_flexible_dyno_hours#flexible-free-dyno-hours

Resources