juto:config
Configure meteor using node-config, allowing you to split your development and production meteor settings JSON.
Based on the ideas from 4commerce:env-settings,
this provides a meteor build plugin so that you can use it as part of a meteor build
command.
Breaking Change
NB: v3.0.0 requires you to manage your own npm version of node-config.
meteor npm install config --save
It also allows NODE_CONFIG
env vars to override settings from any files, which previously did not work with this plugin.
Demo
See this repository for an example meteor project that uses this package.
Background
node-config is great for pure node applications, and 4commerce:env-settings is useful for meteor while in development.
However, when it comes to building your meteor application for deployment, if you have a cordova app then you can't use 4commerce:env-settings. This is due to a limitation of meteor's build tool, which expects a settings file. From that settings file, the Meteor.settings.public object is extracted and copied to the mobile application.
juto:config works around this limitation by providing a build plugin, which generates the settings
json file needed by the meteor build
command. It uses node-config to do this.
Getting started
- Add this package:
meteor add juto:config
- Edit your
.meteor/packages
file to put juto:config right near the top, just after
meteor-base
(or meteor
).
3. Create a folder private/config
in your meteor project.
4. Create a private/config/default.json
file:
1 { 2 "server": { 3 "foo": "bar", 4 "defaultServerKey": "default server value" 5 }, 6 "public": { 7 "foo": "public bar" 8 } 9 } 10 ``` 11 125. Create a ```private/config/production.json``` file with values to override the default ones 13when your app is in production: 14 ```json 15 { 16 "server": { 17 "foo": "production bar", 18 "anotherServerKey": "production extra server val" 19 }, 20 "public": { 21 "foo": "production public bar", 22 "anotherKey": "production extra val" 23 } 24 } 25 ``` 26 276. Create a ```server/load-config.js``` file to load the config files from 28```private/config``` and extend the global ```Meteor.settings``` object : 29 30 ```js 31 import { Meteor } from 'meteor/meteor'; 32 let path = require('path'); 33 34 Meteor.startup(()=>{ 35 // get the actual path of private/config/default.json 36 var filePath = Assets.absoluteFilePath("config/default.json"); 37 // pass the actual path of private/config to JutoConfig. 38 JutoConfig(path.dirname(filePath)); 39 // Now Meteor.settings environment has been set. 40 41 }); 42 43 ``` 44 457. Tell [juto:config] about your setup by creating a ```juto-settings-config.json``` file: 46 47 ```json 48 { 49 "configSourcePath":"private/config", 50 "outputSettingsFiles":true, 51 "settingsProduction":"settings-production.json", 52 "settingsDevelopment":"settings-development.json" 53 } 54 ``` 55 56 This tells it to output a ```settings-production.json``` file and a 57 ```settings-development.json``` file, 58 which you can pass to the ```meteor build```, ```meteor run ios``` or ```meteor run android``` commands. 59 60 Alternatively, if your config is more complex than just `development` and `production`, you can specify an array of 61 settings files to generate: 62 63 ```json 64 { 65 "configSourcePath" : "packages/juto-load-config/config", 66 "outputSettingsFiles":true, 67 "environments": [ 68 { 69 "NODE_ENV": "production", 70 "outputFile": "settings-production.json" 71 }, 72 { 73 "NODE_ENV": "development", 74 "outputFile": "settings-development.json" 75 }, 76 { 77 "NODE_ENV": "development", 78 "HOST": "dev.ju.to", 79 "outputFile": "settings-dev-ju-to.json" 80 } 81 ] 82}
These files should not be used when running meteor in development mode for a web browser; Simply run it without the settings flag and let your ```server/load-config.js``` (above) do the work of deciding which settings to provide on the server and client. Note that ```settings-production.json``` file doesn't need to be generated yet for you to be able to pass it to a ```meteor build``` command; since [juto:config] provides a meteor build plugin, the file will be generated just before it is needed. So you should be able to use this in a continuous integration environment.
The configuration above results in the following for Meteor.settings
:
Server - development :
1{ 2 "public": { 3 "foo": "public bar" 4 }, 5 "foo": "bar", 6 "defaultServerKey": "default server value" 7}
Client - development:
1{ 2 "public": { 3 "foo": "public bar" 4 } 5}
Server - production :
1{ 2 "public": { 3 "foo": "production public bar", 4 "anotherKey": "production extra val" 5 }, 6 "foo": "production bar", 7 "defaultServerKey": "default server value", 8 "anotherServerKey": "production extra server val" 9} 10
Client - production :
1{ 2 "public": { 3 "foo": "production public bar", 4 "anotherKey": "production extra val" 5 } 6} 7
Running meteor with limited access
Now when you run meteor as a developer who does NOT have their GPG key in the list of allowed keys (i.e. the files are encrypted from your point of view), you will receive an error.
ERROR: /Users/mikecunneen/Documents/Development/Juto/app-builder/private/config/production.json is a git-crypt file and CONFIG_SKIP_GITCRYPT is not set.
You will need to set the environment var CONFIG_SKIP_GITCRYPT=1 to skip encrypted git-crypt files e.g. :
CONFIG_SKIP_GITCRYPT=1 meteor --port 4000
Deployment tools (mup, pm2-meteor etc)
If you're using mup, mupx, pm2-meteor or some other deployment tool,
just symlink settings-production.json
to your required settings file
(or settings-development.json
if it's destined for a development server). E.g.:
mkdir .deploy_prod cd .deploy_prod mup init rm settings.json ln -s ../settings-production.json settings.json
Now protect your production data
To ensure your production keys don't accidentally end up in a git repository, you have a few options:
Option 1 - Don't store them in git at all
Use .gitignore, e.g.
private/config/production.json settings-development.json settings-production.json
Option 2 - encrypt them
Use git-crypt or similar, e.g.
git-crypt init echo 'private/config/production.json filter=git-crypt diff=git-crypt' >> .gitattributes echo 'settings-production.json filter=git-crypt diff=git-crypt' >> .gitattributes