Skip to content

Commit

Permalink
deploy on stackato (fixes mozilla#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
cvan committed Mar 11, 2014
1 parent e5e468e commit f696837
Show file tree
Hide file tree
Showing 9 changed files with 255 additions and 21 deletions.
17 changes: 7 additions & 10 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
*.deflate
*.egg-info
*.elc
*.gz
*.less.css
*.po.js
*.pyc
Expand All @@ -15,30 +17,25 @@
.emacs.d/site/nxhtml
.emacs.d/tramp
.emacs.desktop
.ipython
.node-version
.virtualenvs
.zsh/cache
TAGS
build_*
dist
locale/
node_modules
npm-debug.log
settings_local.js
settings_local_hosted.js
smokealarm/captures/
tags
yulelog_*
.node-version
settings_local.py

locale/
src/locales/*
src/media/build_id.txt
src/media/locales/*
src/media/css/include.css
src/media/css/include.css
src/media/imgurls.txt
src/media/include.css
src/media/include.js
src/media/js/include.js
src/media/locales/*
src/templates.js
settings_local.js
tags
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,31 @@ To infinity and beyond.
npm install commonplace -g
# Copy local configuration into place
cp src/media/js/settings_local.js.dist src/media/js/settings_local.js
# Copy production configuration into place
cp src/media/js/settings_local_hosted.js.dist src/media/js/settings_local_hosted.js
# Start the server
damper
```


## Deployment

We use stackato:

stackato push --no-prompt

To start the instance on stackato:

stackato start

To read the logs on stackato:

stackato logs

To run shell commands on stackato:

stackato run cat ../logs/stdout.log

To access the shell on stackato:

stackato ssh
135 changes: 135 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
var fs = require('fs');
var http = require('http');
var zlib = require('zlib');

var nodeStatic = require('node-static');


const SERVER_HTML = '/server.html';
const REWRITES = [
{from: '^/([\?].*)?$', to: SERVER_HTML},
{from: '^/(friends|submit|game|genre|user|settings|leaderboard|developer|review|tests|debug)([\?].*)?$', to: SERVER_HTML},
];
const STRIP_TRAILING_SLASHES = true;
const TEMPLATE_404 = SERVER_HTML;


function patchVaryHeader(headers, header) {
var v = headers['Vary'];
return headers['Vary'] = (v && v !== header ? v + ', ' : '') + header;
}

/* Check if we should consider sending a deflate version of the file based on the
* file content type and client's Accept-Encoding header value.
*/
nodeStatic.Server.prototype.deflateOk = function(req, contentType) {
var enable = this.options.deflate;
if (enable &&
(typeof enable === 'boolean' ||
(contentType && enable instanceof RegExp &&
enable.test(contentType)))) {
var acceptEncoding = req.headers['accept-encoding'];
return acceptEncoding && acceptEncoding.indexOf('deflate') >= 0;
}
return false;
};

/* Monkeypatching `node-static`'s gzip so we can do it on the fly and also
* support deflate (which results in smaller responses).
*/
nodeStatic.Server.prototype.respondGzip = function(pathname, status,
contentType, _headers,
files, stat, req, res,
finish) {
var that = this;
var gzipOk = that.gzipOk(req, contentType);
var deflateOk = that.deflateOk(req, contentType);
if (!(files.length === 1 && (gzipOk || deflateOk))) {
// Client doesn't want deflate/gzip or we're sending multiple files.
return that.respondNoGzip(pathname, status, contentType, _headers, files,
stat, req, res, finish);
}

var compFile;
var compLib;

if (deflateOk) {
compFile = files[0] + '.deflate';
compLib = zlib.createDeflate();
_headers['Content-Encoding'] = 'deflate';
} else {
compFile = files[0] + '.gz';
compLib = zlib.createGzip();
_headers['Content-Encoding'] = 'gzip';
}

var inStr = fs.createReadStream(files[0]);
var outStr = fs.createWriteStream(compFile);

patchVaryHeader(_headers, 'Accept-Encoding');

inStr.pipe(compLib).pipe(outStr);

outStr.on('close', function() {
fs.stat(compFile, function(e, stat) {
that.respondNoGzip(pathname, status, contentType, _headers, [compFile],
stat, req, res, finish);
});
});
};

var fileServer = new nodeStatic.Server('./src', {
// TODO: Set a reasonable `max-age` (issue #41).
cache: 0,
deflate: true,
gzip: true
});


function getRewrite(req, stripslashes) {
var data = {headers: {}};
REWRITES.forEach(function(rewrite) {
var re = new RegExp(rewrite.from);
if (re.test(req.url)) {
if (rewrite.redirect) {
data.headers['Location'] = data.path;
data.statusCode = rewrite.redirect === 'permanent' ? 301 : 302;
} else {
data.statusCode = 200;
}
data.path = rewrite.to;
} else if (stripslashes && req.url.substr(-1) === '/') {
var slashlessUrl = req.url.substr(0, req.url.length - 1);
if (re.test(slashlessUrl)) {
data.headers['Location'] = slashlessUrl;
data.statusCode = 302;
}
}
});
return data;
}

http.createServer(function (req, res) {
req.addListener('end', function () {
if (req.url === '/') {
req.url = SERVER_HTML;
}
fileServer.serve(req, res, function(err, fileRes) {
var rewrite = getRewrite(req, STRIP_TRAILING_SLASHES);
if (rewrite.path) {
fileServer.serveFile(rewrite.path, rewrite.statusCode,
rewrite.headers, req, res);
} else if (rewrite.statusCode) {
res.writeHead(rewrite.statusCode, rewrite.headers);
res.end();
} else if (err && err.status === 404) {
if (TEMPLATE_404) {
fileServer.serveFile(TEMPLATE_404, 404, {}, req, res);
} else {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end('404');
}
}
});
}).resume();
}).listen(process.env.PORT || 9000);
12 changes: 12 additions & 0 deletions deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash

COMMONPLACE=./node_modules/commonplace/bin/commonplace

find . -name 'src/*.deflate' -delete
find . -name 'src/*.gz' -delete

npm install
npm install --force [email protected]

$COMMONPLACE includes
$COMMONPLACE langpacks
18 changes: 18 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "galaxy",
"version": "0.0.1",
"engines": {
"node": ">=0.10.x",
"npm": ">=1.1.x"
},
"repository": {
"type": "git",
"url": "git://github.com/cvan/galaxy.git"
},
"dependencies": {
"node-static": "latest"
},
"scripts": {
"start": "node app.js"
}
}
8 changes: 0 additions & 8 deletions src/media/js/settings_local_hosted.js

This file was deleted.

4 changes: 1 addition & 3 deletions src/media/js/settings_local_hosted.js.dist
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
define('settings_local', [], function() {
// Use this module for settings to be used in production.
var origin = window.location.origin || (
window.location.protocol + '//' + window.location.host);
return {
api_url: origin
api_url: 'https://galaxy-api.paas.allizom.org'
};
});
39 changes: 39 additions & 0 deletions src/server.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<title>Mozilla Galaxy</title>
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Electrolize">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600,700,900,200italic,300italic,400italic,600italic,700italic,900italic" type="text/css">
<link rel="stylesheet" href="/media/css/include.css">
</head>
<body class="home" data-media="/media/">
<noscript><p>Sorry, you need JavaScript to use this site.</p></noscript>
<div id="splash-overlay"><div class="throbber"></div></div>

<header id="site-header" class="header site-header"></header>

<div class="cloak"></div>
<main>
<div id="page" class="page" role="main"></div>
</main>

<footer id="site-footer" class="site-footer"></footer>

<!-- screenshot lightbox -->
<div id="lightbox">
<section>
<ul class="content"></ul>
<a class="close" href="#">&times;</a>
</section>
</div>

<script src="https://login.persona.org/include.js"></script>
<!-- TODO: Make Aviary load as `async` -->
<script src="https://dme0ih8comzn4.cloudfront.net/js/feather.js"></script>
<script src="/media/js/l10n.js"></script>
<script src="//platform.twitter.com/widgets.js" async></script>
<script src="/media/js/include.js"></script>
</body>
</html>
18 changes: 18 additions & 0 deletions stackato.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: galaxy

instances: 1

framework:
type: node
runtime: node010

mem: 64

hooks:
pre-push:
- ./deploy.sh

processes:
web: npm start

ignores: [".git", "node_modules/*"]

0 comments on commit f696837

Please sign in to comment.