Improve environment variable stuff

This commit is contained in:
Jonathan Cremin 2015-08-30 18:35:05 +02:00
parent 760ee07a2e
commit 6ba174cff0
16 changed files with 66 additions and 64 deletions

24
.env.example Normal file
View file

@ -0,0 +1,24 @@
export DEBUG="hostr*"
export NODE_ENV=development
export PORT=4040
export WEB_BASE_URL=http://localhost:$PORT
export API_BASE_URL=http://localhost:$PORT/api
export UPLOAD_STORAGE_PATH=$HOME/.hostr/uploads
export COOKIE_KEY=INSECURE
export EMAIL_FROM=
export EMAIL_NAME=
export STATSD_HOST=localhost
export MONGO_URL=mongodb://localhost:27017/hostr
export REDIS_URL=redis://localhost:6379
export MANDRILL_KEY=
export STRIPE_SECRET_KEY=
export STRIPE_PUBLIC_KEY=
# optional, some functionality will be disabled
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export AWS_BUCKET=
export VIRUSTOTAL_KEY=
export SENTRY_DSN=

View file

@ -19,39 +19,11 @@ You'll need `graphicsmagick` for image thumbnailing, everything else is taken ca
### Enviroment Variable Configuration
`AWS_ACCESS_KEY_ID`
`AWS_SECRET_ACCESS_KEY`
`AWS_BUCKET`
`MANDRILL_KEY`
`EMAIL_FROM` - defaults to `nobody@example.com`
`REDIS_URL` - defaults to `redis://localhost:6379`
`MONGO_URL` - defaults to `mongodb://localhost:27017/hostr`
`LOCAL_PATH` - defaults to `~/.hostr/uploads`.
`BASE_URL` - defaults to `https://localhost:4040`
`FILE_HOST` - used by API for absolute file urls, defaults to `$BASE_URL`
`API_URL` - defaults to `/api`
`PORT` - defaults to `4040`.
`VIRUSTOTAL` - API key enables Virustotal integration.
`SENTRY_DSN` - DSN enables Sentry integration.
Additionally, Hostr uses [debug](https://github.com/visionmedia/debug) so you can use the `DEBUG` environment variable something like `DEBUG=hostr*` to get debug output.
See [`.env.example`](.env.example). Copy it to `.env`, modify and `source .env` for development. [autoenv](https://github.com/kennethreitz/autoenv) is pretty nice for doing this automatically when you `cd` into your work directory.
### Deploying to Heroku
Because it uses iojs and graphicsmagick runtimes hostr needs an env variable for `BUILDPACK_URL` set to `https://github.com/ddollar/heroku-buildpack-multi.git`.
Because it uses iojs and graphicsmagick runtimes hostr needs an env variable for `BUILDPACK_URL` set to `https://github.com/ddollar/heroku-buildpack-multi.git` on Heroku.
You'll also need to add Heroku Redis and a MongoDB addon.
@ -65,6 +37,14 @@ $ npm start
This will install and build the frontend too.
Alternatively
```
$ npm run watch
```
Will watch your JS and CSS for changes, rebuild them, and reload the server.
### Run the tests
```

View file

@ -10,7 +10,7 @@ const debug = debugname('hostr-api');
const router = new Router();
const statsdOpts = {prefix: 'hostr-api', host: process.env.STATSD_HOST || 'localhost'};
const statsdOpts = {prefix: 'hostr-api', host: process.env.STATSD_HOST};
router.use(stats(statsdOpts));
const statsd = new StatsD(statsdOpts);
router.use(function* statsMiddleware(next) {

View file

@ -13,11 +13,11 @@ import { formatFile } from '../../lib/format';
import debugname from 'debug';
const debug = debugname('hostr-api:file');
const redisUrl = process.env.REDIS_URL || process.env.REDISTOGO_URL || 'redis://localhost:6379';
const redisUrl = process.env.REDIS_URL;
const fileHost = process.env.FILE_HOST || 'http://localhost:4040';
const baseURL = process.env.WEB_BASE_URL;
const storePath = process.env.STORE_PATH || path.join(process.env.HOME, '.hostr', 'uploads');
const storePath = process.env.UPLOAD_STORAGE_PATH;
export function* post(next) {
if (!this.request.is('multipart/*')) {
@ -60,7 +60,7 @@ export function* post(next) {
const fileId = yield hostrId(Files);
// Fire an event to let the frontend map the GUID it sent to the real ID. Allows immediate linking to the file
const acceptedEvent = `{"type": "file-accepted", "data": {"id": "${fileId}", "guid": "${tempGuid}", "href": "${fileHost}/${fileId}"}}`;
const acceptedEvent = `{"type": "file-accepted", "data": {"id": "${fileId}", "guid": "${tempGuid}", "href": "${baseURL}/${fileId}"}}`;
this.redis.publish('/user/' + this.user.id, acceptedEvent);
this.statsd.incr('file.upload.accepted', 1);
@ -173,7 +173,7 @@ export function* post(next) {
this.status = 201;
this.body = formattedFile;
if (process.env.VIRUSTOTAL) {
if (process.env.VIRUSTOTAL_KEY) {
// Check in the background
process.nextTick(function* malwareScan() {
debug('Malware Scan');

View file

@ -6,7 +6,7 @@ import passwords from 'passwords';
import debugname from 'debug';
const debug = debugname('hostr-api:user');
const redisUrl = process.env.REDIS_URL || process.env.REDISTOGO_URL || 'redis://localhost:6379';
const redisUrl = process.env.REDIS_URL;
export function* get() {
this.body = this.user;

4
app.js
View file

@ -17,8 +17,10 @@ import web from './web/app';
import debugname from 'debug';
const debug = debugname('hostr');
debug(process.env.COOKIE_KEY);
const app = websockify(koa());
app.keys = [process.env.KEYS || 'INSECURE'];
app.keys = [process.env.COOKIE_KEY];
if (process.env.SENTRY_DSN) {
const ravenClient = new raven.Client(process.env.SENTRY_DSN);

View file

@ -1,7 +1,7 @@
import moment from 'moment';
import { sniff } from './type';
const fileHost = process.env.FILE_HOST || 'http://localhost:4040';
const baseURL = process.env.WEB_BASE_URL;
export function formatDate(timestamp) {
return moment.unix(timestamp).format('D MMM YY [at] h:mm A');
@ -25,7 +25,7 @@ export function formatFile(file) {
added: moment.unix(file.time_added).format(),
readableAdded: formatDate(file.time_added),
downloads: file.downloads !== undefined ? file.downloads : 0,
href: fileHost + '/' + file._id, // eslint-disable-line no-underscore-dangle
href: baseURL + '/' + file._id, // eslint-disable-line no-underscore-dangle
id: file._id, // eslint-disable-line no-underscore-dangle
name: file.file_name,
size: file.file_size,
@ -40,8 +40,8 @@ export function formatFile(file) {
formattedFile.width = file.width;
const ext = (file.file_name.split('.').pop().toLowerCase() === 'psd' ? '.png' : '');
formattedFile.direct = {
'150x': fileHost + '/file/150/' + file._id + '/' + file.file_name + ext, // eslint-disable-line no-underscore-dangle
'970x': fileHost + '/file/970/' + file._id + '/' + file.file_name + ext, // eslint-disable-line no-underscore-dangle
'150x': baseURL + '/file/150/' + file._id + '/' + file.file_name + ext, // eslint-disable-line no-underscore-dangle
'970x': baseURL + '/file/970/' + file._id + '/' + file.file_name + ext, // eslint-disable-line no-underscore-dangle
};
}
return formattedFile;

View file

@ -1,6 +1,6 @@
import virustotal from 'virustotal.js';
virustotal.setKey(process.env.VIRUSTOTAL);
virustotal.setKey(process.env.VIRUSTOTAL_KEY);
const extensions = ['EXE', 'PIF', 'APPLICATION', 'GADGET', 'MSI', 'MSP', 'COM', 'SCR', 'HTA', 'CPL', 'MSC',
'JAR', 'BAT', 'CMD', 'VB', 'VBS', 'VBE', 'JS', 'JSE', 'WS', 'WSF', 'WSC', 'WSH', 'PS1', 'PS1XML', 'PS2',

View file

@ -3,11 +3,9 @@ const MongoClient = mongodb().MongoClient;
import debugname from 'debug';
const debug = debugname('hostr:mongo');
const uristring = process.env.MONGO_URL || process.env.MONGOLAB_URI || 'mongodb://localhost:27017/hostr';
const configuredClient = new Promise((resolve, reject) => {
debug('Connecting to Mongodb');
return MongoClient.connect(uristring).then((client) => {
return MongoClient.connect(process.env.MONGO_URL).then((client) => {
debug('Successfully connected to Mongodb');
client.Users = client.collection('users');
client.Files = client.collection('files');

View file

@ -5,7 +5,7 @@ import session from 'koa-generic-session';
import debugname from 'debug';
const debug = debugname('hostr:redis');
const redisUrl = process.env.REDIS_URL || process.env.REDISTOGO_URL || 'redis://localhost:6379';
const redisUrl = process.env.REDIS_URL;
const connection = new Promise((resolve, reject) => {
debug('Connecting to Redis');

View file

@ -3,17 +3,15 @@ import s3UploadStream from 's3-upload-stream';
import debugname from 'debug';
const debug = debugname('hostr:s3');
const bucket = process.env.AWS_BUCKET || 'hostrdotcodev';
const s3 = new aws.S3();
const s3Stream = s3UploadStream(s3);
export function get(key) {
debug('fetching file: %s', 'hostr_files/' + key);
return s3.getObject({Bucket: bucket, Key: 'hostr_files/' + key}).createReadStream();
debug('fetching from s3: %s', 'hostr_files/' + key);
return s3.getObject({Bucket: process.env.AWS_BUCKET, Key: 'hostr_files/' + key}).createReadStream();
}
export function upload(key) {
debug('Uploading file: %s', 'hostr_files/' + key);
return s3Stream.upload({Bucket: bucket, Key: 'hostr_files/' + key});
debug('sending to s3: %s', 'hostr_files/' + key);
return s3Stream.upload({Bucket: process.env.AWS_BUCKET, Key: 'hostr_files/' + key});
}

View file

@ -9,7 +9,7 @@ function range(start, stop) {
return result;
}
const storePath = process.env.FILE_PATH || path.join(process.env.HOME, '.hostr', 'uploads');
const storePath = process.env.UPLOAD_STORAGE_PATH;
const directories = range('A', 'Z').concat(range('a', 'z'), range('0', '9'));

View file

@ -16,7 +16,7 @@ const router = new Router();
router.use(errors({template: path.join(__dirname, 'public', 'error.html')}));
const statsdOpts = {prefix: 'hostr-web', host: process.env.STATSD_HOST || 'localhost'};
const statsdOpts = {prefix: 'hostr-web', host: process.env.STATSD_HOST};
router.use(stats(statsdOpts));
const statsd = new StatsD(statsdOpts);
router.use(function* statsMiddleware(next) {
@ -29,8 +29,8 @@ router.use(redis.sessionStore());
router.use(function* stateMiddleware(next) {
this.state = {
session: this.session,
apiURL: process.env.API_URL,
baseURL: process.env.BASE_URL,
baseURL: process.env.WEB_BASE_URL,
apiURL: process.env.API_BASE_URL,
stripePublic: process.env.STRIPE_PUBLIC_KEY,
};
yield next;

View file

@ -94,11 +94,11 @@ export function* signup(email, password, ip) {
};
Users.insertOne(user);
const html = yield render('email/inlined/activate', {activationUrl: process.env.BASE_URL + '/activate/' + user.activationCode});
const html = yield render('email/inlined/activate', {activationUrl: process.env.WEB_BASE_URL + '/activate/' + user.activationCode});
const text = `Thanks for signing up to Hostr!
Please confirm your email address by clicking the link below.
${process.env.BASE_URL + '/activate/' + user.activationCode}
${process.env.WEB_BASE_URL + '/activate/' + user.activationCode}
Jonathan Cremin, Hostr Founder
`;
@ -130,9 +130,9 @@ export function* sendResetToken(email) {
'token': token,
'created': Math.round(new Date().getTime() / 1000),
});
const html = yield render('email/inlined/forgot', {forgotUrl: process.env.BASE_URL + '/forgot/' + token});
const html = yield render('email/inlined/forgot', {forgotUrl: process.env.WEB_BASE_URL + '/forgot/' + token});
const text = `It seems you've forgotten your password :(
Visit ${process.env.BASE_URL + '/forgot/' + token} to set a new one.
Visit ${process.env.WEB_BASE_URL + '/forgot/' + token} to set a new one.
`;
mandrill.messages.send({message: {
html: html,

View file

@ -3,7 +3,7 @@ import mime from 'mime-types';
import hostrFileStream from '../../lib/hostr-file-stream';
import { formatFile } from '../../lib/format';
const storePath = process.env.STORE_PATH || path.join(process.env.HOME, '.hostr', 'uploads');
const storePath = process.env.UPLOAD_STORAGE_PATH;
function userAgentCheck(userAgent) {
if (!userAgent) {

View file

@ -6,8 +6,8 @@ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
import { Mandrill } from 'mandrill-api/mandrill';
const mandrill = new Mandrill(process.env.MANDRILL_KEY);
const fromEmail = process.env.EMAIL_FROM || 'nobody@example.com';
const fromName = process.env.EMAIL_NAME || 'Nobody';
const fromEmail = process.env.EMAIL_FROM;
const fromName = process.env.EMAIL_NAME;
export function* create() {
const Users = this.db.Users;