Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Deploying a
location-aware EmberJS app
Ben Limmer
EmberJS Denver Meetup
5/27/2015
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
deployment can be
scary
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
!==
Dev/Staging Production
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
data/servers can differ
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
data/servers can differ
db sharding
mini/uglification
caching
latency
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
us testing
>
users testing
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
dev/qa/stakeholder testing in prod
>
users testing in prod
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
enter ember-cli-deploy
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
– Michael Klein
“Lightning Fast Deployments of Ember-CLI
Apps”
LevelbossM...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
– Ben Limmer
“Easy, Lightning Fast, Sleep-Better-at-Night,
Deployments of...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
how does it work?
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
“abc123”: “<html>...</html>”
what’s current?
contents of abc123
example.o...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
“def456”: “<html>...</html>”
app-hash.css, app-hash.js, ...
what’s curren...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
“def456”: “<html>...</html>”
what’s def456?
contents of def456
“abc123”: ...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
“def456”: “<html>...</html>”
what’s current?
contents of def456
“abc123”:...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
💩!
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
“def456”: “<html>...</html>”
what’s current?
contents of abc123
“abc123”:...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
demo project
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
Español English
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
ip address mexican user
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
ember-cli-server-variables
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
Client Stack
• EmberJS 1.12
• ember-i18n
• ember-cli-deploy (redis + s3 a...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
client code
ember-cli-server-variables
config/environment.js
1 module.exports = function(environment) {
2 var ENV = {
3 modulePrefix: '...
session initialization
1 export default Ember.Service.extend({
2 serverVariables: Ember.inject.service(),
3
4 countryCode:...
app initialization
app/routes/application.js
1 export default Ember.Route.extend({
2 i18n: Ember.inject.service(),
3 sessi...
languageForCountryCode
app/utils/language-for-country-code.js
1 export default function languageForCountryCode(countryCode...
translations (en)
app/locales/en/translations.js
1 export default {
2 'home': {
3 'greeting': 'Hello!',
4 'secondaryGreeti...
translations (es)
app/locales/es/translations.js
1 export default {
2 'home': {
3 'greeting': ‘¡Hola!',
4 'secondaryGreeti...
template
app/templates/index.hbs
1 <div class='row'>
2 <h2 class='text-center' id="greeting">
3 {{t 'home.greeting'}}
4 </...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
demo
Server Stack
Hosting
• heroku
• heroku-redis
Server Tech
• express 4
• geoip-lite
• redis
• cheerio
• node-ember-cli-
depl...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
server code
server routing
index.js
1 app.get('/', function(req, res) {
2 nodeEmberCliDeployRedis.
3 fetchIndex(‘location-aware-ember’...
inject server variables
lib/server-var-inject-helper.js
1 var injectServerVariables = function (htmlString, req) {
2 var $...
geocode ip address
lib/location-helper.js
1 var getCountry = function (req) {
2 var ipAddr = req.headers["x-forwarded-for"...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
running in prod
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
feature request:
change locale in realtime
git diff
++app/templates/index.hbs
1 <div class='row language-chooser'>
2 <h6>{{t 'home.chooseLang'}}</h6>
3 <a id='set-en...
git diff
++app/routes/application.js
1 export default Ember.Route.extend({
2 i18n: Ember.inject.service(),
3 ...
4 actions...
deloyment config
config/deploy.js
1 module.exports = {
2 "production": {
3 buildEnv: "production",
4 store: {
5 host: 'ec2-1...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
demo
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
thank you!
blimmer
l1m5
hello@benlimmer.com
ember.party
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
demo project code
• location-aware-ember
• location-aware-ember-server
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
demo project libs (client)
• ember-cli-deploy
• s3 adapter
• redis adapte...
Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
demo project libs (server)
• express js
• geoip-lite
• redis
• cheerio
• ...
Upcoming SlideShare
Loading in …5
×

Deploying a Location-Aware Ember Application

7,876 views

Published on

Learn how to deploy a location aware EmberJS application to heroku. This presentation explains how to use ember-cli-deploy along with heroku redis and s3 to create an application that dynamically changes the internationalization translation based on what country you're visiting the site from. Also uses ember-cli-server-variables, ember-i18n, node-ember-cli-deploy-redis, cheeriojs, and ember-cli.

Published in: Technology
  • Login to see the comments

Deploying a Location-Aware Ember Application

  1. 1. Deploying a location-aware EmberJS app Ben Limmer EmberJS Denver Meetup 5/27/2015
  2. 2. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party deployment can be scary
  3. 3. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party !== Dev/Staging Production
  4. 4. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party data/servers can differ
  5. 5. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party data/servers can differ db sharding mini/uglification caching latency
  6. 6. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
  7. 7. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party us testing > users testing
  8. 8. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party dev/qa/stakeholder testing in prod > users testing in prod
  9. 9. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
  10. 10. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party enter ember-cli-deploy
  11. 11. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party – Michael Klein “Lightning Fast Deployments of Ember-CLI Apps” LevelbossMike
  12. 12. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party – Ben Limmer “Easy, Lightning Fast, Sleep-Better-at-Night, Deployments of Ember-CLI Apps” blimmer
  13. 13. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party how does it work?
  14. 14. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
  15. 15. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party “abc123”: “<html>...</html>” what’s current? contents of abc123 example.org “current”: “abc123”
  16. 16. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party “def456”: “<html>...</html>” app-hash.css, app-hash.js, ... what’s current? contents of abc123 “abc123”: “<html>...</html>” example.org “current”: “abc123”
  17. 17. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party “def456”: “<html>...</html>” what’s def456? contents of def456 “abc123”: “<html>...</html>” example.org/? secret=def456 “current”: “abc123”
  18. 18. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party “def456”: “<html>...</html>” what’s current? contents of def456 “abc123”: “<html>...</html>” example.org “current”: “def456”
  19. 19. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party 💩!
  20. 20. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party “def456”: “<html>...</html>” what’s current? contents of abc123 “abc123”: “<html>...</html>” example.org “current”: “abc123”
  21. 21. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party demo project
  22. 22. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party Español English
  23. 23. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
  24. 24. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party
  25. 25. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party ip address mexican user
  26. 26. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party ember-cli-server-variables
  27. 27. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party Client Stack • EmberJS 1.12 • ember-i18n • ember-cli-deploy (redis + s3 adapters) • ember-cli-server-variables
  28. 28. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party client code
  29. 29. ember-cli-server-variables config/environment.js 1 module.exports = function(environment) { 2 var ENV = { 3 modulePrefix: 'location-aware-ember', 4 5 serverVariables: { 6 tagPrefix: 'var', 7 vars: ['country'] 8 } 9 }; 10 11 if (environment === 'development') { 12 ENV.serverVariables.defaults = { 13 'country': 'US' 14 }; 15 } 16 }
  30. 30. session initialization 1 export default Ember.Service.extend({ 2 serverVariables: Ember.inject.service(), 3 4 countryCode: 'US', 5 6 forceInitialization: function () { 7 const country = this.get('serverVariables.country'); 8 if (country) { 9 this.set('countryCode', country); 10 } 11 } 12 }); app/services/session.js
  31. 31. app initialization app/routes/application.js 1 export default Ember.Route.extend({ 2 i18n: Ember.inject.service(), 3 session: Ember.inject.service(), 4 5 beforeModel: function () { 6 this.set( 7 'i18n.locale', 8 languageForCountryCode(this.get('session.countryCode')) 9 ); 10 } 11 });
  32. 32. languageForCountryCode app/utils/language-for-country-code.js 1 export default function languageForCountryCode(countryCode) { 2 switch(countryCode.toLowerCase()) { 3 case 'es': 4 case 'mx': 5 return 'es'; 6 case 'gb': 7 case 'us': 8 return 'en'; 9 default: 10 return 'en'; 11 } 12 }
  33. 33. translations (en) app/locales/en/translations.js 1 export default { 2 'home': { 3 'greeting': 'Hello!', 4 'secondaryGreeting': 'Thank you for visiting from {{countryName}}.' 5 } 6 };
  34. 34. translations (es) app/locales/es/translations.js 1 export default { 2 'home': { 3 'greeting': ‘¡Hola!', 4 'secondaryGreeting': 'Gracias por visitar desde {{countryName}}.' 5 } 6 };
  35. 35. template app/templates/index.hbs 1 <div class='row'> 2 <h2 class='text-center' id="greeting"> 3 {{t 'home.greeting'}} 4 </h2> 5 </div> 6 <div class='row'> 7 <h4 class='text-center' id="secondary-greeting"> 8 {{t 'home.secondaryGreeting' countryName=countryName}} 9 </h4> 10 </div>
  36. 36. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party demo
  37. 37. Server Stack Hosting • heroku • heroku-redis Server Tech • express 4 • geoip-lite • redis • cheerio • node-ember-cli- deploy-redis
  38. 38. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party server code
  39. 39. server routing index.js 1 app.get('/', function(req, res) { 2 nodeEmberCliDeployRedis. 3 fetchIndex(‘location-aware-ember’, req, client). 4 then(function (indexHtml) { 5 indexHtml = serverVarInjectHelper. 6 injectServerVariables(indexHtml, req); 7 res.status(200).send(indexHtml); 8 }).catch(function(err) { 9 res.status(500).send('Oh noes!n' + err.message); 10 }); 11 });
  40. 40. inject server variables lib/server-var-inject-helper.js 1 var injectServerVariables = function (htmlString, req) { 2 var $ = cheerio.load(htmlString); 3 $('meta[name=var-country]'). 4 attr('content', locationHelper.getCountry(req)); 5 6 return $.html(); 7 };
  41. 41. geocode ip address lib/location-helper.js 1 var getCountry = function (req) { 2 var ipAddr = req.headers["x-forwarded-for"]; 3 if (ipAddr){ 4 var list = ipAddr.split(","); 5 ipAddr = list[list.length-1]; 6 } else { 7 ipAddr = req.connection.remoteAddress; 8 } 9 10 var geo = geoip.lookup(ipAddr); 11 12 if (geo && geo.country) { 13 return geo.country; 14 } else { 15 return 'US'; 16 } 17 };
  42. 42. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party running in prod
  43. 43. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party feature request: change locale in realtime
  44. 44. git diff ++app/templates/index.hbs 1 <div class='row language-chooser'> 2 <h6>{{t 'home.chooseLang'}}</h6> 3 <a id='set-en' {{action 'setLanguage' 'en'}}>EN</a> 4 <a id='set-es' {{action 'setLanguage' 'es'}}>ES</a> 5 </div>
  45. 45. git diff ++app/routes/application.js 1 export default Ember.Route.extend({ 2 i18n: Ember.inject.service(), 3 ... 4 actions: { 5 setLanguage: function (locale) { 6 this.set('i18n.locale', locale); 7 } 8 } 9 });
  46. 46. deloyment config config/deploy.js 1 module.exports = { 2 "production": { 3 buildEnv: "production", 4 store: { 5 host: 'ec2-107-22-167-67.compute-1.amazonaws.com', 6 port: 6929, 7 password: process.env.REDIS_PW, 8 }, 9 assets: { 10 "type": "s3", 11 "accessKeyId": "AKIAIFM7MT2JTIHV6HBA", 12 "secretAccessKey": process.env.S3_SECRET_ACCESS_KEY, 13 "bucket": "location-aware-ember" 14 } 15 } 16 };
  47. 47. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party demo
  48. 48. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party thank you! blimmer l1m5 hello@benlimmer.com ember.party
  49. 49. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party demo project code • location-aware-ember • location-aware-ember-server
  50. 50. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party demo project libs (client) • ember-cli-deploy • s3 adapter • redis adapter • ember-cli-server-variables • ember-i18n
  51. 51. Ben LimmerEmberJS Meetup - 5/27/2015 ember.party demo project libs (server) • express js • geoip-lite • redis • cheerio • node-ember-cli-deploy-redis

×