From bab392830d2e229fd552173c0f817be37a7473a3 Mon Sep 17 00:00:00 2001 From: Olivier Corradi Date: Fri, 30 Dec 2016 01:23:39 +0100 Subject: [PATCH] Proper creation of styles assets and production update for 0 downtime asset serving --- docker-compose.yml | 2 +- production_gce.yml | 3 +++ web/.dockerignore | 3 +++ web/package.json | 5 ++--- web/server.js | 9 +++------ web/views/pages/index.ejs | 1 - web/webpack.config.js | 11 ++++++++++- 7 files changed, 22 insertions(+), 12 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9ccfc8f48c..534af2f747 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '2' services: web: build: web - command: ./node_modules/.bin/nodemon server.js + command: npm run server-dev depends_on: [mongo, memcached] environment: - ENV=development diff --git a/production_gce.yml b/production_gce.yml index de49a2ff06..6a02af135b 100644 --- a/production_gce.yml +++ b/production_gce.yml @@ -7,11 +7,14 @@ services: - ENV=production - MEMCACHED_HOST=memcached - MONGO_URL=mongodb://mongo:27017/electricity + - STATIC_PATH=/opt/static - VIRTUAL_HOST=electricitymap.tmrow.co image: eu.gcr.io/tmrow-152415/electricitymap_web:production mem_limit: 100M networks: [default, infrastructure] # required to be able to com' with statsd & nginx restart: unless-stopped + volumes: + - /home/shared/electricitymap/static/dist:/opt/static/dist feeder: depends_on: [mongo] env_file: [./mailgun.env, ./secrets.env] diff --git a/web/.dockerignore b/web/.dockerignore index 3c3629e647..6339961aef 100644 --- a/web/.dockerignore +++ b/web/.dockerignore @@ -1 +1,4 @@ +build node_modules +public/dist +world_*.json diff --git a/web/package.json b/web/package.json index 1322b641c3..e0550a214a 100644 --- a/web/package.json +++ b/web/package.json @@ -18,7 +18,6 @@ "topojson": "^2.2.0" }, "devDependencies": { - "clean-webpack-plugin": "^0.1.14", "nodemon": "^1.10.2", "webpack": "^1.13.3" }, @@ -27,11 +26,11 @@ "url": "https://github.com/corradio/electricitymap.git" }, "scripts": { - "build": "webpack", + "build": "webpack --bail", "build-debug": "BUILD=debug npm run build", "build-release": "BUILD=release npm run build", "clean": "mkdir -p public/dist && rm public/dist/bundle.*.js", "server-dev": "nodemon server.js", - "watch": "BUILD=debug webpack --watch --progress" + "watch": "BUILD=debug webpack --watch --progress --bail" } } diff --git a/web/server.js b/web/server.js index 7505a91f2f..721b05c3ac 100644 --- a/web/server.js +++ b/web/server.js @@ -31,10 +31,11 @@ app.use(compression()); // Cloudflare already does gzip but we do it anyway app.disable('etag'); // Disable etag generation (except for static) // * Static and templating -app.use(express.static(__dirname + '/public', {etag: true, maxAge: isProduction ? '24h': '0'})); +var STATIC_PATH = process.env['STATIC_PATH'] || (__dirname + '/public'); +app.use(express.static(STATIC_PATH, {etag: true, maxAge: isProduction ? '24h': '0'})); app.set('view engine', 'ejs'); var BUNDLE_HASH = !isProduction ? 'dev' : - JSON.parse(fs.readFileSync('public/dist/manifest.json')).hash; + JSON.parse(fs.readFileSync(STATIC_PATH + '/dist/manifest.json')).hash; // * Cache var memcachedClient = new Memcached(process.env['MEMCACHED_HOST']); @@ -543,10 +544,6 @@ app.get('/health', function(req, res) { } }); }); -app.get(`/dist/styles.${BUNDLE_HASH}.css`, function(req, res) { - res.setHeader('Cache-Control', 'public, max-age=' + (isProduction ? '86400' : '0')); - res.sendFile(__dirname + '/public/css/styles.css'); -}); app.get('/', function(req, res) { res.render('pages/index', { 'bundleHash': BUNDLE_HASH, diff --git a/web/views/pages/index.ejs b/web/views/pages/index.ejs index 43ea239b79..debe64a8fc 100644 --- a/web/views/pages/index.ejs +++ b/web/views/pages/index.ejs @@ -21,7 +21,6 @@ - diff --git a/web/webpack.config.js b/web/webpack.config.js index 6bfd15b550..14b5b04bf6 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -1,4 +1,5 @@ var webpack = require('webpack'); +var fs = require('fs'); module.exports = { devtool: (process.env.BUILD === 'debug' ? 'eval' : 'sourcemap'), @@ -13,7 +14,15 @@ module.exports = { }), function() { this.plugin('done', function(stats) { - require('fs').writeFileSync( + fs.createReadStream(__dirname + '/public/css/styles.css') + .pipe(fs.createWriteStream( + __dirname + '/public/dist/styles.' + + (process.env.BUILD === 'debug' ? 'dev' : stats.hash) + '.css')); + }); + }, + function() { + this.plugin('done', function(stats) { + fs.writeFileSync( __dirname + '/public/dist/manifest.json', JSON.stringify(stats.toJson())); });