From efd3ee4ce842861bc1044f0c8b5883bb715d531f Mon Sep 17 00:00:00 2001 From: Ryan J Baxter Date: Wed, 29 Jul 2015 11:02:37 -0400 Subject: [PATCH] Initial support for deploying MEANJS to Cloud Foundry --- .cfignore | 10 +++++ README.md | 34 ++++++++++++++++ config/assets/cloud-foundry.js | 23 +++++++++++ config/env/cloud-foundry.js | 71 ++++++++++++++++++++++++++++++++++ manifest.yml | 13 +++++++ package.json | 3 +- 6 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 .cfignore create mode 100644 config/assets/cloud-foundry.js create mode 100644 config/env/cloud-foundry.js create mode 100644 manifest.yml diff --git a/.cfignore b/.cfignore new file mode 100644 index 0000000000..d0f44fddf6 --- /dev/null +++ b/.cfignore @@ -0,0 +1,10 @@ +# List of files and directories to ignore when deploying to Cloud Foundry +.DS_Store +.nodemonignore +.sass-cache/ +npm-debug.log +node_modules/ +public/lib +app/tests/coverage/ +.bower-*/ +.idea/ diff --git a/README.md b/README.md index 5ba54ee710..959816c9ee 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,40 @@ In the docs we'll try to explain both general concepts of MEAN components and gi ## Live Example Browse the live MEAN.JS example on [http://meanjs.herokuapp.com](http://meanjs.herokuapp.com). +## Deploying To Cloud Foundry + +Cloud Foundry is an open source platform-as-a-service (PaaS). The MEANJS project +can easily be deployed to any Cloud Foundry instance. The easiest way to deploy the +MEANJS project to Cloud Foundry is to use a public hosted instance. The two most popular +instances are [Pivotal Web Services](https://run.pivotal.io/) and +[IBM Bluemix](https://bluemix.net). Both provide free trials and support pay-as-you-go models +for hosting applications in the cloud. After you have an account follow the below steps to +deploy MEANJS. + +* Install the [Cloud Foundry command line tools](http://docs.cloudfoundry.org/devguide/installcf/install-go-cli.html). +* Now you need to log into Cloud Foundry from the Cloud Foundry command line. + * If you are using Pivotal Web Services run `$ cf login -a api.run.pivotal.io`. + * If you are using IBM Bluemix run `$ cf login -a api.ng.bluemix.net`. +* Create a Mongo DB service, IBM Bluemix and Pivotal Web Services offer a free MongoLabs service. + * `$ cf create-service mongolab sandbox mean-mongo` +* Clone the GitHub repo for MEANJS if you have not already done so + * `$ git clone https://github.com/meanjs/mean.git && cd mean` +* Run `$ npm install` +* Run the Grunt Build task to build the optimized JavaScript and CSS files + * `$ grunt build` +* Deploy MEANJS to Cloud Foundry + * `$ cf push` + +After `cf push` completes you will see the URL to your running MEANJS application +(your URL will be different). + + requested state: started + instances: 1/1 + usage: 128M x 1 instances + urls: mean-humbler-frappa.mybluemix.net + +Open your browser and go to that URL and your should see your MEANJS app running! + ## Credits Inspired by the great work of [Madhusudhan Srinivasa](https://github.com/madhums/) The MEAN name was coined by [Valeri Karpov](http://blog.mongodb.org/post/49262866911/the-mean-stack-mongodb-expressjs-angularjs-and) diff --git a/config/assets/cloud-foundry.js b/config/assets/cloud-foundry.js new file mode 100644 index 0000000000..1e7744763b --- /dev/null +++ b/config/assets/cloud-foundry.js @@ -0,0 +1,23 @@ +'use strict'; + +module.exports = { + client: { + lib: { + css: [ + 'public/lib/bootstrap/dist/css/bootstrap.min.css', + 'public/lib/bootstrap/dist/css/bootstrap-theme.min.css', + ], + js: [ + 'public/lib/angular/angular.min.js', + 'public/lib/angular-resource/angular-resource.min.js', + 'public/lib/angular-animate/angular-animate.min.js', + 'public/lib/angular-ui-router/release/angular-ui-router.min.js', + 'public/lib/angular-ui-utils/ui-utils.min.js', + 'public/lib/angular-bootstrap/ui-bootstrap-tpls.min.js', + 'public/lib/angular-file-upload/angular-file-upload.min.js' + ] + }, + css: 'public/dist/application.min.css', + js: 'public/dist/application.min.js' + } +}; \ No newline at end of file diff --git a/config/env/cloud-foundry.js b/config/env/cloud-foundry.js new file mode 100644 index 0000000000..361bb94514 --- /dev/null +++ b/config/env/cloud-foundry.js @@ -0,0 +1,71 @@ +'use strict'; + +var cfenv = require('cfenv'), + appEnv = cfenv.getAppEnv(), + cfMongoUrl = appEnv.getService('mean-mongo') ? + appEnv.getService('mean-mongo').credentials.uri : undefined; + +var getCred = function(serviceName, credProp) { + return appEnv.getService(serviceName) ? + appEnv.getService(serviceName).credentials[credProp] : undefined; +}; + +module.exports = { + port: appEnv.port, + db: { + uri: cfMongoUrl, + options: { + user: '', + pass: '' + } + }, + log: { + // Can specify one of 'combined', 'common', 'dev', 'short', 'tiny' + format: 'combined', + // Stream defaults to process.stdout + // By default we want logs to go to process.out so the Cloud Foundry Loggregator will collect them + options: { + } + }, + facebook: { + clientID: getCred('mean-facebook', 'id') || 'APP_ID', + clientSecret: getCred('mean-facebook', 'secret') || 'APP_SECRET', + callbackURL: '/api/auth/facebook/callback' + }, + twitter: { + clientID: getCred('mean-twitter', 'key') || 'CONSUMER_KEY', + clientSecret: getCred('mean-twitter', 'secret') || 'CONSUMER_SECRET', + callbackURL: '/api/auth/twitter/callback' + }, + google: { + clientID: getCred('mean-google', 'id') || 'APP_ID', + clientSecret: getCred('mean-google', 'secret') || 'APP_SECRET', + callbackURL: '/api/auth/google/callback' + }, + linkedin: { + clientID: getCred('mean-linkedin', 'id') || 'APP_ID', + clientSecret: getCred('mean-linkedin', 'secret') || 'APP_SECRET', + callbackURL: '/api/auth/linkedin/callback' + }, + github: { + clientID: getCred('mean-github', 'id') || 'APP_ID', + clientSecret: getCred('mean-github', 'secret') || 'APP_SECRET', + callbackURL: '/api/auth/github/callback' + }, + paypal: { + clientID: getCred('mean-paypal', 'id') || 'CLIENT_ID', + clientSecret: getCred('mean-paypal', 'secret') || 'CLIENT_SECRET', + callbackURL: '/api/auth/paypal/callback', + sandbox: false + }, + mailer: { + from: getCred('mean-mail', 'from') || 'MAILER_FROM', + options: { + service: getCred('mean-mail', 'service') || 'MAILER_SERVICE_PROVIDER', + auth: { + user: getCred('mean-mail', 'username') || 'MAILER_EMAIL_ID', + pass: getCred('mean-mail', 'password') || 'MAILER_PASSWORD' + } + } + } +}; \ No newline at end of file diff --git a/manifest.yml b/manifest.yml new file mode 100644 index 0000000000..9f732b7b42 --- /dev/null +++ b/manifest.yml @@ -0,0 +1,13 @@ +--- +declared-services: + mean-mongo: + label: mongolab + plan: sandbox +applications: +- name: mean + host: mean-${random-word} + memory: 128M + services: + - mean-mongo + env: + NODE_ENV: cloud-foundry \ No newline at end of file diff --git a/package.json b/package.json index 24ecb6a4dc..62049a76d4 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,8 @@ "serve-favicon": "^2.3.0", "socket.io": "^1.3.5", "swig": "^1.4.2", - "validator": "^3.41.2" + "validator": "^3.41.2", + "cfenv": "~1.0.0" }, "devDependencies": { "grunt-concurrent": "^2.0.0",