Skip to content

Commit

Permalink
Merge pull request #26 from anishathalye/heroku-deploy
Browse files Browse the repository at this point in the history
Add button to deploy to Heroku
  • Loading branch information
ehzhang committed May 14, 2017
2 parents 0cbfba1 + cfd4a17 commit a2eff6b
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 9 deletions.
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ You can install Meteor through their [website.](https://www.meteor.com/)
Quickstart
----------

#### Heroku

[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/ehzhang/HELPq/tree/master)

When deploying to Heroku, you **must** set at least the `ROOT_URL` and `ADMIN_PASSWORD` environment variables.

#### Mac OS X, Linux

```sh
Expand All @@ -168,11 +174,9 @@ Deploy
------
**IMPORTANT**

Without login configuration, you will only be able to login with the admin username and password specified in `private/config.json`.

To change the password of the admin account after deployed, you must manually remove the admin user through the meteor mongo shell, and then redeploy with a new admin username/password value. *This will be changed pretty soon*
Without login configuration, you will only be able to login with the admin username and password specified in `private/config.json` (or the corresponding environment variables).

Deploy with:
If you're not using Heroku, you can deploy with:

```sh
meteor deploy <your domain name>.meteor.com
Expand All @@ -183,10 +187,9 @@ Configuration

#### Login

To configure login, edit `private/config.json`
To configure login, edit `private/config.json`. Alternatively, you can configure login using the environment variables listed in `app.json` (this is especially useful when using Heroku).

In `private/config.json`, provide the appropriate application id/secret combinations
for either Facebook or Github authentication, or choose to disable them.
In `private/config.json` (or the corresponding environment variables), provide the appropriate application id/secret combinations for either Facebook or Github authentication, or choose to disable them.

#### Branding

Expand Down
29 changes: 29 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "HELPq",
"description": "An extensible, customizable real-time queue system",
"env": {
"ROOT_URL": "https://{SET THIS}.herokuapp.com/",
"ADMIN_PASSWORD": "{SET THIS}",
"ADMIN_USERNAME": "admin",
"DEFAULT_MENTOR": "true",
"FACEBOOK_CLIENT_ID": "facebook-client-id",
"FACEBOOK_ENABLE": "false",
"FACEBOOK_SECRET": "facebook-secret",
"GITHUB_CLIENT_ID": "github-client-id",
"GITHUB_ENABLE": "false",
"GITHUB_SECRET": "github-secret",
"GOOGLE_CLIENT_ID": "google-client-id",
"GOOGLE_ENABLE": "false",
"GOOGLE_SECRET": "google-secret",
"SETTINGS_EXPIRATION_DELAY": "1800000",
"SETTINGS_QUEUE_ENABLED": "true"
},
"addons": [
"mongolab"
],
"buildpacks": [
{
"url": "https://github.com/AdmitHub/meteor-buildpack-horse"
}
]
}
96 changes: 94 additions & 2 deletions server/startup.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
// Startup Functions
Meteor.startup(function(){
// Grab the config
var config = JSON.parse(Assets.getText('config.json'));
var config = {};
var configJson;
try {
configJson = Assets.getText('config.json');
} catch (err) {
// file doesn't exist, but that's okay
}
if (configJson) {
config = JSON.parse(configJson);
}

// environment variables override config file
var configTemplate = JSON.parse(Assets.getText('config.json.template'));
var envConfigs = readConfigsFromEnv(configTemplate);
overlay(config, envConfigs);

// Create the admin
createAdmin(config.admin.username, config.admin.password);
Expand Down Expand Up @@ -37,7 +51,7 @@ function createAdmin(username, password){
});

if (!user){
Accounts.createUser({
user = Accounts.createUser({
username: username,
password: password,
profile: {
Expand All @@ -46,6 +60,8 @@ function createAdmin(username, password){
});
}

Accounts.setPassword(user, password);

Meteor.users.update({
username: username
},{
Expand Down Expand Up @@ -91,3 +107,79 @@ function setBasicSettings(config){
Settings.insert(config.settings);
}
}

// reads configuration overrides from environment variables according to a
// template object
//
// name are mapped to environment variables like
// 'foo.bar.bazQuux' -> 'FOO_BAR_BAZ_QUUX'
function readConfigsFromEnv(template) {
function rec(template, pathElems) {
var config = {};
for (var key in template) {
if (!template.hasOwnProperty(key)) {
continue;
}
var value = template[key];
var upperCased = key.replace(
/([A-Z])/g,
function(c) { return '_' + c.toLowerCase(); }
).toUpperCase();
var elems = pathElems.concat([upperCased]);
var envName = elems.join('_');
switch (typeof value) {
case 'object':
config[key] = rec(value, elems);
break;
case 'string':
if (typeof process.env[envName] !== 'undefined') {
config[key] = process.env[envName];
}
break;
case 'boolean':
var parsedBool = parseBool(process.env[envName]);
if (parsedBool !== null) {
config[key] = parsedBool;
}
break;
case 'number':
var parsedInt = parseInt(process.env[envName]);
if (!isNaN(parsedInt)) {
config[key] = parsedInt;
}
break;
default:
throw 'unsupported type: ' + (typeof value);
}
}
return config;
}
function parseBool(str) {
if (str) {
if (!isNaN(str)) {
// numeric string
return +str > 0;
} else {
return /^t/i.test(str) || /^y/i.test(str); // accepts things like 'True' and "yes"
}
} else {
return null;
}
}
return rec(template, []);
}

// updates a base object using the values in an overlay object, leaving all
// other values in the base object intact
function overlay(base, object) {
for (var key in object) {
if (!object.hasOwnProperty(key)) {
continue;
}
if (typeof object[key] === 'object' && typeof base[key] === 'object') {
overlay(base[key], object[key]);
} else {
base[key] = object[key];
}
}
}

0 comments on commit a2eff6b

Please sign in to comment.