From 1165eb39511da27903b08507e8a48c23167eb7bb Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Sat, 1 Apr 2017 19:27:03 +0200 Subject: [PATCH 01/52] Initial commit for v2 --- .gitignore | 5 +- 00-basic-express-generator/.dockerignore | 5 - 00-basic-express-generator/Dockerfile | 13 -- 00-basic-express-generator/README.md | 28 ---- 00-basic-express-generator/app/app.js | 60 -------- 00-basic-express-generator/app/bin/www | 90 ------------ 00-basic-express-generator/app/package.json | 17 --- .../app/public/stylesheets/style.css | 8 -- .../app/routes/index.js | 9 -- .../app/routes/users.js | 9 -- .../app/views/error.jade | 6 - .../app/views/index.jade | 5 - .../app/views/layout.jade | 7 - 00-basic-express-generator/docker-compose.yml | 6 - 01-express-nodemon/.dockerignore | 5 - 01-express-nodemon/Dockerfile | 15 -- 01-express-nodemon/README.md | 37 ----- 01-express-nodemon/app/app.js | 60 -------- 01-express-nodemon/app/bin/www | 9 -- 01-express-nodemon/app/nodemon.json | 6 - 01-express-nodemon/app/package.json | 18 --- 01-express-nodemon/app/public/images/.gitkeep | 0 .../app/public/javascripts/.gitkeep | 0 .../app/public/stylesheets/.gitkeep | 0 .../app/public/stylesheets/style.css | 8 -- 01-express-nodemon/app/routes/index.js | 9 -- 01-express-nodemon/app/routes/users.js | 9 -- 01-express-nodemon/app/views/error.hjs | 3 - 01-express-nodemon/app/views/index.hjs | 11 -- 01-express-nodemon/docker-compose.yml | 6 - 02-express-redis-nodemon/.dockerignore | 5 - 02-express-redis-nodemon/Dockerfile | 15 -- 02-express-redis-nodemon/README.md | 38 ----- 02-express-redis-nodemon/app/app.js | 60 -------- 02-express-redis-nodemon/app/bin/www | 9 -- 02-express-redis-nodemon/app/nodemon.json | 6 - 02-express-redis-nodemon/app/package.json | 19 --- .../app/public/images/.gitkeep | 0 .../app/public/javascripts/.gitkeep | 0 .../app/public/stylesheets/.gitkeep | 0 .../app/public/stylesheets/style.css | 8 -- 02-express-redis-nodemon/app/routes/index.js | 22 --- 02-express-redis-nodemon/app/routes/users.js | 9 -- 02-express-redis-nodemon/app/views/error.hjs | 3 - 02-express-redis-nodemon/app/views/index.hjs | 12 -- 02-express-redis-nodemon/docker-compose.yml | 11 -- 03-express-gulp-watch/.dockerignore | 5 - 03-express-gulp-watch/Dockerfile | 18 --- 03-express-gulp-watch/README.md | 43 ------ 03-express-gulp-watch/app/app.js | 60 -------- 03-express-gulp-watch/app/bin/www | 9 -- 03-express-gulp-watch/app/gulpfile.js | 24 ---- 03-express-gulp-watch/app/package.json | 25 ---- .../app/public/images/.gitkeep | 0 .../app/public/javascripts/.gitkeep | 0 .../app/public/scss/_variables.scss | 4 - .../app/public/scss/style.scss | 11 -- .../app/public/stylesheets/.gitkeep | 0 03-express-gulp-watch/app/routes/index.js | 9 -- 03-express-gulp-watch/app/routes/users.js | 9 -- 03-express-gulp-watch/app/views/error.hjs | 3 - 03-express-gulp-watch/app/views/index.hjs | 11 -- 03-express-gulp-watch/docker-compose.yml | 7 - 04-express-grunt-watch/.dockerignore | 5 - 04-express-grunt-watch/.gitignore | 1 - 04-express-grunt-watch/Dockerfile | 20 --- 04-express-grunt-watch/README.md | 50 ------- 04-express-grunt-watch/app/Gruntfile.js | 66 --------- 04-express-grunt-watch/app/app.js | 60 -------- 04-express-grunt-watch/app/bin/www | 9 -- 04-express-grunt-watch/app/package.json | 25 ---- .../app/public/images/.gitkeep | 0 .../app/public/javascripts/.gitkeep | 0 .../app/public/scss/_variables.scss | 4 - .../app/public/scss/style.scss | 11 -- .../app/public/stylesheets/.gitkeep | 0 .../app/public/stylesheets/style.css | 9 -- .../app/public/stylesheets/style.css.map | 7 - 04-express-grunt-watch/app/routes/index.js | 9 -- 04-express-grunt-watch/app/routes/users.js | 9 -- 04-express-grunt-watch/app/views/error.hjs | 3 - 04-express-grunt-watch/app/views/index.hjs | 11 -- 04-express-grunt-watch/docker-compose.yml | 7 - 05-nginx-express-redis-nodemon/.dockerignore | 5 - 05-nginx-express-redis-nodemon/README.md | 38 ----- 05-nginx-express-redis-nodemon/app/Dockerfile | 11 -- 05-nginx-express-redis-nodemon/app/app.js | 60 -------- 05-nginx-express-redis-nodemon/app/bin/www | 9 -- .../app/nodemon.json | 6 - .../app/package.json | 19 --- .../app/public/images/.gitkeep | 0 .../app/public/javascripts/.gitkeep | 0 .../app/public/stylesheets/.gitkeep | 0 .../app/public/stylesheets/style.css | 8 -- .../app/routes/index.js | 22 --- .../app/routes/users.js | 9 -- .../app/views/error.hjs | 3 - .../app/views/index.hjs | 12 -- .../docker-compose.yml | 24 ---- .../nginx/Dockerfile | 3 - .../nginx/sites-enabled/nodejs_project | 19 --- README.md | 36 +---- bin/builder | 3 + builder.js | 136 ++++++++++++++++++ index.js | 93 ++++++++++++ package.json | 15 ++ templates/common/Dockerfile.mustache | 5 + templates/common/docker/install.mustache | 10 ++ templates/express/docker-compose.yml | 9 ++ templates/express/index.js | 17 +++ templates/express/package.json | 6 + templates/express/site/router.js | 10 ++ templates/express/views/index.mustache | 22 +++ templates/minimal/docker-compose.yml | 9 ++ templates/minimal/index.js | 14 ++ templates/minimal/package.json | 6 + 116 files changed, 360 insertions(+), 1504 deletions(-) delete mode 100644 00-basic-express-generator/.dockerignore delete mode 100644 00-basic-express-generator/Dockerfile delete mode 100644 00-basic-express-generator/README.md delete mode 100644 00-basic-express-generator/app/app.js delete mode 100755 00-basic-express-generator/app/bin/www delete mode 100644 00-basic-express-generator/app/package.json delete mode 100644 00-basic-express-generator/app/public/stylesheets/style.css delete mode 100644 00-basic-express-generator/app/routes/index.js delete mode 100644 00-basic-express-generator/app/routes/users.js delete mode 100644 00-basic-express-generator/app/views/error.jade delete mode 100644 00-basic-express-generator/app/views/index.jade delete mode 100644 00-basic-express-generator/app/views/layout.jade delete mode 100644 00-basic-express-generator/docker-compose.yml delete mode 100644 01-express-nodemon/.dockerignore delete mode 100644 01-express-nodemon/Dockerfile delete mode 100644 01-express-nodemon/README.md delete mode 100644 01-express-nodemon/app/app.js delete mode 100755 01-express-nodemon/app/bin/www delete mode 100644 01-express-nodemon/app/nodemon.json delete mode 100644 01-express-nodemon/app/package.json delete mode 100644 01-express-nodemon/app/public/images/.gitkeep delete mode 100644 01-express-nodemon/app/public/javascripts/.gitkeep delete mode 100644 01-express-nodemon/app/public/stylesheets/.gitkeep delete mode 100644 01-express-nodemon/app/public/stylesheets/style.css delete mode 100644 01-express-nodemon/app/routes/index.js delete mode 100644 01-express-nodemon/app/routes/users.js delete mode 100644 01-express-nodemon/app/views/error.hjs delete mode 100644 01-express-nodemon/app/views/index.hjs delete mode 100644 01-express-nodemon/docker-compose.yml delete mode 100644 02-express-redis-nodemon/.dockerignore delete mode 100644 02-express-redis-nodemon/Dockerfile delete mode 100644 02-express-redis-nodemon/README.md delete mode 100644 02-express-redis-nodemon/app/app.js delete mode 100755 02-express-redis-nodemon/app/bin/www delete mode 100644 02-express-redis-nodemon/app/nodemon.json delete mode 100644 02-express-redis-nodemon/app/package.json delete mode 100644 02-express-redis-nodemon/app/public/images/.gitkeep delete mode 100644 02-express-redis-nodemon/app/public/javascripts/.gitkeep delete mode 100644 02-express-redis-nodemon/app/public/stylesheets/.gitkeep delete mode 100644 02-express-redis-nodemon/app/public/stylesheets/style.css delete mode 100644 02-express-redis-nodemon/app/routes/index.js delete mode 100644 02-express-redis-nodemon/app/routes/users.js delete mode 100644 02-express-redis-nodemon/app/views/error.hjs delete mode 100644 02-express-redis-nodemon/app/views/index.hjs delete mode 100644 02-express-redis-nodemon/docker-compose.yml delete mode 100644 03-express-gulp-watch/.dockerignore delete mode 100644 03-express-gulp-watch/Dockerfile delete mode 100644 03-express-gulp-watch/README.md delete mode 100644 03-express-gulp-watch/app/app.js delete mode 100755 03-express-gulp-watch/app/bin/www delete mode 100644 03-express-gulp-watch/app/gulpfile.js delete mode 100644 03-express-gulp-watch/app/package.json delete mode 100644 03-express-gulp-watch/app/public/images/.gitkeep delete mode 100644 03-express-gulp-watch/app/public/javascripts/.gitkeep delete mode 100644 03-express-gulp-watch/app/public/scss/_variables.scss delete mode 100644 03-express-gulp-watch/app/public/scss/style.scss delete mode 100644 03-express-gulp-watch/app/public/stylesheets/.gitkeep delete mode 100644 03-express-gulp-watch/app/routes/index.js delete mode 100644 03-express-gulp-watch/app/routes/users.js delete mode 100644 03-express-gulp-watch/app/views/error.hjs delete mode 100644 03-express-gulp-watch/app/views/index.hjs delete mode 100644 03-express-gulp-watch/docker-compose.yml delete mode 100644 04-express-grunt-watch/.dockerignore delete mode 100644 04-express-grunt-watch/.gitignore delete mode 100644 04-express-grunt-watch/Dockerfile delete mode 100644 04-express-grunt-watch/README.md delete mode 100644 04-express-grunt-watch/app/Gruntfile.js delete mode 100644 04-express-grunt-watch/app/app.js delete mode 100755 04-express-grunt-watch/app/bin/www delete mode 100644 04-express-grunt-watch/app/package.json delete mode 100644 04-express-grunt-watch/app/public/images/.gitkeep delete mode 100644 04-express-grunt-watch/app/public/javascripts/.gitkeep delete mode 100644 04-express-grunt-watch/app/public/scss/_variables.scss delete mode 100644 04-express-grunt-watch/app/public/scss/style.scss delete mode 100644 04-express-grunt-watch/app/public/stylesheets/.gitkeep delete mode 100644 04-express-grunt-watch/app/public/stylesheets/style.css delete mode 100644 04-express-grunt-watch/app/public/stylesheets/style.css.map delete mode 100644 04-express-grunt-watch/app/routes/index.js delete mode 100644 04-express-grunt-watch/app/routes/users.js delete mode 100644 04-express-grunt-watch/app/views/error.hjs delete mode 100644 04-express-grunt-watch/app/views/index.hjs delete mode 100644 04-express-grunt-watch/docker-compose.yml delete mode 100644 05-nginx-express-redis-nodemon/.dockerignore delete mode 100644 05-nginx-express-redis-nodemon/README.md delete mode 100644 05-nginx-express-redis-nodemon/app/Dockerfile delete mode 100644 05-nginx-express-redis-nodemon/app/app.js delete mode 100755 05-nginx-express-redis-nodemon/app/bin/www delete mode 100644 05-nginx-express-redis-nodemon/app/nodemon.json delete mode 100644 05-nginx-express-redis-nodemon/app/package.json delete mode 100644 05-nginx-express-redis-nodemon/app/public/images/.gitkeep delete mode 100644 05-nginx-express-redis-nodemon/app/public/javascripts/.gitkeep delete mode 100644 05-nginx-express-redis-nodemon/app/public/stylesheets/.gitkeep delete mode 100644 05-nginx-express-redis-nodemon/app/public/stylesheets/style.css delete mode 100644 05-nginx-express-redis-nodemon/app/routes/index.js delete mode 100644 05-nginx-express-redis-nodemon/app/routes/users.js delete mode 100644 05-nginx-express-redis-nodemon/app/views/error.hjs delete mode 100644 05-nginx-express-redis-nodemon/app/views/index.hjs delete mode 100644 05-nginx-express-redis-nodemon/docker-compose.yml delete mode 100644 05-nginx-express-redis-nodemon/nginx/Dockerfile delete mode 100644 05-nginx-express-redis-nodemon/nginx/sites-enabled/nodejs_project create mode 100755 bin/builder create mode 100644 builder.js create mode 100644 index.js create mode 100644 package.json create mode 100644 templates/common/Dockerfile.mustache create mode 100755 templates/common/docker/install.mustache create mode 100644 templates/express/docker-compose.yml create mode 100644 templates/express/index.js create mode 100644 templates/express/package.json create mode 100644 templates/express/site/router.js create mode 100644 templates/express/views/index.mustache create mode 100644 templates/minimal/docker-compose.yml create mode 100644 templates/minimal/index.js create mode 100644 templates/minimal/package.json diff --git a/.gitignore b/.gitignore index 1e3d79b..1ec27db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -.sass-cache +build/ +node_modules/ !.gitkeep -03-express-gulp-watch/app/public/stylesheets/style.css -03-express-gulp-watch/app/public/stylesheets/style.css.map \ No newline at end of file diff --git a/00-basic-express-generator/.dockerignore b/00-basic-express-generator/.dockerignore deleted file mode 100644 index d1eaa0b..0000000 --- a/00-basic-express-generator/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -.git -.gitignore -README.md -docker-compose.yml -node_modules diff --git a/00-basic-express-generator/Dockerfile b/00-basic-express-generator/Dockerfile deleted file mode 100644 index 9027fcb..0000000 --- a/00-basic-express-generator/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM node:0.10.38 - -RUN mkdir /src - -RUN npm install express-generator -g - -WORKDIR /src -ADD app/package.json /src/package.json -RUN npm install - -EXPOSE 3000 - -CMD node app/bin/www \ No newline at end of file diff --git a/00-basic-express-generator/README.md b/00-basic-express-generator/README.md deleted file mode 100644 index 7b018ca..0000000 --- a/00-basic-express-generator/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Basic skeleton with Express app generator - -Generate and run a basic [Express](http://expressjs.com/) app. This step should be considered as starting point and is not (yet) suited for "real" development because there's not automatic restart on file changes. We'll get there in the following steps. - -## Prerequisites - -Install [Docker](https://www.docker.com/) on your system. - -* [Install instructions](https://docs.docker.com/installation/mac/) for Mac OS X -* [Install instructions](https://docs.docker.com/installation/ubuntulinux/) for Ubuntu Linux -* [Install instructions](https://docs.docker.com/installation/) for other platforms - -Install [Docker Compose](http://docs.docker.com/compose/) on your system. - -* Python/pip: `sudo pip install -U docker-compose` -* Other: ``curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose; chmod +x /usr/local/bin/docker-compose`` - -## Setup - -1. Run `docker-compose build`. It will pull a base image from the Docker registry and install [express-generator](https://github.com/expressjs/generator) globally in your container. The rest can be ignored for now. - -2. Run `docker-compose run web express app`. This will bootstrap a new Express app in your container in the `app` subfolder. Since it already exists, Express will ask you if you want to override, which you can answer with `yes`. - -3. Run `docker-compose build` again. It will install install all dependencies from the (generated) package.json, expose port 3000 to the host, and instruct the container to execute `node app/bin/www` on start up. - -## Start - -Run `docker-compose up` to create and start the container. The app should then be running on your docker daemon on port 3030 (On OS X you can use `boot2docker ip` to find out the IP address). diff --git a/00-basic-express-generator/app/app.js b/00-basic-express-generator/app/app.js deleted file mode 100644 index 95b1e2a..0000000 --- a/00-basic-express-generator/app/app.js +++ /dev/null @@ -1,60 +0,0 @@ -var express = require('express'); -var path = require('path'); -var favicon = require('serve-favicon'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var bodyParser = require('body-parser'); - -var routes = require('./routes/index'); -var users = require('./routes/users'); - -var app = express(); - -// view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'jade'); - -// uncomment after placing your favicon in /public -//app.use(favicon(__dirname + '/public/favicon.ico')); -app.use(logger('dev')); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); - -app.use('/', routes); -app.use('/users', users); - -// catch 404 and forward to error handler -app.use(function(req, res, next) { - var err = new Error('Not Found'); - err.status = 404; - next(err); -}); - -// error handlers - -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); - }); -} - -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); -}); - - -module.exports = app; diff --git a/00-basic-express-generator/app/bin/www b/00-basic-express-generator/app/bin/www deleted file mode 100755 index 7f811c5..0000000 --- a/00-basic-express-generator/app/bin/www +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env node - -/** - * Module dependencies. - */ - -var app = require('../app'); -var debug = require('debug')('app:server'); -var http = require('http'); - -/** - * Get port from environment and store in Express. - */ - -var port = normalizePort(process.env.PORT || '3000'); -app.set('port', port); - -/** - * Create HTTP server. - */ - -var server = http.createServer(app); - -/** - * Listen on provided port, on all network interfaces. - */ - -server.listen(port); -server.on('error', onError); -server.on('listening', onListening); - -/** - * Normalize a port into a number, string, or false. - */ - -function normalizePort(val) { - var port = parseInt(val, 10); - - if (isNaN(port)) { - // named pipe - return val; - } - - if (port >= 0) { - // port number - return port; - } - - return false; -} - -/** - * Event listener for HTTP server "error" event. - */ - -function onError(error) { - if (error.syscall !== 'listen') { - throw error; - } - - var bind = typeof port === 'string' - ? 'Pipe ' + port - : 'Port ' + port - - // handle specific listen errors with friendly messages - switch (error.code) { - case 'EACCES': - console.error(bind + ' requires elevated privileges'); - process.exit(1); - break; - case 'EADDRINUSE': - console.error(bind + ' is already in use'); - process.exit(1); - break; - default: - throw error; - } -} - -/** - * Event listener for HTTP server "listening" event. - */ - -function onListening() { - var addr = server.address(); - var bind = typeof addr === 'string' - ? 'pipe ' + addr - : 'port ' + addr.port; - debug('Listening on ' + bind); -} diff --git a/00-basic-express-generator/app/package.json b/00-basic-express-generator/app/package.json deleted file mode 100644 index 3c5f460..0000000 --- a/00-basic-express-generator/app/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "app", - "version": "0.0.0", - "private": true, - "scripts": { - "start": "node ./bin/www" - }, - "dependencies": { - "body-parser": "~1.10.2", - "cookie-parser": "~1.3.3", - "debug": "~2.1.1", - "express": "~4.11.1", - "jade": "~1.9.1", - "morgan": "~1.5.1", - "serve-favicon": "~2.2.0" - } -} \ No newline at end of file diff --git a/00-basic-express-generator/app/public/stylesheets/style.css b/00-basic-express-generator/app/public/stylesheets/style.css deleted file mode 100644 index 30e047d..0000000 --- a/00-basic-express-generator/app/public/stylesheets/style.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - padding: 50px; - font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; -} - -a { - color: #00B7FF; -} \ No newline at end of file diff --git a/00-basic-express-generator/app/routes/index.js b/00-basic-express-generator/app/routes/index.js deleted file mode 100644 index ecca96a..0000000 --- a/00-basic-express-generator/app/routes/index.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET home page. */ -router.get('/', function(req, res, next) { - res.render('index', { title: 'Express' }); -}); - -module.exports = router; diff --git a/00-basic-express-generator/app/routes/users.js b/00-basic-express-generator/app/routes/users.js deleted file mode 100644 index 623e430..0000000 --- a/00-basic-express-generator/app/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/', function(req, res, next) { - res.send('respond with a resource'); -}); - -module.exports = router; diff --git a/00-basic-express-generator/app/views/error.jade b/00-basic-express-generator/app/views/error.jade deleted file mode 100644 index 51ec12c..0000000 --- a/00-basic-express-generator/app/views/error.jade +++ /dev/null @@ -1,6 +0,0 @@ -extends layout - -block content - h1= message - h2= error.status - pre #{error.stack} diff --git a/00-basic-express-generator/app/views/index.jade b/00-basic-express-generator/app/views/index.jade deleted file mode 100644 index 3d63b9a..0000000 --- a/00-basic-express-generator/app/views/index.jade +++ /dev/null @@ -1,5 +0,0 @@ -extends layout - -block content - h1= title - p Welcome to #{title} diff --git a/00-basic-express-generator/app/views/layout.jade b/00-basic-express-generator/app/views/layout.jade deleted file mode 100644 index b945f57..0000000 --- a/00-basic-express-generator/app/views/layout.jade +++ /dev/null @@ -1,7 +0,0 @@ -doctype html -html - head - title= title - link(rel='stylesheet', href='/stylesheets/style.css') - body - block content \ No newline at end of file diff --git a/00-basic-express-generator/docker-compose.yml b/00-basic-express-generator/docker-compose.yml deleted file mode 100644 index e5d9890..0000000 --- a/00-basic-express-generator/docker-compose.yml +++ /dev/null @@ -1,6 +0,0 @@ -web: - build: . - volumes: - - "./app:/src/app" - ports: - - "3030:3000" \ No newline at end of file diff --git a/01-express-nodemon/.dockerignore b/01-express-nodemon/.dockerignore deleted file mode 100644 index d1eaa0b..0000000 --- a/01-express-nodemon/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -.git -.gitignore -README.md -docker-compose.yml -node_modules diff --git a/01-express-nodemon/Dockerfile b/01-express-nodemon/Dockerfile deleted file mode 100644 index af1bd93..0000000 --- a/01-express-nodemon/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM node:0.10.38 - -RUN mkdir /src - -RUN npm install nodemon -g - -WORKDIR /src -ADD app/package.json /src/package.json -RUN npm install - -ADD app/nodemon.json /src/nodemon.json - -EXPOSE 3000 - -CMD npm start \ No newline at end of file diff --git a/01-express-nodemon/README.md b/01-express-nodemon/README.md deleted file mode 100644 index 2d71f79..0000000 --- a/01-express-nodemon/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Express app with nodemon development server - -Use [nodemon's](https://github.com/remy/nodemon) legacy mode to monitor file changes in your container. The app will restart, if you change any **.js**, **.json** or **.hjs** file. - -## Prerequisites - -Install [Docker](https://www.docker.com/) on your system. - -* [Install instructions](https://docs.docker.com/installation/mac/) for Mac OS X -* [Install instructions](https://docs.docker.com/installation/ubuntulinux/) for Ubuntu Linux -* [Install instructions](https://docs.docker.com/installation/) for other platforms - -Install [Docker Compose](http://docs.docker.com/compose/) on your system. - -* Python/pip: `sudo pip install -U docker-compose` -* Other: ``curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose; chmod +x /usr/local/bin/docker-compose`` - -## Setup - -Run `docker-compose build`. It will - -* install [nodemon](https://github.com/remy/nodemon) globally in your container -* install all dependencies from the package.json locally -* expose port 3000 to the host -* instruct the container to execute `npm start` on start up. - -## Start - -Run `docker-compose up` to create and start the container. The app should then be running on your docker daemon on port 3030 (On OS X you can use `boot2docker ip` to find out the IP address). - -## Notes on boot2docker - -It [appears](https://github.com/boot2docker/boot2docker/issues/290) that boot2docker (OS X, Windows) currently does not automatically sync the system clock with the host system after a host resumes from sleep. This becomes a problem due to the way nodemon detects file changes. That might cause it to go bananas, if the clocks on both systems are "too much" out of sync. Until this is fixed, you might use [this workaround](https://github.com/boot2docker/boot2docker/issues/290#issuecomment-62384209) or simply do a manual sync via - -```bash -/usr/local/bin/boot2docker ssh sudo ntpclient -s -h pool.ntp.org -``` diff --git a/01-express-nodemon/app/app.js b/01-express-nodemon/app/app.js deleted file mode 100644 index ca8ba7a..0000000 --- a/01-express-nodemon/app/app.js +++ /dev/null @@ -1,60 +0,0 @@ -var express = require('express'); -var path = require('path'); -var favicon = require('serve-favicon'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var bodyParser = require('body-parser'); - -var routes = require('./routes/index'); -var users = require('./routes/users'); - -var app = express(); - -// view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'hjs'); - -// uncomment after placing your favicon in /public -//app.use(favicon(__dirname + '/public/favicon.ico')); -app.use(logger('dev')); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); - -app.use('/', routes); -app.use('/users', users); - -// catch 404 and forward to error handler -app.use(function(req, res, next) { - var err = new Error('Not Found'); - err.status = 404; - next(err); -}); - -// error handlers - -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); - }); -} - -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); -}); - - -module.exports = app; diff --git a/01-express-nodemon/app/bin/www b/01-express-nodemon/app/bin/www deleted file mode 100755 index 73391f4..0000000 --- a/01-express-nodemon/app/bin/www +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env node -var debug = require('debug')('app'); -var app = require('../app'); - -app.set('port', process.env.PORT || 3000); - -var server = app.listen(app.get('port'), function() { - debug('Express server listening on port ' + server.address().port); -}); diff --git a/01-express-nodemon/app/nodemon.json b/01-express-nodemon/app/nodemon.json deleted file mode 100644 index f1b04c6..0000000 --- a/01-express-nodemon/app/nodemon.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "env": { - "NODE_ENV": "development" - }, - "ext": "js json hjs" -} \ No newline at end of file diff --git a/01-express-nodemon/app/package.json b/01-express-nodemon/app/package.json deleted file mode 100644 index 725399a..0000000 --- a/01-express-nodemon/app/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "app", - "version": "0.0.0", - "private": true, - "scripts": { - "start": "nodemon -L app/bin/www" - }, - "dependencies": { - "express": "~4.9.0", - "body-parser": "~1.8.1", - "cookie-parser": "~1.3.3", - "morgan": "~1.3.0", - "serve-favicon": "~2.1.3", - "debug": "~2.0.0", - "hjs": "~0.0.6", - "jade": "*" - } -} diff --git a/01-express-nodemon/app/public/images/.gitkeep b/01-express-nodemon/app/public/images/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/01-express-nodemon/app/public/javascripts/.gitkeep b/01-express-nodemon/app/public/javascripts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/01-express-nodemon/app/public/stylesheets/.gitkeep b/01-express-nodemon/app/public/stylesheets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/01-express-nodemon/app/public/stylesheets/style.css b/01-express-nodemon/app/public/stylesheets/style.css deleted file mode 100644 index 30e047d..0000000 --- a/01-express-nodemon/app/public/stylesheets/style.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - padding: 50px; - font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; -} - -a { - color: #00B7FF; -} \ No newline at end of file diff --git a/01-express-nodemon/app/routes/index.js b/01-express-nodemon/app/routes/index.js deleted file mode 100644 index 896c948..0000000 --- a/01-express-nodemon/app/routes/index.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET home page. */ -router.get('/', function(req, res) { - res.render('index', { title: 'Express' }); -}); - -module.exports = router; diff --git a/01-express-nodemon/app/routes/users.js b/01-express-nodemon/app/routes/users.js deleted file mode 100644 index c00d7de..0000000 --- a/01-express-nodemon/app/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/', function(req, res) { - res.send('respond with a resource'); -}); - -module.exports = router; diff --git a/01-express-nodemon/app/views/error.hjs b/01-express-nodemon/app/views/error.hjs deleted file mode 100644 index 36a6196..0000000 --- a/01-express-nodemon/app/views/error.hjs +++ /dev/null @@ -1,3 +0,0 @@ -

{{ message }}

-

{{ error.status }}

-
{{ error.stack }}
diff --git a/01-express-nodemon/app/views/index.hjs b/01-express-nodemon/app/views/index.hjs deleted file mode 100644 index 4f24fe8..0000000 --- a/01-express-nodemon/app/views/index.hjs +++ /dev/null @@ -1,11 +0,0 @@ - - - - {{ title }} - - - -

{{ title }}

-

Welcome to {{ title }}!

- - \ No newline at end of file diff --git a/01-express-nodemon/docker-compose.yml b/01-express-nodemon/docker-compose.yml deleted file mode 100644 index e5d9890..0000000 --- a/01-express-nodemon/docker-compose.yml +++ /dev/null @@ -1,6 +0,0 @@ -web: - build: . - volumes: - - "./app:/src/app" - ports: - - "3030:3000" \ No newline at end of file diff --git a/02-express-redis-nodemon/.dockerignore b/02-express-redis-nodemon/.dockerignore deleted file mode 100644 index d1eaa0b..0000000 --- a/02-express-redis-nodemon/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -.git -.gitignore -README.md -docker-compose.yml -node_modules diff --git a/02-express-redis-nodemon/Dockerfile b/02-express-redis-nodemon/Dockerfile deleted file mode 100644 index af1bd93..0000000 --- a/02-express-redis-nodemon/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM node:0.10.38 - -RUN mkdir /src - -RUN npm install nodemon -g - -WORKDIR /src -ADD app/package.json /src/package.json -RUN npm install - -ADD app/nodemon.json /src/nodemon.json - -EXPOSE 3000 - -CMD npm start \ No newline at end of file diff --git a/02-express-redis-nodemon/README.md b/02-express-redis-nodemon/README.md deleted file mode 100644 index eb7faae..0000000 --- a/02-express-redis-nodemon/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# Express app with Redis and nodemon development server - -In this step we'll link a [Redis](http://redis.io/) container to the app from [step 01](https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/01-express-nodemon). - -## Prerequisites - -Install [Docker](https://www.docker.com/) on your system. - -* [Install instructions](https://docs.docker.com/installation/mac/) for Mac OS X -* [Install instructions](https://docs.docker.com/installation/ubuntulinux/) for Ubuntu Linux -* [Install instructions](https://docs.docker.com/installation/) for other platforms - -Install [Docker Compose](http://docs.docker.com/compose/) on your system. - -* Python/pip: `sudo pip install -U docker-compose` -* Other: ``curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose; chmod +x /usr/local/bin/docker-compose`` -## Setup - -Run `docker-compose build`. It will - -* install [nodemon](https://github.com/remy/nodemon) globally in your container -* install all dependencies from the package.json locally -* expose port 3000 to the host -* instruct the container to execute `npm start` on start up. - -## Start - -Run `docker-compose up` to create and start both `web` and `db` container. The app should then be running on your docker daemon on port 3030 (On OS X you can use `boot2docker ip` to find out the IP address). - -You should see a counter on the index page which will be incremented in Redis on every request. See [app/routes/index.js](https://github.com/b00giZm/docker-compose-nodejs-examples/blob/master/02-express-redis-nodemon/app/routes/index.js) to learn how to conect to Redis via [enviroment variables](http://docs.docker.com/compose/env/) exposed to the `web` container. - -## Notes on boot2docker - -It [appears](https://github.com/boot2docker/boot2docker/issues/290) that boot2docker (OS X, Windows) currently does not automatically sync the system clock with the host system after a host resumes from sleep. This becomes a problem due to the way nodemon detects file changes. That might cause it to go bananas, if the clocks on both systems are "too much" out of sync. Until this is fixed, you might use [this workaround](https://github.com/boot2docker/boot2docker/issues/290#issuecomment-62384209) or simply do a manual sync via - -```bash -/usr/local/bin/boot2docker ssh sudo ntpclient -s -h pool.ntp.org -``` diff --git a/02-express-redis-nodemon/app/app.js b/02-express-redis-nodemon/app/app.js deleted file mode 100644 index ca8ba7a..0000000 --- a/02-express-redis-nodemon/app/app.js +++ /dev/null @@ -1,60 +0,0 @@ -var express = require('express'); -var path = require('path'); -var favicon = require('serve-favicon'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var bodyParser = require('body-parser'); - -var routes = require('./routes/index'); -var users = require('./routes/users'); - -var app = express(); - -// view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'hjs'); - -// uncomment after placing your favicon in /public -//app.use(favicon(__dirname + '/public/favicon.ico')); -app.use(logger('dev')); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); - -app.use('/', routes); -app.use('/users', users); - -// catch 404 and forward to error handler -app.use(function(req, res, next) { - var err = new Error('Not Found'); - err.status = 404; - next(err); -}); - -// error handlers - -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); - }); -} - -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); -}); - - -module.exports = app; diff --git a/02-express-redis-nodemon/app/bin/www b/02-express-redis-nodemon/app/bin/www deleted file mode 100755 index 73391f4..0000000 --- a/02-express-redis-nodemon/app/bin/www +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env node -var debug = require('debug')('app'); -var app = require('../app'); - -app.set('port', process.env.PORT || 3000); - -var server = app.listen(app.get('port'), function() { - debug('Express server listening on port ' + server.address().port); -}); diff --git a/02-express-redis-nodemon/app/nodemon.json b/02-express-redis-nodemon/app/nodemon.json deleted file mode 100644 index f1b04c6..0000000 --- a/02-express-redis-nodemon/app/nodemon.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "env": { - "NODE_ENV": "development" - }, - "ext": "js json hjs" -} \ No newline at end of file diff --git a/02-express-redis-nodemon/app/package.json b/02-express-redis-nodemon/app/package.json deleted file mode 100644 index 369171f..0000000 --- a/02-express-redis-nodemon/app/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "app", - "version": "0.0.0", - "private": true, - "scripts": { - "start": "nodemon -L app/bin/www" - }, - "dependencies": { - "express": "~4.9.0", - "body-parser": "~1.8.1", - "cookie-parser": "~1.3.3", - "morgan": "~1.3.0", - "serve-favicon": "~2.1.3", - "debug": "~2.0.0", - "hjs": "~0.0.6", - "redis": "~0.12.1", - "hiredis": "~0.1.17" - } -} \ No newline at end of file diff --git a/02-express-redis-nodemon/app/public/images/.gitkeep b/02-express-redis-nodemon/app/public/images/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/02-express-redis-nodemon/app/public/javascripts/.gitkeep b/02-express-redis-nodemon/app/public/javascripts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/02-express-redis-nodemon/app/public/stylesheets/.gitkeep b/02-express-redis-nodemon/app/public/stylesheets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/02-express-redis-nodemon/app/public/stylesheets/style.css b/02-express-redis-nodemon/app/public/stylesheets/style.css deleted file mode 100644 index 30e047d..0000000 --- a/02-express-redis-nodemon/app/public/stylesheets/style.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - padding: 50px; - font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; -} - -a { - color: #00B7FF; -} \ No newline at end of file diff --git a/02-express-redis-nodemon/app/routes/index.js b/02-express-redis-nodemon/app/routes/index.js deleted file mode 100644 index 9b28f55..0000000 --- a/02-express-redis-nodemon/app/routes/index.js +++ /dev/null @@ -1,22 +0,0 @@ -var express = require('express'); -var redis = require('redis'); - -var router = express.Router(); - -/* redis */ -var host = process.env.REDIS_PORT_6379_TCP_ADDR || '127.0.01'; -var port = process.env.REDIS_PORT_6379_TCP_PORT || 6379; -var client = redis.createClient(port, host); - -/* GET home page. */ -router.get('/', function(req, res, next) { - client.incr('counter', function(err, result) { - if (err) { - return next(err); - } - - res.render('index', { title: 'Express', counter: result }); - }); -}); - -module.exports = router; diff --git a/02-express-redis-nodemon/app/routes/users.js b/02-express-redis-nodemon/app/routes/users.js deleted file mode 100644 index c00d7de..0000000 --- a/02-express-redis-nodemon/app/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/', function(req, res) { - res.send('respond with a resource'); -}); - -module.exports = router; diff --git a/02-express-redis-nodemon/app/views/error.hjs b/02-express-redis-nodemon/app/views/error.hjs deleted file mode 100644 index 36a6196..0000000 --- a/02-express-redis-nodemon/app/views/error.hjs +++ /dev/null @@ -1,3 +0,0 @@ -

{{ message }}

-

{{ error.status }}

-
{{ error.stack }}
diff --git a/02-express-redis-nodemon/app/views/index.hjs b/02-express-redis-nodemon/app/views/index.hjs deleted file mode 100644 index 39261f2..0000000 --- a/02-express-redis-nodemon/app/views/index.hjs +++ /dev/null @@ -1,12 +0,0 @@ - - - - {{ title }} - - - -

{{ title }}

-

Welcome to {{ title }}.

-

This page has been requested {{ counter }} times.

- - \ No newline at end of file diff --git a/02-express-redis-nodemon/docker-compose.yml b/02-express-redis-nodemon/docker-compose.yml deleted file mode 100644 index 3f9a533..0000000 --- a/02-express-redis-nodemon/docker-compose.yml +++ /dev/null @@ -1,11 +0,0 @@ -web: - build: . - volumes: - - "./app:/src/app" - ports: - - "3030:3000" - links: - - "db:redis" - -db: - image: redis \ No newline at end of file diff --git a/03-express-gulp-watch/.dockerignore b/03-express-gulp-watch/.dockerignore deleted file mode 100644 index d1eaa0b..0000000 --- a/03-express-gulp-watch/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -.git -.gitignore -README.md -docker-compose.yml -node_modules diff --git a/03-express-gulp-watch/Dockerfile b/03-express-gulp-watch/Dockerfile deleted file mode 100644 index bbe2905..0000000 --- a/03-express-gulp-watch/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM node:0.10.38 - -RUN apt-get update -qq && apt-get install -y build-essential -RUN apt-get install -y ruby -RUN gem install sass - -RUN mkdir /src - -RUN npm install gulp -g - -WORKDIR /src -ADD app/package.json /src/package.json -RUN npm install - -EXPOSE 3000 -EXPOSE 35729 - -CMD ["npm", "start"] diff --git a/03-express-gulp-watch/README.md b/03-express-gulp-watch/README.md deleted file mode 100644 index ea6f610..0000000 --- a/03-express-gulp-watch/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Express app with Gulp.js build system - -This app contains a [Gulp](http://gulpjs.com/) configuration which will - -* Restart the app on **.js**, **.json** or **.hjs** file changes via [gulp-nodemon](https://github.com/JacksonGariety/gulp-nodemon) -* Automatically compile [SASS](http://sass-lang.com/) stylesheets to CSS via [gulp.watch](https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulpwatchglob--opts-tasks-or-gulpwatchglob--opts-cb) and [gulp-ruby-sass](https://github.com/sindresorhus/gulp-ruby-sass) - -## Prerequisites - -Install [Docker](https://www.docker.com/) on your system. - -* [Install instructions](https://docs.docker.com/installation/mac/) for Mac OS X -* [Install instructions](https://docs.docker.com/installation/ubuntulinux/) for Ubuntu Linux -* [Install instructions](https://docs.docker.com/installation/) for other platforms - -Install [Docker Compose](http://docs.docker.com/compose/) on your system. - -* Python/pip: `sudo pip install -U docker-compose` -* Other: ``curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose; chmod +x /usr/local/bin/docker-compose`` - -## Setup - -Run `docker-compose build`. It will - -* install [Ruby](https://www.ruby-lang.org) and [SASS](https://rubygems.org/gems/sass) -* install [Gulp](http://gulpjs.com/) globally -* install all dependencies from the package.json locally -* expose port 3000 to the host -* instruct the container to execute `gulp --gulpfile app/gulpfile.js` on start up. - -## Start - -Run `docker-compose up` to create and start the container. The app should then be running on your docker daemon on port 3030 (On OS X you can use `boot2docker ip` to find out the IP address). - -Go ahead and change any SASS stylesheet inside app/public/sass, and watch it autmatically compile to CSS. - -## Notes on boot2docker - -It [appears](https://github.com/boot2docker/boot2docker/issues/290) that boot2docker (OS X, Windows) currently does not automatically sync the system clock with the host system after a host resumes from sleep. This becomes a problem due to the way nodemon detects file changes. That might cause it to go bananas, if the clocks on both systems are "too much" out of sync. Until this is fixed, you might use [this workaround](https://github.com/boot2docker/boot2docker/issues/290#issuecomment-62384209) or simply do a manual sync via - -```bash -/usr/local/bin/boot2docker ssh sudo ntpclient -s -h pool.ntp.org -``` diff --git a/03-express-gulp-watch/app/app.js b/03-express-gulp-watch/app/app.js deleted file mode 100644 index ca8ba7a..0000000 --- a/03-express-gulp-watch/app/app.js +++ /dev/null @@ -1,60 +0,0 @@ -var express = require('express'); -var path = require('path'); -var favicon = require('serve-favicon'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var bodyParser = require('body-parser'); - -var routes = require('./routes/index'); -var users = require('./routes/users'); - -var app = express(); - -// view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'hjs'); - -// uncomment after placing your favicon in /public -//app.use(favicon(__dirname + '/public/favicon.ico')); -app.use(logger('dev')); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); - -app.use('/', routes); -app.use('/users', users); - -// catch 404 and forward to error handler -app.use(function(req, res, next) { - var err = new Error('Not Found'); - err.status = 404; - next(err); -}); - -// error handlers - -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); - }); -} - -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); -}); - - -module.exports = app; diff --git a/03-express-gulp-watch/app/bin/www b/03-express-gulp-watch/app/bin/www deleted file mode 100755 index 73391f4..0000000 --- a/03-express-gulp-watch/app/bin/www +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env node -var debug = require('debug')('app'); -var app = require('../app'); - -app.set('port', process.env.PORT || 3000); - -var server = app.listen(app.get('port'), function() { - debug('Express server listening on port ' + server.address().port); -}); diff --git a/03-express-gulp-watch/app/gulpfile.js b/03-express-gulp-watch/app/gulpfile.js deleted file mode 100644 index 570345c..0000000 --- a/03-express-gulp-watch/app/gulpfile.js +++ /dev/null @@ -1,24 +0,0 @@ -var gulp = require('gulp'); -var nodemon = require('gulp-nodemon'); -var sass = require('gulp-ruby-sass'); -var livereload = require('gulp-livereload'); - -gulp.task('develop', function () { - nodemon({script: './bin/www', ext: 'js hjs json', legacyWatch: true }); -}); - -gulp.task('sass', function() { - gulp - .src('./public/scss/**/*.scss') - .pipe(sass()) - .pipe(gulp.dest('./public/stylesheets')) - .pipe(livereload()) - .on('error', function (err) { - console.log(err.message); - }) - ; -}); - -gulp.watch('./public/scss/**/*.scss', ['sass']); - -gulp.task('default', ['develop', 'sass']); diff --git a/03-express-gulp-watch/app/package.json b/03-express-gulp-watch/app/package.json deleted file mode 100644 index aa18e09..0000000 --- a/03-express-gulp-watch/app/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "app", - "version": "0.0.0", - "private": true, - "scripts": { - "start": "gulp --gulpfile app/gulpfile.js" - }, - "dependencies": { - "express": "~4.9.0", - "body-parser": "~1.8.1", - "cookie-parser": "~1.3.3", - "morgan": "~1.3.0", - "serve-favicon": "~2.1.3", - "debug": "~2.0.0", - "hjs": "~0.0.6" - }, - "devDependencies": { - "gulp": "~3.8.8", - "gulp-nodemon": "~1.0.4", - "gulp-watch": "~1.1.0", - "gulp-ruby-sass": "~0.7.1", - "gulp-plumber": "~0.6.6", - "gulp-livereload": "~2.1.1" - } -} diff --git a/03-express-gulp-watch/app/public/images/.gitkeep b/03-express-gulp-watch/app/public/images/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/03-express-gulp-watch/app/public/javascripts/.gitkeep b/03-express-gulp-watch/app/public/javascripts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/03-express-gulp-watch/app/public/scss/_variables.scss b/03-express-gulp-watch/app/public/scss/_variables.scss deleted file mode 100644 index 5b10391..0000000 --- a/03-express-gulp-watch/app/public/scss/_variables.scss +++ /dev/null @@ -1,4 +0,0 @@ -$font-family: "Lucida Grande", Helvetica, Arial, sans-serif; -$font-size: 14; - -$padding: 50px; \ No newline at end of file diff --git a/03-express-gulp-watch/app/public/scss/style.scss b/03-express-gulp-watch/app/public/scss/style.scss deleted file mode 100644 index d7ce00e..0000000 --- a/03-express-gulp-watch/app/public/scss/style.scss +++ /dev/null @@ -1,11 +0,0 @@ -@import 'variables'; - -body { - padding: $padding; - font-family: $font-family; - font-size: $font-size; -} - -a { - color: #00B7FF; -} \ No newline at end of file diff --git a/03-express-gulp-watch/app/public/stylesheets/.gitkeep b/03-express-gulp-watch/app/public/stylesheets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/03-express-gulp-watch/app/routes/index.js b/03-express-gulp-watch/app/routes/index.js deleted file mode 100644 index 896c948..0000000 --- a/03-express-gulp-watch/app/routes/index.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET home page. */ -router.get('/', function(req, res) { - res.render('index', { title: 'Express' }); -}); - -module.exports = router; diff --git a/03-express-gulp-watch/app/routes/users.js b/03-express-gulp-watch/app/routes/users.js deleted file mode 100644 index c00d7de..0000000 --- a/03-express-gulp-watch/app/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/', function(req, res) { - res.send('respond with a resource'); -}); - -module.exports = router; diff --git a/03-express-gulp-watch/app/views/error.hjs b/03-express-gulp-watch/app/views/error.hjs deleted file mode 100644 index 36a6196..0000000 --- a/03-express-gulp-watch/app/views/error.hjs +++ /dev/null @@ -1,3 +0,0 @@ -

{{ message }}

-

{{ error.status }}

-
{{ error.stack }}
diff --git a/03-express-gulp-watch/app/views/index.hjs b/03-express-gulp-watch/app/views/index.hjs deleted file mode 100644 index 4f24fe8..0000000 --- a/03-express-gulp-watch/app/views/index.hjs +++ /dev/null @@ -1,11 +0,0 @@ - - - - {{ title }} - - - -

{{ title }}

-

Welcome to {{ title }}!

- - \ No newline at end of file diff --git a/03-express-gulp-watch/docker-compose.yml b/03-express-gulp-watch/docker-compose.yml deleted file mode 100644 index da03491..0000000 --- a/03-express-gulp-watch/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -web: - build: . - volumes: - - "./app:/src/app" - ports: - - "3030:3000" - - "35729:35729" \ No newline at end of file diff --git a/04-express-grunt-watch/.dockerignore b/04-express-grunt-watch/.dockerignore deleted file mode 100644 index d1eaa0b..0000000 --- a/04-express-grunt-watch/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -.git -.gitignore -README.md -docker-compose.yml -node_modules diff --git a/04-express-grunt-watch/.gitignore b/04-express-grunt-watch/.gitignore deleted file mode 100644 index 2d5ba21..0000000 --- a/04-express-grunt-watch/.gitignore +++ /dev/null @@ -1 +0,0 @@ -public/stylesheets/** diff --git a/04-express-grunt-watch/Dockerfile b/04-express-grunt-watch/Dockerfile deleted file mode 100644 index 6c2ecff..0000000 --- a/04-express-grunt-watch/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM node:0.10.38 - -RUN apt-get update -qq && apt-get install -y build-essential -RUN apt-get install -y ruby -RUN gem install sass - -RUN mkdir /src - -RUN npm install grunt-cli -g - -WORKDIR /src -ADD app/package.json /src/package.json -RUN npm install - -ADD app/Gruntfile.js /src/Gruntfile.js - -EXPOSE 3000 -EXPOSE 35729 - -CMD ["npm", "start"] diff --git a/04-express-grunt-watch/README.md b/04-express-grunt-watch/README.md deleted file mode 100644 index ccacae0..0000000 --- a/04-express-grunt-watch/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Express app with Grunt.js build system - -This app contains a [Grunt](http://gruntjs.com/) configuration which will - -* Restart the app on **.js**, **.json** or **.hjs** file changes via [grunt-nodemon](https://github.com/ChrisWren/grunt-nodemon) -* Automatically compile [SASS](http://sass-lang.com/) stylesheets to CSS via [grunt-contrib-watch](https://github.com/gruntjs/grunt-contrib-watch) and [grunt-contrib-sass](https://github.com/gruntjs/grunt-contrib-sass) -* Manage the concurrent `nodemon` and `watch` tasks via [grunt-concurrent](https://github.com/sindresorhus/grunt-concurrent) - -## Prerequisites - -Install [Docker](https://www.docker.com/) on your system. - -* [Install instructions](https://docs.docker.com/installation/mac/) for Mac OS X -* [Install instructions](https://docs.docker.com/installation/ubuntulinux/) for Ubuntu Linux -* [Install instructions](https://docs.docker.com/installation/) for other platforms - -Install [Docker Compose](http://docs.docker.com/compose/) on your system. - -* Python/pip: `sudo pip install -U docker-compose` -* Other: ``curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose; chmod +x /usr/local/bin/docker-compose`` - -## Setup - -Run `docker-compose build`. It will - -* install [Ruby](https://www.ruby-lang.org) and [SASS](https://rubygems.org/gems/sass) -* install the [Grunt](http://gruntjs.com) CLI globally -* install all dependencies from the package.json locally -* expose port 3000 to the host -* instruct the container to execute `grunt` on start up. - -## Start - -Run `docker-compose up` to create and start the container. The app should then be running on your docker daemon on port 3030 (On OS X you can use `boot2docker ip` to find out the IP address). - -Go ahead and change any SASS stylesheet inside app/public/sass, and watch it autmatically compile to CSS. - -## Notes on `grunt-contrib-watch` - -For a "real real world" ;) application, you might consider [grunt-simple-watch](https://github.com/unbalanced/grunt-simple-watch) instead of [grunt-contrib-watch](https://github.com/gruntjs/grunt-contrib-sass), because, at least for my personal tests, it's a lot easier on the CPU when you have a non trivial amount of files to watch. - -For more information, please visit the [grunt-simple-watch repo](https://github.com/unbalanced/grunt-simple-watch). - -## Notes on boot2docker - -It [appears](https://github.com/boot2docker/boot2docker/issues/290) that boot2docker (OS X, Windows) currently does not automatically sync the system clock with the host system after a host resumes from sleep. This becomes a problem due to the way nodemon detects file changes. That might cause it to go bananas, if the clocks on both systems are "too much" out of sync. Until this is fixed, you might use [this workaround](https://github.com/boot2docker/boot2docker/issues/290#issuecomment-62384209) or simply do a manual sync via - -```bash -/usr/local/bin/boot2docker ssh sudo ntpclient -s -h pool.ntp.org -``` diff --git a/04-express-grunt-watch/app/Gruntfile.js b/04-express-grunt-watch/app/Gruntfile.js deleted file mode 100644 index fa141da..0000000 --- a/04-express-grunt-watch/app/Gruntfile.js +++ /dev/null @@ -1,66 +0,0 @@ -module.exports = function(grunt) { - - // Project configuration. - grunt.initConfig({ - - pkg: grunt.file.readJSON('package.json'), - - concurrent: { - dev: { - tasks : ['nodemon', 'watch'], - options : { - logConcurrentOutput: true - } - } - }, - - nodemon: { - dev: { - script : 'app/bin/www', - options : { - args : ['dev'], - nodeArgs : ['--debug'], - ext : 'js hjs json', - ignore : ['node_modules/**'], - legacyWatch : true - } - } - }, - - sass: { - dist: { - files: [ - { - expand : true, - cwd : 'app/public/scss', - src : 'style.scss', - dest : 'app/public/stylesheets', - ext : '.css' - } - ] - } - }, - - watch: { - sass: { - files : ['app/public/scss/**/*.scss'], - tasks : ['sass'], - options: { - livereload: true - } - } - } - - }); - - // Load the plugin that provides the "uglify" task. - grunt.loadNpmTasks('grunt-concurrent'); - grunt.loadNpmTasks('grunt-contrib-sass'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-nodemon'); - //grunt.loadNpmTasks('grunt-simple-watch'); - - // Default task(s). - grunt.registerTask('default', ['sass', 'concurrent']); - -}; diff --git a/04-express-grunt-watch/app/app.js b/04-express-grunt-watch/app/app.js deleted file mode 100644 index ca8ba7a..0000000 --- a/04-express-grunt-watch/app/app.js +++ /dev/null @@ -1,60 +0,0 @@ -var express = require('express'); -var path = require('path'); -var favicon = require('serve-favicon'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var bodyParser = require('body-parser'); - -var routes = require('./routes/index'); -var users = require('./routes/users'); - -var app = express(); - -// view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'hjs'); - -// uncomment after placing your favicon in /public -//app.use(favicon(__dirname + '/public/favicon.ico')); -app.use(logger('dev')); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); - -app.use('/', routes); -app.use('/users', users); - -// catch 404 and forward to error handler -app.use(function(req, res, next) { - var err = new Error('Not Found'); - err.status = 404; - next(err); -}); - -// error handlers - -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); - }); -} - -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); -}); - - -module.exports = app; diff --git a/04-express-grunt-watch/app/bin/www b/04-express-grunt-watch/app/bin/www deleted file mode 100755 index 73391f4..0000000 --- a/04-express-grunt-watch/app/bin/www +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env node -var debug = require('debug')('app'); -var app = require('../app'); - -app.set('port', process.env.PORT || 3000); - -var server = app.listen(app.get('port'), function() { - debug('Express server listening on port ' + server.address().port); -}); diff --git a/04-express-grunt-watch/app/package.json b/04-express-grunt-watch/app/package.json deleted file mode 100644 index c93f991..0000000 --- a/04-express-grunt-watch/app/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "app", - "version": "0.0.0", - "private": true, - "scripts": { - "start": "grunt" - }, - "dependencies": { - "express": "~4.9.0", - "body-parser": "~1.8.1", - "cookie-parser": "~1.3.3", - "morgan": "~1.3.0", - "serve-favicon": "~2.1.3", - "debug": "~2.0.0", - "hjs": "~0.0.6" - }, - "devDependencies": { - "grunt": "~0.4.5", - "grunt-concurrent": "~1.0.0", - "grunt-contrib-sass": "~0.8.1", - "grunt-contrib-watch": "~0.6.1", - "grunt-nodemon": "~0.3.0", - "grunt-simple-watch": "~0.1.2" - } -} diff --git a/04-express-grunt-watch/app/public/images/.gitkeep b/04-express-grunt-watch/app/public/images/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/04-express-grunt-watch/app/public/javascripts/.gitkeep b/04-express-grunt-watch/app/public/javascripts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/04-express-grunt-watch/app/public/scss/_variables.scss b/04-express-grunt-watch/app/public/scss/_variables.scss deleted file mode 100644 index eac3069..0000000 --- a/04-express-grunt-watch/app/public/scss/_variables.scss +++ /dev/null @@ -1,4 +0,0 @@ -$font-family: "Lucida Grande", Helvetica, Arial, sans-serif; -$font-size: 14; - -$padding: 50px; diff --git a/04-express-grunt-watch/app/public/scss/style.scss b/04-express-grunt-watch/app/public/scss/style.scss deleted file mode 100644 index ee37d4e..0000000 --- a/04-express-grunt-watch/app/public/scss/style.scss +++ /dev/null @@ -1,11 +0,0 @@ -@import 'variables'; - -body { - padding: $padding; - font-family: $font-family; - font-size: $font-size; -} - -a { - color: #00B7FF; -} diff --git a/04-express-grunt-watch/app/public/stylesheets/.gitkeep b/04-express-grunt-watch/app/public/stylesheets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/04-express-grunt-watch/app/public/stylesheets/style.css b/04-express-grunt-watch/app/public/stylesheets/style.css deleted file mode 100644 index 747b820..0000000 --- a/04-express-grunt-watch/app/public/stylesheets/style.css +++ /dev/null @@ -1,9 +0,0 @@ -body { - padding: 50px; - font-family: "Lucida Grande", Helvetica, Arial, sans-serif; - font-size: 14; } - -a { - color: #00B7FF; } - -/*# sourceMappingURL=style.css.map */ diff --git a/04-express-grunt-watch/app/public/stylesheets/style.css.map b/04-express-grunt-watch/app/public/stylesheets/style.css.map deleted file mode 100644 index 72bb525..0000000 --- a/04-express-grunt-watch/app/public/stylesheets/style.css.map +++ /dev/null @@ -1,7 +0,0 @@ -{ -"version": 3, -"mappings": "AAEA,IAAK;EACH,OAAO,ECAK,IAAI;EDChB,WAAW,ECJC,6CAAe;EDK3B,SAAS,ECJG,EAAE;;ADOhB,CAAE;EACA,KAAK,EAAE,OAAO", -"sources": ["../scss/style.scss","../scss/_variables.scss"], -"names": [], -"file": "style.css" -} diff --git a/04-express-grunt-watch/app/routes/index.js b/04-express-grunt-watch/app/routes/index.js deleted file mode 100644 index 896c948..0000000 --- a/04-express-grunt-watch/app/routes/index.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET home page. */ -router.get('/', function(req, res) { - res.render('index', { title: 'Express' }); -}); - -module.exports = router; diff --git a/04-express-grunt-watch/app/routes/users.js b/04-express-grunt-watch/app/routes/users.js deleted file mode 100644 index c00d7de..0000000 --- a/04-express-grunt-watch/app/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/', function(req, res) { - res.send('respond with a resource'); -}); - -module.exports = router; diff --git a/04-express-grunt-watch/app/views/error.hjs b/04-express-grunt-watch/app/views/error.hjs deleted file mode 100644 index 36a6196..0000000 --- a/04-express-grunt-watch/app/views/error.hjs +++ /dev/null @@ -1,3 +0,0 @@ -

{{ message }}

-

{{ error.status }}

-
{{ error.stack }}
diff --git a/04-express-grunt-watch/app/views/index.hjs b/04-express-grunt-watch/app/views/index.hjs deleted file mode 100644 index 8b8365b..0000000 --- a/04-express-grunt-watch/app/views/index.hjs +++ /dev/null @@ -1,11 +0,0 @@ - - - - {{ title }} - - - -

{{ title }}

-

Welcome to {{ title }}!

- - diff --git a/04-express-grunt-watch/docker-compose.yml b/04-express-grunt-watch/docker-compose.yml deleted file mode 100644 index da03491..0000000 --- a/04-express-grunt-watch/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -web: - build: . - volumes: - - "./app:/src/app" - ports: - - "3030:3000" - - "35729:35729" \ No newline at end of file diff --git a/05-nginx-express-redis-nodemon/.dockerignore b/05-nginx-express-redis-nodemon/.dockerignore deleted file mode 100644 index d1eaa0b..0000000 --- a/05-nginx-express-redis-nodemon/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -.git -.gitignore -README.md -docker-compose.yml -node_modules diff --git a/05-nginx-express-redis-nodemon/README.md b/05-nginx-express-redis-nodemon/README.md deleted file mode 100644 index e08c087..0000000 --- a/05-nginx-express-redis-nodemon/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# Nginx, Express, Redis and nodemon - -We've taken the setup from [step 02](https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/02-express-redis-nodemon) and made the app accessible through an [Nginx](http://nginx.org) server running in its own container. - -This step is heavily inspired by [RealPython's](https://github.com/RealPython) excellent blog post [Django Development With Docker Compose and Machine](https://realpython.com/blog/python/django-development-with-docker-compose-and-machine/). - -## Prerequisites - -Install [Docker](https://www.docker.com/) on your system. - -* [Install instructions](https://docs.docker.com/installation/mac/) for Mac OS X -* [Install instructions](https://docs.docker.com/installation/ubuntulinux/) for Ubuntu Linux -* [Install instructions](https://docs.docker.com/installation/) for other platforms - -Install [Docker Compose](http://docs.docker.com/compose/) on your system. - -* Python/pip: `sudo pip install -U docker-compose` -* Other: ``curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose; chmod +x /usr/local/bin/docker-compose`` -## Setup - -Run `docker-compose build`. It will - -* build the container for our Express app from [step 02](https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/02-express-redis-nodemon) -* build the container for the Nginx server - -## Start - -Run `docker-compose up` to create and start the `web`, `nginx` and `db` containers. The app should then be running on your docker daemon on standard http port 80 (On OS X you can use `boot2docker ip` to find out the IP address). - -You should see a counter on the index page which will be incremented in Redis on every request. See [app/routes/index.js](https://github.com/b00giZm/docker-compose-nodejs-examples/blob/master/02-express-redis-nodemon/app/routes/index.js) to learn how to conect to Redis via [enviroment variables](http://docs.docker.com/compose/env/) exposed to the `web` container. - -## Notes on boot2docker - -It [appears](https://github.com/boot2docker/boot2docker/issues/290) that boot2docker (OS X, Windows) currently does not automatically sync the system clock with the host system after a host resumes from sleep. This becomes a problem due to the way nodemon detects file changes. That might cause it to go bananas, if the clocks on both systems are "too much" out of sync. Until this is fixed, you might use [this workaround](https://github.com/boot2docker/boot2docker/issues/290#issuecomment-62384209) or simply do a manual sync via - -```bash -/usr/local/bin/boot2docker ssh sudo ntpclient -s -h pool.ntp.org -``` diff --git a/05-nginx-express-redis-nodemon/app/Dockerfile b/05-nginx-express-redis-nodemon/app/Dockerfile deleted file mode 100644 index 81ce429..0000000 --- a/05-nginx-express-redis-nodemon/app/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM node:0.10.38 - -RUN mkdir /src - -RUN npm install nodemon -g - -WORKDIR /src -ADD package.json package.json -RUN npm install - -ADD nodemon.json nodemon.json diff --git a/05-nginx-express-redis-nodemon/app/app.js b/05-nginx-express-redis-nodemon/app/app.js deleted file mode 100644 index ca8ba7a..0000000 --- a/05-nginx-express-redis-nodemon/app/app.js +++ /dev/null @@ -1,60 +0,0 @@ -var express = require('express'); -var path = require('path'); -var favicon = require('serve-favicon'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var bodyParser = require('body-parser'); - -var routes = require('./routes/index'); -var users = require('./routes/users'); - -var app = express(); - -// view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'hjs'); - -// uncomment after placing your favicon in /public -//app.use(favicon(__dirname + '/public/favicon.ico')); -app.use(logger('dev')); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); - -app.use('/', routes); -app.use('/users', users); - -// catch 404 and forward to error handler -app.use(function(req, res, next) { - var err = new Error('Not Found'); - err.status = 404; - next(err); -}); - -// error handlers - -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); - }); -} - -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); -}); - - -module.exports = app; diff --git a/05-nginx-express-redis-nodemon/app/bin/www b/05-nginx-express-redis-nodemon/app/bin/www deleted file mode 100755 index 73391f4..0000000 --- a/05-nginx-express-redis-nodemon/app/bin/www +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env node -var debug = require('debug')('app'); -var app = require('../app'); - -app.set('port', process.env.PORT || 3000); - -var server = app.listen(app.get('port'), function() { - debug('Express server listening on port ' + server.address().port); -}); diff --git a/05-nginx-express-redis-nodemon/app/nodemon.json b/05-nginx-express-redis-nodemon/app/nodemon.json deleted file mode 100644 index f1b04c6..0000000 --- a/05-nginx-express-redis-nodemon/app/nodemon.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "env": { - "NODE_ENV": "development" - }, - "ext": "js json hjs" -} \ No newline at end of file diff --git a/05-nginx-express-redis-nodemon/app/package.json b/05-nginx-express-redis-nodemon/app/package.json deleted file mode 100644 index f957efe..0000000 --- a/05-nginx-express-redis-nodemon/app/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "app", - "version": "0.0.0", - "private": true, - "scripts": { - "start": "nodemon -L app/bin/www" - }, - "dependencies": { - "express": "~4.9.0", - "body-parser": "~1.8.1", - "cookie-parser": "~1.3.3", - "morgan": "~1.3.0", - "serve-favicon": "~2.1.3", - "debug": "~2.0.0", - "hjs": "~0.0.6", - "redis": "~0.12.1", - "hiredis": "~0.1.17" - } -} diff --git a/05-nginx-express-redis-nodemon/app/public/images/.gitkeep b/05-nginx-express-redis-nodemon/app/public/images/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/05-nginx-express-redis-nodemon/app/public/javascripts/.gitkeep b/05-nginx-express-redis-nodemon/app/public/javascripts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/05-nginx-express-redis-nodemon/app/public/stylesheets/.gitkeep b/05-nginx-express-redis-nodemon/app/public/stylesheets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/05-nginx-express-redis-nodemon/app/public/stylesheets/style.css b/05-nginx-express-redis-nodemon/app/public/stylesheets/style.css deleted file mode 100644 index 30e047d..0000000 --- a/05-nginx-express-redis-nodemon/app/public/stylesheets/style.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - padding: 50px; - font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; -} - -a { - color: #00B7FF; -} \ No newline at end of file diff --git a/05-nginx-express-redis-nodemon/app/routes/index.js b/05-nginx-express-redis-nodemon/app/routes/index.js deleted file mode 100644 index 9b28f55..0000000 --- a/05-nginx-express-redis-nodemon/app/routes/index.js +++ /dev/null @@ -1,22 +0,0 @@ -var express = require('express'); -var redis = require('redis'); - -var router = express.Router(); - -/* redis */ -var host = process.env.REDIS_PORT_6379_TCP_ADDR || '127.0.01'; -var port = process.env.REDIS_PORT_6379_TCP_PORT || 6379; -var client = redis.createClient(port, host); - -/* GET home page. */ -router.get('/', function(req, res, next) { - client.incr('counter', function(err, result) { - if (err) { - return next(err); - } - - res.render('index', { title: 'Express', counter: result }); - }); -}); - -module.exports = router; diff --git a/05-nginx-express-redis-nodemon/app/routes/users.js b/05-nginx-express-redis-nodemon/app/routes/users.js deleted file mode 100644 index c00d7de..0000000 --- a/05-nginx-express-redis-nodemon/app/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/', function(req, res) { - res.send('respond with a resource'); -}); - -module.exports = router; diff --git a/05-nginx-express-redis-nodemon/app/views/error.hjs b/05-nginx-express-redis-nodemon/app/views/error.hjs deleted file mode 100644 index 36a6196..0000000 --- a/05-nginx-express-redis-nodemon/app/views/error.hjs +++ /dev/null @@ -1,3 +0,0 @@ -

{{ message }}

-

{{ error.status }}

-
{{ error.stack }}
diff --git a/05-nginx-express-redis-nodemon/app/views/index.hjs b/05-nginx-express-redis-nodemon/app/views/index.hjs deleted file mode 100644 index d384f88..0000000 --- a/05-nginx-express-redis-nodemon/app/views/index.hjs +++ /dev/null @@ -1,12 +0,0 @@ - - - - {{ title }} - - - -

{{ title }}

-

Welcome to {{ title }}.

-

This page has been requested {{ counter }} times.

- - diff --git a/05-nginx-express-redis-nodemon/docker-compose.yml b/05-nginx-express-redis-nodemon/docker-compose.yml deleted file mode 100644 index 2ffeb8d..0000000 --- a/05-nginx-express-redis-nodemon/docker-compose.yml +++ /dev/null @@ -1,24 +0,0 @@ -web: - build: ./app - volumes: - - "./app:/src/app" - ports: - - "3030:3000" - links: - - "db:redis" - command: nodemon -L app/bin/www - -nginx: - restart: always - build: ./nginx/ - ports: - - "80:80" - volumes: - - /www/public - volumes_from: - - web - links: - - web:web - -db: - image: redis diff --git a/05-nginx-express-redis-nodemon/nginx/Dockerfile b/05-nginx-express-redis-nodemon/nginx/Dockerfile deleted file mode 100644 index 2a99696..0000000 --- a/05-nginx-express-redis-nodemon/nginx/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM tutum/nginx -RUN rm /etc/nginx/sites-enabled/default -ADD sites-enabled/ /etc/nginx/sites-enabled diff --git a/05-nginx-express-redis-nodemon/nginx/sites-enabled/nodejs_project b/05-nginx-express-redis-nodemon/nginx/sites-enabled/nodejs_project deleted file mode 100644 index d5edd40..0000000 --- a/05-nginx-express-redis-nodemon/nginx/sites-enabled/nodejs_project +++ /dev/null @@ -1,19 +0,0 @@ -server { - - listen 80; - server_name example.org; - access_log /var/log/nginx/nodejs_project.log; - charset utf-8; - - location /public { - alias /src/app/public; - } - - location / { - proxy_pass http://web:3000; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - -} diff --git a/README.md b/README.md index fae6f7f..5d7b38d 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,6 @@ -# Getting started with ~~Fig~~ Docker Compose and Nodejs +# Getting Started with Docker Compose and Node.js -## Motivation - -*Update 02/26/2015: Fig has been renamed "Docker Compose"* - -[Docker Compose](http://docs.docker.com/compose/) is an awesome tool for creating isolated development environments with [Docker](http://docker.com) by using simple configurations with [YAML](http://www.yaml.org/). It's clean and easy enough to wrap your head around, even if you are new to Docker. Even though, the official website is lacking some practial, real world examples for getting started with Docker Compose and Nodejs. - -If you're like me, you are using a development server like [nodemon](https://github.com/remy/nodemon) that watches all your file changes and restarts your app accordingly. Bringing this workflow over to Docker Compose (nΓ©e Fig) is a bit tricky. You can find many Github repositories that aim to show you how to do it, but not one (at least of the ones I found) of them are not suitable for "real world" development. Most of them even require you to rebuild your Dockerfile to reflect file changes - _seriously?!_ - -I hope the following real world examples will save you from some headache (like I had) while trying to figure out how to (pragmatically) use Docker Compose for your Nodejs apps. - -## Examples - -### Basic skeleton with Express app generator -[https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/00-basic-express-generator](https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/00-basic-express-generator) - -### Express app with nodemon development server -[https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/01-express-nodemon](https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/01-express-nodemon) - -### Express app with Redis and nodemon development server -[https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/02-express-redis-nodemon](https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/02-express-redis-nodemon) - -### Express app with Gulp.js build system -[https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/03-express-gulp-watch](https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/03-express-gulp-watch) - -### Express app with Grunt.js build system -[https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/04-express-grunt-watch](https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/04-express-grunt-watch) - -### Nginx, Express, Redis and nodemon -[https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/05-nginx-express-redis-nodemon](https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/05-nginx-express-redis-nodemon) - -More to come... +Version 2.0 coming soon... ## Maintainer @@ -44,7 +14,7 @@ Pascal Cremer > The MIT License (MIT) > -> Copyright (c) 2014-2016 Pascal Cremer +> Copyright (c) 2014-2017 Pascal Cremer > >Permission is hereby granted, free of charge, to any person obtaining a copy >of this software and associated documentation files (the "Software"), to deal diff --git a/bin/builder b/bin/builder new file mode 100755 index 0000000..e515fa2 --- /dev/null +++ b/bin/builder @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../index'); diff --git a/builder.js b/builder.js new file mode 100644 index 0000000..d2c6c79 --- /dev/null +++ b/builder.js @@ -0,0 +1,136 @@ +const fs = require('fs-promise'); +const path = require('path'); +const Mustache = require('mustache'); +const glob = require('glob-promise'); +const Promise = require('bluebird'); +const lodash = require('lodash'); +const chalk = require('chalk'); + +const error = chalk.bold.red; + +const logError = (message) => console.error(error(`Error: ${message}`)); + +const copyTemplate = (src) => (dest = __dirname + '/build') => { + return fs + .access(dest, fs.constants.W_OK) + .then( + () => fs.remove(dest), + err => { + if ('ENOENT' === err.code) { + return + } + + if ('EACCES' === err.code) { + logError(`No write access for ${dest}`); + } + + throw err; + } + ) + .then(() => fs.copy(src, dest)) + ; +}; + +const moduleMappings = { + minimal : {deps: [], devDeps: ['nodemon']}, + express : { + deps: [ + 'express', + 'mustache', + 'mustache-express' + ], + devDeps: [ + 'nodemon' + ] + }, + mysql : {deps: ['mysql'], devDeps: []}, + postgres : {deps: ['pg'], devDeps: []}, + mongodb : {deps: ['mongoose'], devDeps: []}, + es6 : {deps: [], devDeps: ['babel-cli', 'babel-preset-env']}, + react : { + deps: [ + 'react', + 'react-dom', + 'redux', + 'react-redux' + ], + devDeps: [ + 'babel-cli', + 'babel-preset-react', + 'redux-devtools' + ], + }, + vue : { + deps: [ + 'vue' + ], + devDeps: [ + 'babel-cli', + 'babel-preset-vue-app' + ] + }, + make : {deps: [], devDeps: []}, + gulp : {deps: [], devDeps: ['gulp']}, + webpack : {deps: [], devDeps: ['webpack']} +}; + +const determineNodeModules = (answers = {}) => { + const temp = Object + .keys(answers) + .reduce((acc, key) => { + const value = answers[key]; + if (!value) { + return acc; + } + + return { + deps: lodash.uniq(acc.deps.concat(moduleMappings[value].deps)), + devDeps: lodash.uniq(acc.devDeps.concat(moduleMappings[value].devDeps)), + } + }, {deps: [], devDeps: []} + ); + + return { + deps: temp.deps.join(' '), + devDeps: temp.devDeps.join(' ') + } +} + +const generateCommonTemplates = (answers) => (dest = __dirname + '/build') => { + const modules = determineNodeModules(answers); + + return glob(__dirname + '/templates/common/**/*.mustache') + .then((files) => { + const promises = files.map((file) => { + const relativePath = path.relative(__dirname + '/templates/common', file.replace('\.mustache', '')); + const destPath = `${dest}/${relativePath}`; + + return fs + .ensureDir(path.dirname(destPath)) + .then(() => fs.readFile(file)) + .then((buf) => { + return Mustache.render(buf.toString('utf-8'), modules); + }) + .then((output) => fs.writeFile(destPath, output)) + ; + }) + + return Promise.all(promises); + }) + .then(() => glob(dest + '/docker/**/*')) + .then((files) => { + const promises = files.map((file) => fs.chmod(file, 0751)); + + return Promise.all(promises); + }) + ; +}; + +const builder = function builder(answers) { + return { + copyTemplate: copyTemplate(__dirname + '/templates/' + answers.skeleton), + generateCommonTemplates: generateCommonTemplates(answers) + } +} + +module.exports = builder; diff --git a/index.js b/index.js new file mode 100644 index 0000000..e20c872 --- /dev/null +++ b/index.js @@ -0,0 +1,93 @@ +const inquirer = require('inquirer'); +const chalk = require('chalk'); +const builder = require('./builder'); + +const askForSkeleton = { + name: 'skeleton', + message: 'Which type of Node.js app?', + type: 'list', + choices: [ + {name: 'Minimal', value: 'minimal'}, + {name: 'Express.js', value: 'express'} + ], +}; + +const askForDatabase = { + name: 'database', + message: 'Which Database do you want to use?', + type: 'list', + choices: [ + {name: 'None', value: null}, + {name: 'MySQL', value: 'mysql'}, + {name: 'PostgreSQL', value: 'postgres'}, + {name: 'MongoDB', value: 'mongodb'} + ], + when: (currentAnswers) => { + const { skeleton } = currentAnswers; + if (!!skeleton && 'minimal' === skeleton) { + return false; + } + + return true; + } +}; + +const askForFancyFrontend = { + name: 'fancyFrontend', + message: 'Do you want a fancy front end?', + type: 'list', + choices: [ + {name: 'God no!', value: null}, + {name: 'Babel/ES6', value: 'es6'}, + {name: 'React/Redux', value: 'react'}, + {name: 'Vue.js', value: 'vue'} + ], + when: (currentAnswers) => { + const { skeleton } = currentAnswers; + if (!!skeleton && 'minimal' === skeleton) { + return false; + } + + return true; + } +}; + +const askForBuildTool = { + name: 'buildTool', + message: 'How do you want to build your front end?', + type: 'list', + choices: [ + {name: 'Makefile', value: 'make'}, + {name: 'Gulp.js', value: 'gulp'}, + {name: 'Webpack', value: 'webpack'} + ], + when: (currentAnswers) => { + const { skeleton, fancyFrontend } = currentAnswers; + if ((!!skeleton && 'minimal' === skeleton) || !fancyFrontend) { + return false; + } + + return true; + } +} + +inquirer + .prompt([ + askForSkeleton, + askForDatabase, + askForFancyFrontend, + askForBuildTool + ]) + .then((answers) => { + const b = builder(answers); + return b + .copyTemplate() + .then(b.generateCommonTemplates) + .then(() => { + console.log(chalk.green.bold('\nAlright! Your app of choice is ready πŸŽ‰')); + console.log(`Please run ${chalk.green.bold('cd build; ./docker/install')} to install dependencies`); + console.log(`When done, run ${chalk.green.bold('docker-compose up')} to launch your app`); + }) + ; + }) +; diff --git a/package.json b/package.json new file mode 100644 index 0000000..df018be --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "dependencies": { + "bluebird": "^3.5.0", + "chalk": "^1.1.3", + "child-process-promise": "^2.2.1", + "fs-promise": "^2.0.2", + "glob": "^7.1.1", + "glob-promise": "^3.1.0", + "inquirer": "^3.0.6", + "lodash": "^4.17.4", + "mustache": "^2.3.0", + "npm": "^4.4.4", + "through": "^2.3.8" + } +} diff --git a/templates/common/Dockerfile.mustache b/templates/common/Dockerfile.mustache new file mode 100644 index 0000000..a0d7b39 --- /dev/null +++ b/templates/common/Dockerfile.mustache @@ -0,0 +1,5 @@ +FROM node:6 + +COPY . /app + +WORKDIR /app diff --git a/templates/common/docker/install.mustache b/templates/common/docker/install.mustache new file mode 100755 index 0000000..3d63241 --- /dev/null +++ b/templates/common/docker/install.mustache @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +docker-compose build + +{{#deps}} +docker-compose run web npm install --save {{ deps }} +{{/deps}} +{{#devDeps}} +docker-compose run web npm install --save-dev {{ devDeps }} +{{/devDeps}} diff --git a/templates/express/docker-compose.yml b/templates/express/docker-compose.yml new file mode 100644 index 0000000..49c9d73 --- /dev/null +++ b/templates/express/docker-compose.yml @@ -0,0 +1,9 @@ +version: '2' +services: + web: + build: . + ports: + - "3000:3000" + command: npm run start-dev + volumes: + - .:/app diff --git a/templates/express/index.js b/templates/express/index.js new file mode 100644 index 0000000..f8ec7ea --- /dev/null +++ b/templates/express/index.js @@ -0,0 +1,17 @@ +const express = require('express'); +const app = express(); + +// Configure Mustache templates +const mustacheExpress = require('mustache-express'); +app.engine('mustache', mustacheExpress()); +app.set('view engine', 'mustache'); +app.set('views', __dirname + '/views'); + +// Connect routers +app.use(require('./site/router')); + +const port = 3000; + +app.listen(port, () => { + console.log(`Express app listening on port ${port}`); +}); diff --git a/templates/express/package.json b/templates/express/package.json new file mode 100644 index 0000000..ec79d0c --- /dev/null +++ b/templates/express/package.json @@ -0,0 +1,6 @@ +{ + "scripts": { + "start": "node index.js", + "start-dev": "node_modules/.bin/nodemon -e js,mustache index.js" + } +} diff --git a/templates/express/site/router.js b/templates/express/site/router.js new file mode 100644 index 0000000..2e57cae --- /dev/null +++ b/templates/express/site/router.js @@ -0,0 +1,10 @@ +const express = require('express'); +const router = new express.Router(); + +const home = (req, res) => { + return res.render('index'); +} + +router.get('/', home); + +module.exports = router; diff --git a/templates/express/views/index.mustache b/templates/express/views/index.mustache new file mode 100644 index 0000000..4b24916 --- /dev/null +++ b/templates/express/views/index.mustache @@ -0,0 +1,22 @@ + + + + + docker-compose-nodejs-examples + + + + + +

Hello From Express & Docker.

+ + + diff --git a/templates/minimal/docker-compose.yml b/templates/minimal/docker-compose.yml new file mode 100644 index 0000000..49c9d73 --- /dev/null +++ b/templates/minimal/docker-compose.yml @@ -0,0 +1,9 @@ +version: '2' +services: + web: + build: . + ports: + - "3000:3000" + command: npm run start-dev + volumes: + - .:/app diff --git a/templates/minimal/index.js b/templates/minimal/index.js new file mode 100644 index 0000000..5586fef --- /dev/null +++ b/templates/minimal/index.js @@ -0,0 +1,14 @@ +const http = require('http'); + +const hostname = '0.0.0.0'; +const port = 3000; + +const server = http.createServer((req, res) => { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/plain'); + res.end('Hello from Node.js & Docker\n'); +}); + +server.listen(port, hostname, () => { + console.log(`Server running at http://${hostname}:${port}/`); +}); diff --git a/templates/minimal/package.json b/templates/minimal/package.json new file mode 100644 index 0000000..502e63b --- /dev/null +++ b/templates/minimal/package.json @@ -0,0 +1,6 @@ +{ + "scripts": { + "start": "node index.js", + "start-dev": "node_modules/.bin/nodemon index.js" + } +} From 381982c5cdae8774f2efa7cc52f061bbd146997d Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Sat, 8 Apr 2017 19:17:41 +0200 Subject: [PATCH 02/52] Prepare for database integration --- builder.js | 54 ++++++++++++-------- index.js | 1 + package.json | 8 +-- templates/common/docker-compose.yml.mustache | 24 +++++++++ templates/express/api/router.js | 45 ++++++++++++++++ templates/express/database/index.js | 30 +++++++++++ templates/express/docker-compose.yml | 9 ---- templates/express/index.js | 9 ++++ templates/express/site/router.js | 4 +- templates/minimal/docker-compose.yml | 9 ---- 10 files changed, 144 insertions(+), 49 deletions(-) create mode 100644 templates/common/docker-compose.yml.mustache create mode 100644 templates/express/api/router.js create mode 100644 templates/express/database/index.js delete mode 100644 templates/express/docker-compose.yml delete mode 100644 templates/minimal/docker-compose.yml diff --git a/builder.js b/builder.js index d2c6c79..800b24a 100644 --- a/builder.js +++ b/builder.js @@ -2,15 +2,14 @@ const fs = require('fs-promise'); const path = require('path'); const Mustache = require('mustache'); const glob = require('glob-promise'); -const Promise = require('bluebird'); -const lodash = require('lodash'); +const uniq = require('lodash.uniq'); const chalk = require('chalk'); const error = chalk.bold.red; -const logError = (message) => console.error(error(`Error: ${message}`)); +const logError = message => console.error(error(`Error: ${message}`)); -const copyTemplate = (src) => (dest = __dirname + '/build') => { +const copyTemplate = src => (dest = __dirname + '/build') => { return fs .access(dest, fs.constants.W_OK) .then( @@ -35,7 +34,9 @@ const moduleMappings = { minimal : {deps: [], devDeps: ['nodemon']}, express : { deps: [ + 'body-parser', 'express', + 'lodash.find', 'mustache', 'mustache-express' ], @@ -84,8 +85,8 @@ const determineNodeModules = (answers = {}) => { } return { - deps: lodash.uniq(acc.deps.concat(moduleMappings[value].deps)), - devDeps: lodash.uniq(acc.devDeps.concat(moduleMappings[value].devDeps)), + deps: uniq(acc.deps.concat(moduleMappings[value].deps)), + devDeps: uniq(acc.devDeps.concat(moduleMappings[value].devDeps)), } }, {deps: [], devDeps: []} ); @@ -96,41 +97,50 @@ const determineNodeModules = (answers = {}) => { } } -const generateCommonTemplates = (answers) => (dest = __dirname + '/build') => { +const generateCommonTemplates = answers => (dest = `${__dirname}/build`) => { const modules = determineNodeModules(answers); + const templateContext = Object.assign({}, answers, modules); - return glob(__dirname + '/templates/common/**/*.mustache') - .then((files) => { - const promises = files.map((file) => { - const relativePath = path.relative(__dirname + '/templates/common', file.replace('\.mustache', '')); + return glob(`${__dirname}/templates/common/**/*.mustache`) + .then(files => { + const promises = files.map(file => { + const relativePath = path.relative(`${__dirname}/templates/common`, file.replace('\.mustache', '')); const destPath = `${dest}/${relativePath}`; return fs .ensureDir(path.dirname(destPath)) .then(() => fs.readFile(file)) - .then((buf) => { - return Mustache.render(buf.toString('utf-8'), modules); - }) - .then((output) => fs.writeFile(destPath, output)) + .then(buf => Mustache.render(buf.toString('utf-8'), templateContext)) + .then(output => fs.writeFile(destPath, output)) ; }) return Promise.all(promises); }) - .then(() => glob(dest + '/docker/**/*')) - .then((files) => { + .then(() => glob(`${dest}/docker/**/*`)) + .then(files => { const promises = files.map((file) => fs.chmod(file, 0751)); return Promise.all(promises); }) + .then(() => undefined) ; }; -const builder = function builder(answers) { - return { - copyTemplate: copyTemplate(__dirname + '/templates/' + answers.skeleton), - generateCommonTemplates: generateCommonTemplates(answers) +const prepareDatabase = answers => (dest = `${__dirname}/build`) => { + if (!answers.database) { + return Promise.resolve(); } -} + + console.log(dest); + + return fs.copy(`${__dirname}/templates/${answers.database}`, dest); +}; + +const builder = answers => ({ + copyTemplate: copyTemplate(`${__dirname}/templates/${answers.skeleton}`), + generateCommonTemplates: generateCommonTemplates(answers), + prepareDatabase: prepareDatabase(answers) +}); module.exports = builder; diff --git a/index.js b/index.js index e20c872..e244e61 100644 --- a/index.js +++ b/index.js @@ -83,6 +83,7 @@ inquirer return b .copyTemplate() .then(b.generateCommonTemplates) + .then(b.prepareDatabase) .then(() => { console.log(chalk.green.bold('\nAlright! Your app of choice is ready πŸŽ‰')); console.log(`Please run ${chalk.green.bold('cd build; ./docker/install')} to install dependencies`); diff --git a/package.json b/package.json index df018be..9401688 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,11 @@ { "dependencies": { - "bluebird": "^3.5.0", "chalk": "^1.1.3", - "child-process-promise": "^2.2.1", "fs-promise": "^2.0.2", "glob": "^7.1.1", "glob-promise": "^3.1.0", "inquirer": "^3.0.6", - "lodash": "^4.17.4", - "mustache": "^2.3.0", - "npm": "^4.4.4", - "through": "^2.3.8" + "lodash.uniq": "^4.5.0", + "mustache": "^2.3.0" } } diff --git a/templates/common/docker-compose.yml.mustache b/templates/common/docker-compose.yml.mustache new file mode 100644 index 0000000..221df1c --- /dev/null +++ b/templates/common/docker-compose.yml.mustache @@ -0,0 +1,24 @@ +version: '2' +services: + web: + build: . + ports: + - "3000:3000" + volumes: + - .:/app +{{#database}} + environment: + - DATABASE_HOST=${DATABASE_HOST} + - DATABASE_PORT=${DATABASE_PORT} +{{/database}} + command: npm run start-dev +{{#database}} + volumes: + - .:/app +{{/database}} +{{#database}} + db: + extends: + file: database-service.yml + service: database +{{/database}} diff --git a/templates/express/api/router.js b/templates/express/api/router.js new file mode 100644 index 0000000..2853a6b --- /dev/null +++ b/templates/express/api/router.js @@ -0,0 +1,45 @@ +const express = require('express'); +const database = require('../database'); +const router = new express.Router(); + +const createPost = (req, res) => { + const { author, body } = req.body; + + return database + .addNewPost(author, body) + .then( + post => res.status(201).end(), + err => res.status(500).send({ err: 'Oops, something went wrong!' }) + ) + ; +} + +const listPosts = (req, res) => { + res.setHeader('Content-Type', 'application/json'); + + return database + .getPosts() + .then( + posts => res.send(posts), + err => res.status(500).send({ err: 'Oops, something went wrong!' }) + ) + ; +} + +const showPost = (req, res) => { + res.setHeader('Content-Type', 'application/json'); + + return database + .getPostById(req.params.id) + .then( + post => res.send(post), + err => res.status(500).send({ err: 'Oops, something went wrong!' }) + ) + ; +} + +router.post('/comments', createPost); +router.get('/comments', listPosts); +router.get('/comments/:id', showPost); + +module.exports = router; diff --git a/templates/express/database/index.js b/templates/express/database/index.js new file mode 100644 index 0000000..5c07de5 --- /dev/null +++ b/templates/express/database/index.js @@ -0,0 +1,30 @@ +const find = require('lodash.find'); + +const init = () => {} + +let commentId = 1; + +const fakeDatabase = [ + { + id: commentId++, + author: 'John Doe', + body: 'I ❀️ Docker Compose!' + }, + { + id: commentId++, + author: 'Jane Doe', + body: 'This is some cool stuff! πŸŽ‰' + } +]; + +const addNewPost = (author, body) => { + fakeDatabase.push({ id: commentId++, author, body }); + + return Promise.resolve(commentId); +} + +const getPosts = () => Promise.resolve(fakeDatabase); + +const getPostById = id => Promise.resolve(find(fakeDatabase, post => id == post.id)); + +module.exports = { init, addNewPost, getPosts, getPostById }; diff --git a/templates/express/docker-compose.yml b/templates/express/docker-compose.yml deleted file mode 100644 index 49c9d73..0000000 --- a/templates/express/docker-compose.yml +++ /dev/null @@ -1,9 +0,0 @@ -version: '2' -services: - web: - build: . - ports: - - "3000:3000" - command: npm run start-dev - volumes: - - .:/app diff --git a/templates/express/index.js b/templates/express/index.js index f8ec7ea..f7b439c 100644 --- a/templates/express/index.js +++ b/templates/express/index.js @@ -1,14 +1,23 @@ const express = require('express'); +const bodyParser = require('body-parser'); +const database = require('./database'); const app = express(); +// Use body parser for requests with JSON payloads +app.use(bodyParser.json()); + // Configure Mustache templates const mustacheExpress = require('mustache-express'); app.engine('mustache', mustacheExpress()); app.set('view engine', 'mustache'); app.set('views', __dirname + '/views'); +// initialize database +database.init(); + // Connect routers app.use(require('./site/router')); +app.use('/api', require('./api/router')); const port = 3000; diff --git a/templates/express/site/router.js b/templates/express/site/router.js index 2e57cae..9534dc0 100644 --- a/templates/express/site/router.js +++ b/templates/express/site/router.js @@ -1,9 +1,7 @@ const express = require('express'); const router = new express.Router(); -const home = (req, res) => { - return res.render('index'); -} +const home = (req, res) => res.render('index'); router.get('/', home); diff --git a/templates/minimal/docker-compose.yml b/templates/minimal/docker-compose.yml deleted file mode 100644 index 49c9d73..0000000 --- a/templates/minimal/docker-compose.yml +++ /dev/null @@ -1,9 +0,0 @@ -version: '2' -services: - web: - build: . - ports: - - "3000:3000" - command: npm run start-dev - volumes: - - .:/app From 307d1ee22785e0dce1460ede628624351621de3f Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Sat, 8 Apr 2017 20:17:52 +0200 Subject: [PATCH 03/52] Add templates for MongoDB --- templates/mongodb/.env | 2 ++ templates/mongodb/database-service.yml | 4 +++ templates/mongodb/database/index.js | 37 ++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 templates/mongodb/.env create mode 100644 templates/mongodb/database-service.yml create mode 100644 templates/mongodb/database/index.js diff --git a/templates/mongodb/.env b/templates/mongodb/.env new file mode 100644 index 0000000..b9baaa7 --- /dev/null +++ b/templates/mongodb/.env @@ -0,0 +1,2 @@ +DATABASE_HOST=db +DATABASE_PORT=27017 diff --git a/templates/mongodb/database-service.yml b/templates/mongodb/database-service.yml new file mode 100644 index 0000000..d25fba9 --- /dev/null +++ b/templates/mongodb/database-service.yml @@ -0,0 +1,4 @@ +version: '2' +services: + database: + image: mongo diff --git a/templates/mongodb/database/index.js b/templates/mongodb/database/index.js new file mode 100644 index 0000000..47e63e6 --- /dev/null +++ b/templates/mongodb/database/index.js @@ -0,0 +1,37 @@ +const mongoose = require('mongoose'); +mongoose.Promise = global.Promise; + +const dbHost = process.env.DATABASE_HOST; +const dbPort = process.env.DATABASE_PORT; + +const init = ({ host, port } = { host: dbHost, port: dbPort }) => { + mongoose.connect(`mongodb://${host}:${port}`); +}; + +// Set up Mongoose model +const commentSchema = new mongoose.Schema({ + author: String, + body: String, +}) + +commentSchema.set('toJSON', { + transform: (doc, ret, options) => { + ret.id = ret._id; + delete ret._id; + delete ret.__v; + } +}); + +const Comment = mongoose.model('Comment', commentSchema); + +const addNewPost = (author, body) => { + const comment = new Comment({ author, body }); + + return comment.save().then(savedComment => savedComment.id); +} + +const getPosts = () => Comment.find().exec(); + +const getPostById = id => Comment.findById(id).exec(); + +module.exports = { init, addNewPost, getPosts, getPostById }; From bb8358ec9de075b6bd71b38314c66bc743e8da8d Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Sun, 9 Apr 2017 00:22:33 +0200 Subject: [PATCH 04/52] Wait for database containers --- templates/common/Dockerfile.mustache | 3 +++ templates/common/docker-compose.yml.mustache | 14 +++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/templates/common/Dockerfile.mustache b/templates/common/Dockerfile.mustache index a0d7b39..2d3c3e0 100644 --- a/templates/common/Dockerfile.mustache +++ b/templates/common/Dockerfile.mustache @@ -1,5 +1,8 @@ FROM node:6 +RUN curl https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh > /docker-wait \ + && chmod +x /docker-wait + COPY . /app WORKDIR /app diff --git a/templates/common/docker-compose.yml.mustache b/templates/common/docker-compose.yml.mustache index 221df1c..5dfbb1a 100644 --- a/templates/common/docker-compose.yml.mustache +++ b/templates/common/docker-compose.yml.mustache @@ -6,16 +6,24 @@ services: - "3000:3000" volumes: - .:/app -{{#database}} environment: +{{#database}} - DATABASE_HOST=${DATABASE_HOST} - DATABASE_PORT=${DATABASE_PORT} + - DATABASE_USER=${DATABASE_USER} + - DATABASE_PASS=${DATABASE_PASS} + - DATABASE_NAME=${DATABASE_NAME} {{/database}} - command: npm run start-dev + command: {{#database}} + - /docker-wait + - db:${DATABASE_PORT} + - --timeout=60 + - -- +{{/database}} + - npm run start-dev volumes: - .:/app -{{/database}} {{#database}} db: extends: From e8e63df0eb1d235863aaf67abac708e5dc510fd4 Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Sun, 9 Apr 2017 00:22:51 +0200 Subject: [PATCH 05/52] Add MariaDB/MySQL templates --- templates/mysql/.env | 5 ++ templates/mysql/database-service.yml | 9 +++ templates/mysql/database/index.js | 85 ++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 templates/mysql/.env create mode 100644 templates/mysql/database-service.yml create mode 100644 templates/mysql/database/index.js diff --git a/templates/mysql/.env b/templates/mysql/.env new file mode 100644 index 0000000..91b3468 --- /dev/null +++ b/templates/mysql/.env @@ -0,0 +1,5 @@ +DATABASE_HOST=db +DATABASE_PORT=3306 +DATABASE_USER=node +DATABASE_PASS=s3cr3t +DATABASE_NAME=app_db diff --git a/templates/mysql/database-service.yml b/templates/mysql/database-service.yml new file mode 100644 index 0000000..9766c76 --- /dev/null +++ b/templates/mysql/database-service.yml @@ -0,0 +1,9 @@ +version: '2' +services: + database: + image: mariadb + environment: + - MYSQL_USER=${DATABASE_USER} + - MYSQL_PASSWORD=${DATABASE_PASS} + - MYSQL_DATABASE=${DATABASE_NAME} + - MYSQL_RANDOM_ROOT_PASSWORD=yes \ No newline at end of file diff --git a/templates/mysql/database/index.js b/templates/mysql/database/index.js new file mode 100644 index 0000000..2b55de0 --- /dev/null +++ b/templates/mysql/database/index.js @@ -0,0 +1,85 @@ +const mysql = require('mysql'); + +const dbHost = process.env.DATABASE_HOST; +const dbPort = process.env.DATABASE_PORT; +const dbUser = process.env.DATABASE_USER; +const dbPass = process.env.DATABASE_PASS; +const dbName = process.env.DATABASE_NAME; + +let connection; + +const init = ({ host, port, user, password, database } = { + host: dbHost, + port: dbPort, + user: dbUser, + password: dbPass, + database: dbName +}) => { + connection = mysql.createConnection({ + host, + port, + user, + password, + database + }); + + // For a real world app, you probably want to check if there were any + // any exceptions and handle them... + createTable(); +}; + +const createTableStmt = ` +CREATE TABLE IF NOT EXISTS comments ( + id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, + author VARCHAR(100) NOT NULL, + body TEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) +`; + +const createTable = () => new Promise((resolve, reject) => { + connection.query(createTableStmt, err => { + if (err) { + return reject(err); + } + + return resolve(); + }); +}); + +const addNewPost = (author, body) => new Promise((resolve, reject) => { + connection.query('INSERT INTO comments SET ?', { author, body }, err => { + if (err) { + return reject(err); + } + + return resolve(); + }); +}); + +const getPosts = () => new Promise((resolve, reject) => { + connection.query('SELECT * FROM comments', (err, results) => { + if (err) { + return reject(err); + } + + return resolve(results); + }); +}); + +const getPostById = id => new Promise((resolve, reject) => { + connection.query( + 'SELECT * FROM comments WHERE id = ? LIMIT 1', + [id], + (err, results) => { + if (err) { + return reject(err); + } + + return resolve(results); + } + ); +}); + +module.exports = { init, addNewPost, getPosts, getPostById } From e21cb12886cf66fbbcc7cf92118b0740af24586a Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Sun, 9 Apr 2017 00:23:02 +0200 Subject: [PATCH 06/52] Add PostgreSQL templates --- templates/postgres/.env | 5 ++ templates/postgres/database-service.yml | 8 +++ templates/postgres/database/index.js | 65 +++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 templates/postgres/.env create mode 100644 templates/postgres/database-service.yml create mode 100644 templates/postgres/database/index.js diff --git a/templates/postgres/.env b/templates/postgres/.env new file mode 100644 index 0000000..ff0b8e2 --- /dev/null +++ b/templates/postgres/.env @@ -0,0 +1,5 @@ +DATABASE_HOST=db +DATABASE_PORT=5432 +DATABASE_USER=node +DATABASE_PASS=s3cr3t +DATABASE_NAME=app_db diff --git a/templates/postgres/database-service.yml b/templates/postgres/database-service.yml new file mode 100644 index 0000000..a83262d --- /dev/null +++ b/templates/postgres/database-service.yml @@ -0,0 +1,8 @@ +version: '2' +services: + database: + image: postgres + environment: + - POSTGRES_USER=${DATABASE_USER} + - POSTGRES_PASSWORD=${DATABASE_PASS} + - POSTGRES_DB=${DATABASE_NAME} diff --git a/templates/postgres/database/index.js b/templates/postgres/database/index.js new file mode 100644 index 0000000..9931f7d --- /dev/null +++ b/templates/postgres/database/index.js @@ -0,0 +1,65 @@ +const pg = require('pg'); + +const dbHost = process.env.DATABASE_HOST; +const dbPort = process.env.DATABASE_PORT; +const dbUser = process.env.DATABASE_USER; +const dbPass = process.env.DATABASE_PASS; +const dbName = process.env.DATABASE_NAME; + +let pool; + +const init = ({ host, port, user, password, database } = { + host: dbHost, + port: dbPort, + user: dbUser, + password: dbPass, + database: dbName +}) => { + pool = new pg.Pool({ + host, + port, + user, + password, + database + }); + + // For a real world app, you probably want to check if there were any + // any exceptions and handle them... + createTable(); +}; + +const createTableStmt = ` +CREATE TABLE IF NOT EXISTS comments ( + id serial PRIMARY KEY, + author VARCHAR (100) NOT NULL, + body VARCHAR (50) NOT NULL, + created_on TIMESTAMP NOT NULL DEFAULT CURRENT_DATE +) +`; + +const createTable = () => pool.query(createTableStmt); + +const addNewPost = (author, body) => pool.query( + 'INSERT INTO comments (author, body) VALUES ($1, $2)', + [author, body] +); + +const getPosts = () => pool + .query('SELECT * FROM comments') + .then(result => result.rows) +; + +const getPostById = id => { + return pool + .query('SELECT * FROM comments WHERE id = $1', [id]) + .then(result => { + if (Array.isArray(result.rows)) { + return result.rows[0]; + } + + return result; + }) + ; +} + +module.exports = { init, addNewPost, getPosts, getPostById } From 3402f03023d6b17c6a7f5f6b655390377d371f10 Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Mon, 10 Apr 2017 13:25:57 +0200 Subject: [PATCH 07/52] Switch from Mustache to Pug for Express template --- builder.js | 3 +-- templates/express/index.js | 6 ++--- templates/express/package.json | 2 +- templates/express/views/includes/comments.pug | 16 ++++++++++++++ templates/express/views/index.mustache | 22 ------------------- templates/express/views/index.pug | 19 ++++++++++++++++ 6 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 templates/express/views/includes/comments.pug delete mode 100644 templates/express/views/index.mustache create mode 100644 templates/express/views/index.pug diff --git a/builder.js b/builder.js index 800b24a..9c3d743 100644 --- a/builder.js +++ b/builder.js @@ -37,8 +37,7 @@ const moduleMappings = { 'body-parser', 'express', 'lodash.find', - 'mustache', - 'mustache-express' + 'pug', ], devDeps: [ 'nodemon' diff --git a/templates/express/index.js b/templates/express/index.js index f7b439c..4164d9f 100644 --- a/templates/express/index.js +++ b/templates/express/index.js @@ -6,10 +6,8 @@ const app = express(); // Use body parser for requests with JSON payloads app.use(bodyParser.json()); -// Configure Mustache templates -const mustacheExpress = require('mustache-express'); -app.engine('mustache', mustacheExpress()); -app.set('view engine', 'mustache'); +// Configure Pug templates +app.set('view engine', 'pug'); app.set('views', __dirname + '/views'); // initialize database diff --git a/templates/express/package.json b/templates/express/package.json index ec79d0c..3182d62 100644 --- a/templates/express/package.json +++ b/templates/express/package.json @@ -1,6 +1,6 @@ { "scripts": { "start": "node index.js", - "start-dev": "node_modules/.bin/nodemon -e js,mustache index.js" + "start-dev": "node_modules/.bin/nodemon -e js,pug index.js" } } diff --git a/templates/express/views/includes/comments.pug b/templates/express/views/includes/comments.pug new file mode 100644 index 0000000..a83e8ae --- /dev/null +++ b/templates/express/views/includes/comments.pug @@ -0,0 +1,16 @@ +p.lead Please leave some feedback down in the comments. +ul.comments + each post in posts + li(class='comment' id='comment_' + post.id) + div + h3 #{post.author} #[small wrote a comment] + blockquote + p= post.body +form(method='post', action='/') + div.form-group + label(for='author') Author + input(type='text', class='form-control', name='author' id='author', placeholder='Your name') + div.form-group + label(for='body') Comment + textarea(class='form-control', name='body' id='body', placeholder='Tell us something') + button(type='submit' class='btn btn-default btn-primary') Submit Comment diff --git a/templates/express/views/index.mustache b/templates/express/views/index.mustache deleted file mode 100644 index 4b24916..0000000 --- a/templates/express/views/index.mustache +++ /dev/null @@ -1,22 +0,0 @@ - - - - - docker-compose-nodejs-examples - - - - - -

Hello From Express & Docker.

- - - diff --git a/templates/express/views/index.pug b/templates/express/views/index.pug new file mode 100644 index 0000000..9934d2e --- /dev/null +++ b/templates/express/views/index.pug @@ -0,0 +1,19 @@ +doctype html +html + head + link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous') + style(type='text/css'). + body { + padding: 40px; + } + + ul.comments { + padding: 0; + list-style: none; + } + body + h1 Hello From Express & Docker. + + hr + + include includes/comments.pug From ef3c2ddd2370ec3514b97e42e42e7390db14bff9 Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Mon, 10 Apr 2017 13:26:28 +0200 Subject: [PATCH 08/52] Add Comment form for Express template --- templates/express/index.js | 3 ++- templates/express/site/router.js | 28 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/templates/express/index.js b/templates/express/index.js index 4164d9f..f96c482 100644 --- a/templates/express/index.js +++ b/templates/express/index.js @@ -3,7 +3,8 @@ const bodyParser = require('body-parser'); const database = require('./database'); const app = express(); -// Use body parser for requests with JSON payloads +// Use body parser +app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()); // Configure Pug templates diff --git a/templates/express/site/router.js b/templates/express/site/router.js index 9534dc0..5853881 100644 --- a/templates/express/site/router.js +++ b/templates/express/site/router.js @@ -1,8 +1,34 @@ const express = require('express'); +const database = require('../database'); const router = new express.Router(); -const home = (req, res) => res.render('index'); +const saveComment = (req, res) => { + const { author, body } = req.body; + + if (!author || !body) { + return res.redirect('/'); + } + + return database + .addNewPost(author, body) + .then( + () => res.redirect('/'), + err => res.status(500).send('Oops, something went wrong!') + ) + ; +} + +const home = (req, res) => { + return database + .getPosts() + .then( + posts => res.render('index', { posts }), + err => res.status(500).send('Oops, something went wrong!') + ) + ; +}; router.get('/', home); +router.post('/', saveComment); module.exports = router; From e7a62cd356269ddae3921c4e5a4faa9bbade0a89 Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Mon, 10 Apr 2017 13:27:04 +0200 Subject: [PATCH 09/52] Remove Babel/ES6 option What was I even thinking? --- index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/index.js b/index.js index e244e61..d28b5fa 100644 --- a/index.js +++ b/index.js @@ -38,7 +38,6 @@ const askForFancyFrontend = { type: 'list', choices: [ {name: 'God no!', value: null}, - {name: 'Babel/ES6', value: 'es6'}, {name: 'React/Redux', value: 'react'}, {name: 'Vue.js', value: 'vue'} ], From 9843bc95d845a92988f416b1af06a22cc24f75f6 Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Mon, 10 Apr 2017 13:27:27 +0200 Subject: [PATCH 10/52] Add react-server dependency for React/Redux option --- builder.js | 1 + 1 file changed, 1 insertion(+) diff --git a/builder.js b/builder.js index 9c3d743..166ecc7 100644 --- a/builder.js +++ b/builder.js @@ -51,6 +51,7 @@ const moduleMappings = { deps: [ 'react', 'react-dom', + 'react-server', 'redux', 'react-redux' ], From 392e4a9b9a248719120f3a9fcff5dd0beae43026 Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Mon, 10 Apr 2017 17:15:02 +0200 Subject: [PATCH 11/52] Prepare Express template for fancy frontends --- templates/express/index.js | 3 +++ templates/express/public/js/app.js | 1 + templates/express/views/index.pug | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 templates/express/public/js/app.js diff --git a/templates/express/index.js b/templates/express/index.js index f96c482..ff287fd 100644 --- a/templates/express/index.js +++ b/templates/express/index.js @@ -11,6 +11,9 @@ app.use(bodyParser.json()); app.set('view engine', 'pug'); app.set('views', __dirname + '/views'); +// Serve static files +app.use(express.static('public')); + // initialize database database.init(); diff --git a/templates/express/public/js/app.js b/templates/express/public/js/app.js new file mode 100644 index 0000000..900d6a8 --- /dev/null +++ b/templates/express/public/js/app.js @@ -0,0 +1 @@ +// Put all your client JS here! diff --git a/templates/express/views/index.pug b/templates/express/views/index.pug index 9934d2e..986f584 100644 --- a/templates/express/views/index.pug +++ b/templates/express/views/index.pug @@ -16,4 +16,7 @@ html hr - include includes/comments.pug + div#comments-root + include includes/comments.pug + + script(src='/js/app.js') From 338af94a459c22e920a02e6a17fd595a718f252c Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Mon, 10 Apr 2017 17:15:31 +0200 Subject: [PATCH 12/52] [WIP] Add initial templates for React/Redux and Makefile --- builder.js | 44 ++++++++++++++++--- index.js | 2 + templates/make/package.json | 8 ++++ templates/react/.babelrc | 11 +++++ .../assets/javascripts/components/Comments.js | 7 +++ templates/react/assets/javascripts/index.js | 10 +++++ 6 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 templates/make/package.json create mode 100644 templates/react/.babelrc create mode 100644 templates/react/assets/javascripts/components/Comments.js create mode 100644 templates/react/assets/javascripts/index.js diff --git a/builder.js b/builder.js index 166ecc7..b53cdb5 100644 --- a/builder.js +++ b/builder.js @@ -51,12 +51,12 @@ const moduleMappings = { deps: [ 'react', 'react-dom', - 'react-server', 'redux', 'react-redux' ], devDeps: [ - 'babel-cli', + 'babel-preset-env', + 'babel-preset-es2015', 'babel-preset-react', 'redux-devtools' ], @@ -70,7 +70,14 @@ const moduleMappings = { 'babel-preset-vue-app' ] }, - make : {deps: [], devDeps: []}, + make : { + deps: [], + devDeps: [ + 'babelify', + 'browserify', + 'watchify' + ] + }, gulp : {deps: [], devDeps: ['gulp']}, webpack : {deps: [], devDeps: ['webpack']} }; @@ -132,15 +139,40 @@ const prepareDatabase = answers => (dest = `${__dirname}/build`) => { return Promise.resolve(); } - console.log(dest); + return fs + .copy(`${__dirname}/templates/${answers.database}`, dest) + .then(() => undefined) + ; +}; + +const prepareFancyFrontend = answers => (dest = `${__dirname}/build`) => { + if (!answers.fancyFrontend) { + return Promise.resolve(); + } + + return fs + .copy(`${__dirname}/templates/${answers.fancyFrontend}`, dest) + .then(() => undefined) + ; +}; - return fs.copy(`${__dirname}/templates/${answers.database}`, dest); +const prepareBuildTool = answers => (dest = `${__dirname}/build`) => { + if (!answers.buildTool) { + return Promise.resolve(); + } + + return fs + .copy(`${__dirname}/templates/${answers.buildTool}`, dest) + .then(() => undefined) + ; }; const builder = answers => ({ copyTemplate: copyTemplate(`${__dirname}/templates/${answers.skeleton}`), generateCommonTemplates: generateCommonTemplates(answers), - prepareDatabase: prepareDatabase(answers) + prepareDatabase: prepareDatabase(answers), + prepareFancyFrontend: prepareFancyFrontend(answers), + prepareBuildTool: prepareBuildTool(answers) }); module.exports = builder; diff --git a/index.js b/index.js index d28b5fa..141112b 100644 --- a/index.js +++ b/index.js @@ -83,6 +83,8 @@ inquirer .copyTemplate() .then(b.generateCommonTemplates) .then(b.prepareDatabase) + .then(b.prepareFancyFrontend) + .then(b.prepareBuildTool) .then(() => { console.log(chalk.green.bold('\nAlright! Your app of choice is ready πŸŽ‰')); console.log(`Please run ${chalk.green.bold('cd build; ./docker/install')} to install dependencies`); diff --git a/templates/make/package.json b/templates/make/package.json new file mode 100644 index 0000000..0b9e5ec --- /dev/null +++ b/templates/make/package.json @@ -0,0 +1,8 @@ +{ + "scripts": { + "start": "node index.js", + "start-dev": "node_modules/.bin/nodemon -e js,pug index.js", + "build-js": "browserify assets/javascripts -o public/js/app.js -t [ babelify ]", + "watch-js": "watchify assets/javascripts -o public/js/app.js -t [ babelify ] --verbose" + } +} diff --git a/templates/react/.babelrc b/templates/react/.babelrc new file mode 100644 index 0000000..3785388 --- /dev/null +++ b/templates/react/.babelrc @@ -0,0 +1,11 @@ +{ + "presets": [ + ["env", { + "targets": { + "browsers": ["last 2 versions", "safari >= 7"] + } + }], + "es2015", + "react" + ] +} diff --git a/templates/react/assets/javascripts/components/Comments.js b/templates/react/assets/javascripts/components/Comments.js new file mode 100644 index 0000000..f28112a --- /dev/null +++ b/templates/react/assets/javascripts/components/Comments.js @@ -0,0 +1,7 @@ +import React from 'react'; + +const Comments = () => { + return (

Here be comments

); +} + +export default Comments; diff --git a/templates/react/assets/javascripts/index.js b/templates/react/assets/javascripts/index.js new file mode 100644 index 0000000..937cc81 --- /dev/null +++ b/templates/react/assets/javascripts/index.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import Comments from './components/Comments'; + +document.addEventListener('DOMContentLoaded', () => { + ReactDOM.render( + , + document.getElementById('comments-root') + ); +}); From 4eaeb509340650b3862b75e631d540c129d36d0b Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Mon, 10 Apr 2017 23:05:34 +0200 Subject: [PATCH 13/52] Fix docker-compose.yml template --- templates/common/docker-compose.yml.mustache | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/templates/common/docker-compose.yml.mustache b/templates/common/docker-compose.yml.mustache index 5dfbb1a..e8dfcb8 100644 --- a/templates/common/docker-compose.yml.mustache +++ b/templates/common/docker-compose.yml.mustache @@ -6,8 +6,8 @@ services: - "3000:3000" volumes: - .:/app - environment: {{#database}} + environment: - DATABASE_HOST=${DATABASE_HOST} - DATABASE_PORT=${DATABASE_PORT} - DATABASE_USER=${DATABASE_USER} @@ -21,7 +21,9 @@ services: - --timeout=60 - -- {{/database}} - - npm run start-dev + - npm + - run + - start-dev volumes: - .:/app {{#database}} From 9971a4cff8f5be4dc14cf972389e46b996ec50b1 Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Mon, 10 Apr 2017 23:07:11 +0200 Subject: [PATCH 14/52] Use make as default build tool / task runner --- index.js | 3 +-- templates/common/Makefile.mustache | 30 ++++++++++++++++++++++++ templates/common/docker/install.mustache | 10 -------- 3 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 templates/common/Makefile.mustache delete mode 100755 templates/common/docker/install.mustache diff --git a/index.js b/index.js index 141112b..ca05738 100644 --- a/index.js +++ b/index.js @@ -87,8 +87,7 @@ inquirer .then(b.prepareBuildTool) .then(() => { console.log(chalk.green.bold('\nAlright! Your app of choice is ready πŸŽ‰')); - console.log(`Please run ${chalk.green.bold('cd build; ./docker/install')} to install dependencies`); - console.log(`When done, run ${chalk.green.bold('docker-compose up')} to launch your app`); + console.log(`Please run ${chalk.green.bold('cd build; make')} to install, build and launch.`); }) ; }) diff --git a/templates/common/Makefile.mustache b/templates/common/Makefile.mustache new file mode 100644 index 0000000..b72725f --- /dev/null +++ b/templates/common/Makefile.mustache @@ -0,0 +1,30 @@ +.DEFAULT_GOAL := all +.PHONY: all docker-build install start {{#fancyFrontend}}build-js build watch-js watch{{/fancyFrontend}} + +all: install {{#fancyFrontend}}build{{/fancyFrontend}} start + +docker-build: + docker-compose build + +install: docker-build + {{#deps}} + docker-compose run web npm install --save {{ deps }} + {{/deps}} + {{#devDeps}} + docker-compose run web npm install --save-dev {{ devDeps }} + {{/devDeps}} + +start: + docker-compose up + +{{#fancyFrontend}} +build-js: + docker-compose run web npm run build-js + +build: build-js + +watch-js: + docker-compose run web npm run watch-js + +watch: watch-js +{{/fancyFrontend}} diff --git a/templates/common/docker/install.mustache b/templates/common/docker/install.mustache deleted file mode 100755 index 3d63241..0000000 --- a/templates/common/docker/install.mustache +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -docker-compose build - -{{#deps}} -docker-compose run web npm install --save {{ deps }} -{{/deps}} -{{#devDeps}} -docker-compose run web npm install --save-dev {{ devDeps }} -{{/devDeps}} From 25c91efddd87eb791270acbc6302c27b24446dc2 Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Wed, 12 Apr 2017 12:51:23 +0200 Subject: [PATCH 15/52] Add refactorings * ./bin/builder -> ./bin/build * ./templates -> ./blueprints * Moved Inquirer questions into their own module * Moved NPM module mappings into their own module * Cleaned up and refactored the whole builder module --- bin/{builder => build} | 0 .../common/Dockerfile.mustache | 0 .../common/Makefile.mustache | 0 .../common/docker-compose.yml.mustache | 0 .../express/api/router.js | 0 .../express/database/index.js | 0 {templates => blueprints}/express/index.js | 0 .../express/package.json | 0 .../express/public/js/app.js | 0 .../express/site/router.js | 0 .../express/views/includes/comments.pug | 0 .../express/views/index.pug | 0 {templates => blueprints}/make/package.json | 0 {templates => blueprints}/minimal/index.js | 0 .../minimal/package.json | 0 {templates => blueprints}/mongodb/.env | 0 .../mongodb/database-service.yml | 0 .../mongodb/database/index.js | 0 {templates => blueprints}/mysql/.env | 0 .../mysql/database-service.yml | 0 .../mysql/database/index.js | 12 +- {templates => blueprints}/postgres/.env | 0 .../postgres/database-service.yml | 0 .../postgres/database/index.js | 0 {templates => blueprints}/react/.babelrc | 0 .../assets/javascripts/components/Comments.js | 0 .../react/assets/javascripts/index.js | 0 builder.js | 189 +++++------------- index.js | 97 ++------- modules.js | 50 +++++ package.json | 3 +- questions.js | 74 +++++++ 32 files changed, 195 insertions(+), 230 deletions(-) rename bin/{builder => build} (100%) rename {templates => blueprints}/common/Dockerfile.mustache (100%) rename {templates => blueprints}/common/Makefile.mustache (100%) rename {templates => blueprints}/common/docker-compose.yml.mustache (100%) rename {templates => blueprints}/express/api/router.js (100%) rename {templates => blueprints}/express/database/index.js (100%) rename {templates => blueprints}/express/index.js (100%) rename {templates => blueprints}/express/package.json (100%) rename {templates => blueprints}/express/public/js/app.js (100%) rename {templates => blueprints}/express/site/router.js (100%) rename {templates => blueprints}/express/views/includes/comments.pug (100%) rename {templates => blueprints}/express/views/index.pug (100%) rename {templates => blueprints}/make/package.json (100%) rename {templates => blueprints}/minimal/index.js (100%) rename {templates => blueprints}/minimal/package.json (100%) rename {templates => blueprints}/mongodb/.env (100%) rename {templates => blueprints}/mongodb/database-service.yml (100%) rename {templates => blueprints}/mongodb/database/index.js (100%) rename {templates => blueprints}/mysql/.env (100%) rename {templates => blueprints}/mysql/database-service.yml (100%) rename {templates => blueprints}/mysql/database/index.js (90%) rename {templates => blueprints}/postgres/.env (100%) rename {templates => blueprints}/postgres/database-service.yml (100%) rename {templates => blueprints}/postgres/database/index.js (100%) rename {templates => blueprints}/react/.babelrc (100%) rename {templates => blueprints}/react/assets/javascripts/components/Comments.js (100%) rename {templates => blueprints}/react/assets/javascripts/index.js (100%) create mode 100644 modules.js create mode 100644 questions.js diff --git a/bin/builder b/bin/build similarity index 100% rename from bin/builder rename to bin/build diff --git a/templates/common/Dockerfile.mustache b/blueprints/common/Dockerfile.mustache similarity index 100% rename from templates/common/Dockerfile.mustache rename to blueprints/common/Dockerfile.mustache diff --git a/templates/common/Makefile.mustache b/blueprints/common/Makefile.mustache similarity index 100% rename from templates/common/Makefile.mustache rename to blueprints/common/Makefile.mustache diff --git a/templates/common/docker-compose.yml.mustache b/blueprints/common/docker-compose.yml.mustache similarity index 100% rename from templates/common/docker-compose.yml.mustache rename to blueprints/common/docker-compose.yml.mustache diff --git a/templates/express/api/router.js b/blueprints/express/api/router.js similarity index 100% rename from templates/express/api/router.js rename to blueprints/express/api/router.js diff --git a/templates/express/database/index.js b/blueprints/express/database/index.js similarity index 100% rename from templates/express/database/index.js rename to blueprints/express/database/index.js diff --git a/templates/express/index.js b/blueprints/express/index.js similarity index 100% rename from templates/express/index.js rename to blueprints/express/index.js diff --git a/templates/express/package.json b/blueprints/express/package.json similarity index 100% rename from templates/express/package.json rename to blueprints/express/package.json diff --git a/templates/express/public/js/app.js b/blueprints/express/public/js/app.js similarity index 100% rename from templates/express/public/js/app.js rename to blueprints/express/public/js/app.js diff --git a/templates/express/site/router.js b/blueprints/express/site/router.js similarity index 100% rename from templates/express/site/router.js rename to blueprints/express/site/router.js diff --git a/templates/express/views/includes/comments.pug b/blueprints/express/views/includes/comments.pug similarity index 100% rename from templates/express/views/includes/comments.pug rename to blueprints/express/views/includes/comments.pug diff --git a/templates/express/views/index.pug b/blueprints/express/views/index.pug similarity index 100% rename from templates/express/views/index.pug rename to blueprints/express/views/index.pug diff --git a/templates/make/package.json b/blueprints/make/package.json similarity index 100% rename from templates/make/package.json rename to blueprints/make/package.json diff --git a/templates/minimal/index.js b/blueprints/minimal/index.js similarity index 100% rename from templates/minimal/index.js rename to blueprints/minimal/index.js diff --git a/templates/minimal/package.json b/blueprints/minimal/package.json similarity index 100% rename from templates/minimal/package.json rename to blueprints/minimal/package.json diff --git a/templates/mongodb/.env b/blueprints/mongodb/.env similarity index 100% rename from templates/mongodb/.env rename to blueprints/mongodb/.env diff --git a/templates/mongodb/database-service.yml b/blueprints/mongodb/database-service.yml similarity index 100% rename from templates/mongodb/database-service.yml rename to blueprints/mongodb/database-service.yml diff --git a/templates/mongodb/database/index.js b/blueprints/mongodb/database/index.js similarity index 100% rename from templates/mongodb/database/index.js rename to blueprints/mongodb/database/index.js diff --git a/templates/mysql/.env b/blueprints/mysql/.env similarity index 100% rename from templates/mysql/.env rename to blueprints/mysql/.env diff --git a/templates/mysql/database-service.yml b/blueprints/mysql/database-service.yml similarity index 100% rename from templates/mysql/database-service.yml rename to blueprints/mysql/database-service.yml diff --git a/templates/mysql/database/index.js b/blueprints/mysql/database/index.js similarity index 90% rename from templates/mysql/database/index.js rename to blueprints/mysql/database/index.js index 2b55de0..971015e 100644 --- a/templates/mysql/database/index.js +++ b/blueprints/mysql/database/index.js @@ -8,12 +8,12 @@ const dbName = process.env.DATABASE_NAME; let connection; -const init = ({ host, port, user, password, database } = { - host: dbHost, +const init = ({ host, port, user, password, database } = { + host: dbHost, port: dbPort, user: dbUser, - password: dbPass, - database: dbName + password: dbPass, + database: dbName }) => { connection = mysql.createConnection({ host, @@ -70,8 +70,8 @@ const getPosts = () => new Promise((resolve, reject) => { const getPostById = id => new Promise((resolve, reject) => { connection.query( - 'SELECT * FROM comments WHERE id = ? LIMIT 1', - [id], + 'SELECT * FROM comments WHERE id = ? LIMIT 1', + [id], (err, results) => { if (err) { return reject(err); diff --git a/templates/postgres/.env b/blueprints/postgres/.env similarity index 100% rename from templates/postgres/.env rename to blueprints/postgres/.env diff --git a/templates/postgres/database-service.yml b/blueprints/postgres/database-service.yml similarity index 100% rename from templates/postgres/database-service.yml rename to blueprints/postgres/database-service.yml diff --git a/templates/postgres/database/index.js b/blueprints/postgres/database/index.js similarity index 100% rename from templates/postgres/database/index.js rename to blueprints/postgres/database/index.js diff --git a/templates/react/.babelrc b/blueprints/react/.babelrc similarity index 100% rename from templates/react/.babelrc rename to blueprints/react/.babelrc diff --git a/templates/react/assets/javascripts/components/Comments.js b/blueprints/react/assets/javascripts/components/Comments.js similarity index 100% rename from templates/react/assets/javascripts/components/Comments.js rename to blueprints/react/assets/javascripts/components/Comments.js diff --git a/templates/react/assets/javascripts/index.js b/blueprints/react/assets/javascripts/index.js similarity index 100% rename from templates/react/assets/javascripts/index.js rename to blueprints/react/assets/javascripts/index.js diff --git a/builder.js b/builder.js index b53cdb5..fa7522a 100644 --- a/builder.js +++ b/builder.js @@ -2,98 +2,22 @@ const fs = require('fs-promise'); const path = require('path'); const Mustache = require('mustache'); const glob = require('glob-promise'); +const uniqid = require('uniqid'); const uniq = require('lodash.uniq'); -const chalk = require('chalk'); +const modules = require('./modules'); -const error = chalk.bold.red; - -const logError = message => console.error(error(`Error: ${message}`)); - -const copyTemplate = src => (dest = __dirname + '/build') => { - return fs - .access(dest, fs.constants.W_OK) - .then( - () => fs.remove(dest), - err => { - if ('ENOENT' === err.code) { - return - } - - if ('EACCES' === err.code) { - logError(`No write access for ${dest}`); - } - - throw err; - } - ) - .then(() => fs.copy(src, dest)) - ; -}; - -const moduleMappings = { - minimal : {deps: [], devDeps: ['nodemon']}, - express : { - deps: [ - 'body-parser', - 'express', - 'lodash.find', - 'pug', - ], - devDeps: [ - 'nodemon' - ] - }, - mysql : {deps: ['mysql'], devDeps: []}, - postgres : {deps: ['pg'], devDeps: []}, - mongodb : {deps: ['mongoose'], devDeps: []}, - es6 : {deps: [], devDeps: ['babel-cli', 'babel-preset-env']}, - react : { - deps: [ - 'react', - 'react-dom', - 'redux', - 'react-redux' - ], - devDeps: [ - 'babel-preset-env', - 'babel-preset-es2015', - 'babel-preset-react', - 'redux-devtools' - ], - }, - vue : { - deps: [ - 'vue' - ], - devDeps: [ - 'babel-cli', - 'babel-preset-vue-app' - ] - }, - make : { - deps: [], - devDeps: [ - 'babelify', - 'browserify', - 'watchify' - ] - }, - gulp : {deps: [], devDeps: ['gulp']}, - webpack : {deps: [], devDeps: ['webpack']} -}; - -const determineNodeModules = (answers = {}) => { +const determineNodeModules = (context, modules) => { const temp = Object - .keys(answers) + .keys(context) .reduce((acc, key) => { - const value = answers[key]; + const value = context[key]; if (!value) { return acc; } return { - deps: uniq(acc.deps.concat(moduleMappings[value].deps)), - devDeps: uniq(acc.devDeps.concat(moduleMappings[value].devDeps)), + deps: uniq(acc.deps.concat(modules[value].deps)), + devDeps: uniq(acc.devDeps.concat(modules[value].devDeps)), } }, {deps: [], devDeps: []} ); @@ -102,77 +26,66 @@ const determineNodeModules = (answers = {}) => { deps: temp.deps.join(' '), devDeps: temp.devDeps.join(' ') } -} +}; -const generateCommonTemplates = answers => (dest = `${__dirname}/build`) => { - const modules = determineNodeModules(answers); - const templateContext = Object.assign({}, answers, modules); +const compileTemplates = (context, src, opts = {}) => { + const options = Object.assign({ + deleteAfterCompilation: true + }, opts); - return glob(`${__dirname}/templates/common/**/*.mustache`) + return glob(src + '/**/*.mustache') .then(files => { const promises = files.map(file => { - const relativePath = path.relative(`${__dirname}/templates/common`, file.replace('\.mustache', '')); - const destPath = `${dest}/${relativePath}`; - return fs - .ensureDir(path.dirname(destPath)) - .then(() => fs.readFile(file)) - .then(buf => Mustache.render(buf.toString('utf-8'), templateContext)) - .then(output => fs.writeFile(destPath, output)) + .readFile(file) + .then(buf => Mustache.render(buf.toString('utf-8'), context)) + .then(output => fs.writeFile(file.replace('\.mustache', ''), output)) + .then(() => { + if (options.deleteAfterCompilation) { + return fs.remove(file); + } + }) ; - }) - - return Promise.all(promises); - }) - .then(() => glob(`${dest}/docker/**/*`)) - .then(files => { - const promises = files.map((file) => fs.chmod(file, 0751)); + }); return Promise.all(promises); }) - .then(() => undefined) ; }; -const prepareDatabase = answers => (dest = `${__dirname}/build`) => { - if (!answers.database) { - return Promise.resolve(); - } - - return fs - .copy(`${__dirname}/templates/${answers.database}`, dest) - .then(() => undefined) +const build = (ctx, dest = './build') => { + const choices = Object + .keys(ctx) + .map(key => ctx[key]) + .filter(choice => !!choice) ; -}; + const realDest = `./build/${choices.join('-')}`; + const tempDest = uniqid(realDest + '-'); -const prepareFancyFrontend = answers => (dest = `${__dirname}/build`) => { - if (!answers.fancyFrontend) { - return Promise.resolve(); - } + const [skeleton, ...rest] = choices; + const remaining = Array.isArray(rest) ? rest.concat('common') : [rest, 'common']; - return fs - .copy(`${__dirname}/templates/${answers.fancyFrontend}`, dest) - .then(() => undefined) - ; -}; - -const prepareBuildTool = answers => (dest = `${__dirname}/build`) => { - if (!answers.buildTool) { - return Promise.resolve(); - } + const context = Object.assign(ctx, determineNodeModules(ctx, modules)); return fs - .copy(`${__dirname}/templates/${answers.buildTool}`, dest) - .then(() => undefined) - ; -}; + .emptyDir(dest) + .then(() => fs.ensureDir(tempDest)) + .then(() => fs.copy(`./blueprints/${skeleton}`, tempDest)) + .then(() => { + const promises = remaining + .map(choice => fs.copy(`./blueprints/${choice}`, tempDest)) + ; -const builder = answers => ({ - copyTemplate: copyTemplate(`${__dirname}/templates/${answers.skeleton}`), - generateCommonTemplates: generateCommonTemplates(answers), - prepareDatabase: prepareDatabase(answers), - prepareFancyFrontend: prepareFancyFrontend(answers), - prepareBuildTool: prepareBuildTool(answers) -}); + return Promise.all(promises); + }) + .then(() => compileTemplates(context, tempDest)) + .then(() => fs.move(tempDest, realDest)) + .then(() => realDest) + ; +} -module.exports = builder; +module.exports = { + build, + determineNodeModules, + compileTemplates +}; diff --git a/index.js b/index.js index ca05738..06f8eb3 100644 --- a/index.js +++ b/index.js @@ -1,94 +1,21 @@ const inquirer = require('inquirer'); const chalk = require('chalk'); const builder = require('./builder'); +const questions = require('./questions') -const askForSkeleton = { - name: 'skeleton', - message: 'Which type of Node.js app?', - type: 'list', - choices: [ - {name: 'Minimal', value: 'minimal'}, - {name: 'Express.js', value: 'express'} - ], -}; +const logError = message => console.error(chalk.red.bold(`Error: ${message}`)); -const askForDatabase = { - name: 'database', - message: 'Which Database do you want to use?', - type: 'list', - choices: [ - {name: 'None', value: null}, - {name: 'MySQL', value: 'mysql'}, - {name: 'PostgreSQL', value: 'postgres'}, - {name: 'MongoDB', value: 'mongodb'} - ], - when: (currentAnswers) => { - const { skeleton } = currentAnswers; - if (!!skeleton && 'minimal' === skeleton) { - return false; - } - - return true; - } -}; - -const askForFancyFrontend = { - name: 'fancyFrontend', - message: 'Do you want a fancy front end?', - type: 'list', - choices: [ - {name: 'God no!', value: null}, - {name: 'React/Redux', value: 'react'}, - {name: 'Vue.js', value: 'vue'} - ], - when: (currentAnswers) => { - const { skeleton } = currentAnswers; - if (!!skeleton && 'minimal' === skeleton) { - return false; - } - - return true; - } -}; - -const askForBuildTool = { - name: 'buildTool', - message: 'How do you want to build your front end?', - type: 'list', - choices: [ - {name: 'Makefile', value: 'make'}, - {name: 'Gulp.js', value: 'gulp'}, - {name: 'Webpack', value: 'webpack'} - ], - when: (currentAnswers) => { - const { skeleton, fancyFrontend } = currentAnswers; - if ((!!skeleton && 'minimal' === skeleton) || !fancyFrontend) { - return false; - } - - return true; - } -} - -inquirer +return inquirer .prompt([ - askForSkeleton, - askForDatabase, - askForFancyFrontend, - askForBuildTool + questions.askForSkeleton, + questions.askForDatabase, + questions.askForFancyFrontend, + questions.askForBuildTool ]) - .then((answers) => { - const b = builder(answers); - return b - .copyTemplate() - .then(b.generateCommonTemplates) - .then(b.prepareDatabase) - .then(b.prepareFancyFrontend) - .then(b.prepareBuildTool) - .then(() => { - console.log(chalk.green.bold('\nAlright! Your app of choice is ready πŸŽ‰')); - console.log(`Please run ${chalk.green.bold('cd build; make')} to install, build and launch.`); - }) - ; + .then(builder.build) + .then(buildDir => { + console.log(chalk.green.bold('\nAlright! Your app of choice is ready πŸŽ‰')); + console.log(`Please run ${chalk.green.bold(`cd ${buildDir}; make`)} to install, build and launch.`); }) + .catch(err => logError(err.message)) ; diff --git a/modules.js b/modules.js new file mode 100644 index 0000000..9f72223 --- /dev/null +++ b/modules.js @@ -0,0 +1,50 @@ +module.exports = { + minimal : {deps: [], devDeps: ['nodemon']}, + express : { + deps: [ + 'body-parser', + 'express', + 'lodash.find', + 'pug', + ], + devDeps: [ + 'nodemon' + ] + }, + mysql : {deps: ['mysql'], devDeps: []}, + postgres : {deps: ['pg'], devDeps: []}, + mongodb : {deps: ['mongoose'], devDeps: []}, + react : { + deps: [ + 'react', + 'react-dom', + 'redux', + 'react-redux' + ], + devDeps: [ + 'babel-preset-env', + 'babel-preset-es2015', + 'babel-preset-react', + 'redux-devtools' + ], + }, + vue : { + deps: [ + 'vue' + ], + devDeps: [ + 'babel-cli', + 'babel-preset-vue-app' + ] + }, + make : { + deps: [], + devDeps: [ + 'babelify', + 'browserify', + 'watchify' + ] + }, + gulp : {deps: [], devDeps: ['gulp']}, + webpack : {deps: [], devDeps: ['webpack']} +}; diff --git a/package.json b/package.json index 9401688..bdf50d0 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "glob-promise": "^3.1.0", "inquirer": "^3.0.6", "lodash.uniq": "^4.5.0", - "mustache": "^2.3.0" + "mustache": "^2.3.0", + "uniqid": "^4.1.1" } } diff --git a/questions.js b/questions.js new file mode 100644 index 0000000..c72a18c --- /dev/null +++ b/questions.js @@ -0,0 +1,74 @@ +const askForSkeleton = { + name: 'skeleton', + message: 'Which type of Node.js app?', + type: 'list', + choices: [ + {name: 'Minimal', value: 'minimal'}, + {name: 'Express.js', value: 'express'} + ], +}; + +const askForDatabase = { + name: 'database', + message: 'Which Database do you want to use?', + type: 'list', + choices: [ + {name: 'None', value: null}, + {name: 'MySQL', value: 'mysql'}, + {name: 'PostgreSQL', value: 'postgres'}, + {name: 'MongoDB', value: 'mongodb'} + ], + when: (currentAnswers) => { + const { skeleton } = currentAnswers; + if (!!skeleton && 'minimal' === skeleton) { + return false; + } + + return true; + } +}; + +const askForFancyFrontend = { + name: 'fancyFrontend', + message: 'Do you want a fancy front end?', + type: 'list', + choices: [ + {name: 'God no!', value: null}, + {name: 'React/Redux', value: 'react'}, + {name: 'Vue.js', value: 'vue'} + ], + when: (currentAnswers) => { + const { skeleton } = currentAnswers; + if (!!skeleton && 'minimal' === skeleton) { + return false; + } + + return true; + } +}; + +const askForBuildTool = { + name: 'buildTool', + message: 'How do you want to build your front end?', + type: 'list', + choices: [ + {name: 'Makefile', value: 'make'}, + {name: 'Gulp.js', value: 'gulp'}, + {name: 'Webpack', value: 'webpack'} + ], + when: (currentAnswers) => { + const { skeleton, fancyFrontend } = currentAnswers; + if ((!!skeleton && 'minimal' === skeleton) || !fancyFrontend) { + return false; + } + + return true; + } +} + +module.exports = { + askForSkeleton, + askForDatabase, + askForFancyFrontend, + askForBuildTool +}; From 29403ad51aab0598981d136ec7f2f2296cf87028 Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Wed, 12 Apr 2017 13:13:51 +0200 Subject: [PATCH 16/52] Remove array check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The check is unnecessary, since `…rest` always returns an array --- builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder.js b/builder.js index fa7522a..25d10c1 100644 --- a/builder.js +++ b/builder.js @@ -63,7 +63,7 @@ const build = (ctx, dest = './build') => { const tempDest = uniqid(realDest + '-'); const [skeleton, ...rest] = choices; - const remaining = Array.isArray(rest) ? rest.concat('common') : [rest, 'common']; + const remaining = rest.concat('common'); const context = Object.assign(ctx, determineNodeModules(ctx, modules)); From 7b8a151dbcec9bf0fb20b806daaa0c467cf91a37 Mon Sep 17 00:00:00 2001 From: Pascal Cremer Date: Wed, 12 Apr 2017 16:58:43 +0200 Subject: [PATCH 17/52] Add more stuff for the React/Redux blueprint --- .../react/assets/javascripts/actions/index.js | 9 ++++ .../react/assets/javascripts/api/index.js | 0 .../assets/javascripts/components/Comments.js | 7 --- .../components/comments/AddComment.js | 47 +++++++++++++++++++ .../javascripts/components/comments/App.js | 15 ++++++ .../components/comments/Comment.js | 16 +++++++ .../javascripts/components/comments/List.js | 19 ++++++++ .../react/assets/javascripts/constants.js | 1 + blueprints/react/assets/javascripts/index.js | 12 ++++- .../assets/javascripts/reducers/comments.js | 29 ++++++++++++ .../assets/javascripts/reducers/index.js | 6 +++ modules.js | 3 +- 12 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 blueprints/react/assets/javascripts/actions/index.js create mode 100644 blueprints/react/assets/javascripts/api/index.js delete mode 100644 blueprints/react/assets/javascripts/components/Comments.js create mode 100644 blueprints/react/assets/javascripts/components/comments/AddComment.js create mode 100644 blueprints/react/assets/javascripts/components/comments/App.js create mode 100644 blueprints/react/assets/javascripts/components/comments/Comment.js create mode 100644 blueprints/react/assets/javascripts/components/comments/List.js create mode 100644 blueprints/react/assets/javascripts/constants.js create mode 100644 blueprints/react/assets/javascripts/reducers/comments.js create mode 100644 blueprints/react/assets/javascripts/reducers/index.js diff --git a/blueprints/react/assets/javascripts/actions/index.js b/blueprints/react/assets/javascripts/actions/index.js new file mode 100644 index 0000000..929e8b6 --- /dev/null +++ b/blueprints/react/assets/javascripts/actions/index.js @@ -0,0 +1,9 @@ +import { ADD_COMMENT } from '../constants'; + +const addComment = (author, body) => ({ + type: ADD_COMMENT, + author, + body +}); + +export { addComment }; diff --git a/blueprints/react/assets/javascripts/api/index.js b/blueprints/react/assets/javascripts/api/index.js new file mode 100644 index 0000000..e69de29 diff --git a/blueprints/react/assets/javascripts/components/Comments.js b/blueprints/react/assets/javascripts/components/Comments.js deleted file mode 100644 index f28112a..0000000 --- a/blueprints/react/assets/javascripts/components/Comments.js +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -const Comments = () => { - return (

Here be comments

); -} - -export default Comments; diff --git a/blueprints/react/assets/javascripts/components/comments/AddComment.js b/blueprints/react/assets/javascripts/components/comments/AddComment.js new file mode 100644 index 0000000..11f91a9 --- /dev/null +++ b/blueprints/react/assets/javascripts/components/comments/AddComment.js @@ -0,0 +1,47 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import { addComment } from '../../actions'; + +let AddComment = ({ dispatch }) => { + let authorInput, bodyInput; + + return ( +
{ + e.preventDefault(); + if (!authorInput.value.trim() || !bodyInput.value.trim()) { + return; + } + + dispatch(addComment(authorInput.value, bodyInput.value)); + authorInput.value = ''; + bodyInput.value = ''; + }}> +
+ + { + authorInput = node; + }} /> +
+
+ +