diff --git a/.gitignore b/.gitignore index 1e3d79b..dbd6e36 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +**/node_modules +**/package-lock.json + .sass-cache !.gitkeep 03-express-gulp-watch/app/public/stylesheets/style.css 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 index 9027fcb..1c22dd3 100644 --- a/00-basic-express-generator/Dockerfile +++ b/00-basic-express-generator/Dockerfile @@ -1,13 +1,15 @@ -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 +ARG IMAGE_VERSION_BUILD=latest +ARG IMAGE_VERSION=18.14.2-bullseye-slim +ARG NODE_ENV=development + +FROM node:${IMAGE_VERSION_BUILD} AS build +RUN apt-get update && apt-get install -y --no-install-recommends dumb-init + +FROM node:${IMAGE_VERSION} +ENV NODE_ENV ${NODE_ENV} +COPY --from=build /usr/bin/dumb-init /usr/bin/dumb-init +RUN mkdir /usr/src/app +RUN chown node:node /usr/src/app +WORKDIR /usr/src/app +USER node +CMD ["dumb-init", "npm", "run", "start"] \ No newline at end of file diff --git a/00-basic-express-generator/README.md b/00-basic-express-generator/README.md index 7b018ca..1a3787b 100644 --- a/00-basic-express-generator/README.md +++ b/00-basic-express-generator/README.md @@ -10,19 +10,14 @@ Install [Docker](https://www.docker.com/) on your system. * [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`` +[Install Docker Compose](https://docs.docker.com/compose/install/) on your system. ## 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`. +1. Run `docker-compose build`. This will pull the base images, and install image dependencies. -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. +2. Run `docker-compose run web npm install`. This will install the `package.json` dependencies in the `app` sub-folder. Since this folder is mounted into the Docker image as a volume, any changes made in the image or on your local file system are synced. ## 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). +Run `docker-compose up` to start the container. The app should then be running at http://localhost:3000. diff --git a/00-basic-express-generator/app/app.js b/00-basic-express-generator/app/app.js index 95b1e2a..e1f522d 100644 --- a/00-basic-express-generator/app/app.js +++ b/00-basic-express-generator/app/app.js @@ -1,60 +1,11 @@ -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'); +const express = require('express'); +const app = express(); +const port = process.env.APP_PORT; -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); +app.get('/', (req, res) => { + res.send('Hello World!') }); -// 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; +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}); \ No newline at end of file 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 index 3c5f460..689a364 100644 --- a/00-basic-express-generator/app/package.json +++ b/00-basic-express-generator/app/package.json @@ -3,15 +3,9 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "node ./bin/www" + "start": "node app.js" }, "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" + "express": "4.18.2" } } \ 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 index e5d9890..91cf08c 100644 --- a/00-basic-express-generator/docker-compose.yml +++ b/00-basic-express-generator/docker-compose.yml @@ -1,6 +1,12 @@ -web: - build: . - volumes: - - "./app:/src/app" - ports: - - "3030:3000" \ No newline at end of file +version: "3.9" + +services: + web: + build: . + user: "node:node" + environment: + - APP_PORT=${APP_PORT:-3000} + volumes: + - "./app:/usr/src/app" + ports: + - "3000: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 index af1bd93..1c22dd3 100644 --- a/01-express-nodemon/Dockerfile +++ b/01-express-nodemon/Dockerfile @@ -1,15 +1,15 @@ -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 +ARG IMAGE_VERSION_BUILD=latest +ARG IMAGE_VERSION=18.14.2-bullseye-slim +ARG NODE_ENV=development + +FROM node:${IMAGE_VERSION_BUILD} AS build +RUN apt-get update && apt-get install -y --no-install-recommends dumb-init + +FROM node:${IMAGE_VERSION} +ENV NODE_ENV ${NODE_ENV} +COPY --from=build /usr/bin/dumb-init /usr/bin/dumb-init +RUN mkdir /usr/src/app +RUN chown node:node /usr/src/app +WORKDIR /usr/src/app +USER node +CMD ["dumb-init", "npm", "run", "start"] \ No newline at end of file diff --git a/01-express-nodemon/README.md b/01-express-nodemon/README.md index 2d71f79..a2ba76b 100644 --- a/01-express-nodemon/README.md +++ b/01-express-nodemon/README.md @@ -1,6 +1,6 @@ # 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. +Use [nodemon](https://www.npmjs.com/package/nodemon) to monitor file changes in your container. The app will restart, if you change any **.js**, **.json** or **.hjs** file. ## Prerequisites @@ -10,28 +10,14 @@ Install [Docker](https://www.docker.com/) on your system. * [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`` +[Install Docker Compose](https://docs.docker.com/compose/install/) on your system. ## Setup -Run `docker-compose build`. It will +1. Run `docker-compose build`. This will pull the base images, and install image dependencies. -* 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. +2. Run `docker-compose run web npm install`. This will install the `package.json` dependencies in the `app` sub-folder. Since this folder is mounted into the Docker image as a volume, any changes made in the image or on your local file system are synced. ## 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 -``` +Run `docker-compose up` to start the container. The app should then be running at http://localhost:3000. diff --git a/01-express-nodemon/app/app.js b/01-express-nodemon/app/app.js index ca8ba7a..e1f522d 100644 --- a/01-express-nodemon/app/app.js +++ b/01-express-nodemon/app/app.js @@ -1,60 +1,11 @@ -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'); +const express = require('express'); +const app = express(); +const port = process.env.APP_PORT; -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); +app.get('/', (req, res) => { + res.send('Hello World!') }); -// 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; +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}); \ No newline at end of file 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 index f1b04c6..2636389 100644 --- a/01-express-nodemon/app/nodemon.json +++ b/01-express-nodemon/app/nodemon.json @@ -1,6 +1,3 @@ { - "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 index 725399a..b8bfa8e 100644 --- a/01-express-nodemon/app/package.json +++ b/01-express-nodemon/app/package.json @@ -3,16 +3,12 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "nodemon -L app/bin/www" + "start": "nodemon app.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", - "jade": "*" + "express": "4.18.2" + }, + "devDependencies": { + "nodemon": "2.0.21" } -} +} \ No newline at end of file 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 index e5d9890..91cf08c 100644 --- a/01-express-nodemon/docker-compose.yml +++ b/01-express-nodemon/docker-compose.yml @@ -1,6 +1,12 @@ -web: - build: . - volumes: - - "./app:/src/app" - ports: - - "3030:3000" \ No newline at end of file +version: "3.9" + +services: + web: + build: . + user: "node:node" + environment: + - APP_PORT=${APP_PORT:-3000} + volumes: + - "./app:/usr/src/app" + ports: + - "3000: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 index af1bd93..1c22dd3 100644 --- a/02-express-redis-nodemon/Dockerfile +++ b/02-express-redis-nodemon/Dockerfile @@ -1,15 +1,15 @@ -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 +ARG IMAGE_VERSION_BUILD=latest +ARG IMAGE_VERSION=18.14.2-bullseye-slim +ARG NODE_ENV=development + +FROM node:${IMAGE_VERSION_BUILD} AS build +RUN apt-get update && apt-get install -y --no-install-recommends dumb-init + +FROM node:${IMAGE_VERSION} +ENV NODE_ENV ${NODE_ENV} +COPY --from=build /usr/bin/dumb-init /usr/bin/dumb-init +RUN mkdir /usr/src/app +RUN chown node:node /usr/src/app +WORKDIR /usr/src/app +USER node +CMD ["dumb-init", "npm", "run", "start"] \ No newline at end of file diff --git a/02-express-redis-nodemon/README.md b/02-express-redis-nodemon/README.md index eb7faae..4e66f59 100644 --- a/02-express-redis-nodemon/README.md +++ b/02-express-redis-nodemon/README.md @@ -10,29 +10,15 @@ Install [Docker](https://www.docker.com/) on your system. * [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. +[Install Docker Compose](https://docs.docker.com/compose/install/) 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 +1. Run `docker-compose build`. This will pull the base images, and install image dependencies. -* 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. +2. Run `docker-compose run web npm install`. This will install the `package.json` dependencies in the `app` sub-folder. Since this folder is mounted into the Docker image as a volume, any changes made in the image or on your local file system are synced. ## 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). +Run `docker-compose up` to start the container. The app should then be running at http://localhost:3000. -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 index ca8ba7a..17bc65b 100644 --- a/02-express-redis-nodemon/app/app.js +++ b/02-express-redis-nodemon/app/app.js @@ -1,60 +1,27 @@ -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'); +const express = require('express'); +const {createClient} = require("redis"); -var routes = require('./routes/index'); -var users = require('./routes/users'); +const app = express(); +const port = process.env.APP_PORT; -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); +const client = createClient({ + url: process.env.DB_URI }); -// error handlers +client.on('error', err => console.log('Redis Client Error', err)); +(async() => { await client.connect(); })(); -// 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 - }); - }); -} +app.get('/', async (req, res) => { + let body = ''; + await client.set('foo', 'bar'); + body += 'Write value "bar" to key "foo"... '; -// 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: {} - }); -}); + const bar = await client.get('foo'); + body += `Read key "foo", got value "${bar}".`; + res.send(body); +}); -module.exports = app; +app.listen(port, () => { + console.log(`Example app listening on port ${port}`); +}); \ No newline at end of file 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 index f1b04c6..2636389 100644 --- a/02-express-redis-nodemon/app/nodemon.json +++ b/02-express-redis-nodemon/app/nodemon.json @@ -1,6 +1,3 @@ { - "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 index 369171f..b79ca57 100644 --- a/02-express-redis-nodemon/app/package.json +++ b/02-express-redis-nodemon/app/package.json @@ -3,17 +3,13 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "nodemon -L app/bin/www" + "start": "nodemon app.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", - "redis": "~0.12.1", - "hiredis": "~0.1.17" + "express": "4.18.2", + "redis": "4.6.5" + }, + "devDependencies": { + "nodemon": "2.0.21" } } \ 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 5f5d069..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.0.1'; -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 index 3f9a533..3801183 100644 --- a/02-express-redis-nodemon/docker-compose.yml +++ b/02-express-redis-nodemon/docker-compose.yml @@ -1,11 +1,19 @@ -web: - build: . - volumes: - - "./app:/src/app" - ports: - - "3030:3000" - links: - - "db:redis" +version: "3.9" -db: - image: redis \ No newline at end of file +services: + web: + build: . + user: "node:node" + environment: + - APP_PORT=${APP_PORT:-3000} + - DB_URI=redis://db:6379 + volumes: + - "./app:/usr/src/app" + ports: + - "3000:3000" + depends_on: + - db + db: + image: "redis:${IMAGE_VERSION_REDIS:-7.0.9-bullseye}" + ports: + - "6379:6379" \ 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/LICENSE b/LICENSE index d016f99..dc74a1d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2017 Pascal Cremer +Copyright (c) 2014-2023 Geek Cell 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/README.md b/README.md index 2f503f5..5318368 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,30 @@ # Getting started with Docker Compose and Nodejs -**Heads up: Version 2.0 is coming! Read about its development here** - -https://medium.com/@b00giZm/building-the-next-version-of-compose-node-86eef3c23d5b - ## Motivation -[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. +[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. -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. +If you're like us, you're using a development server like [nodemon](https://github.com/remy/nodemon) that watches all your file changes and reloads your app. Bringing this workflow over to Docker Compose is a bit tricky. We hope the following real world examples will save you from headaches 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) +https://github.com/geekcell/docker-compose-nodejs-examples/tree/main/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) +https://github.com/geekcell/docker-compose-nodejs-examples/tree/main/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) +https://github.com/geekcell/docker-compose-nodejs-examples/tree/main/02-express-redis-nodemon -### 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) +## Maintainers -### 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) +Geek Cell -More to come... +* Twitter: [@thegeekcell](https://twitter.com/thegeekcell) +* Web: [https://geekcell.io](https://geekcell.io) -## Maintainer +### Previous Maintainer Pascal Cremer @@ -44,24 +34,4 @@ Pascal Cremer ## License -> The MIT License (MIT) -> -> 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 ->in the Software without restriction, including without limitation the rights ->to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ->copies of the Software, and to permit persons to whom the Software is ->furnished to do so, subject to the following conditions: -> ->The above copyright notice and this permission notice shall be included in all ->copies or substantial portions of the Software. -> ->THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ->IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ->FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ->AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ->LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ->OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ->SOFTWARE. +[MIT](https://choosealicense.com/licenses/mit/)