From 7e8a792a8672fd1b0a3026f316855db99199e60d Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sun, 10 Jun 2018 19:01:12 +0100 Subject: [PATCH 01/13] ignore package-lock.json --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 01a7ce3..6a5bcc8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ blog.md node_modules/ npm-debug.log +package-lock.json From eeb73c41be06b2acf0830bcc7ad7cc164dc0c10f Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sun, 10 Jun 2018 19:01:46 +0100 Subject: [PATCH 02/13] update obsolete deps, add new deps, update start script --- package.json | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 5301d9e..cddd2ef 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,18 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "supervisor ./bin/www" + "start": "node ./bin/www" }, "dependencies": { - "body-parser": "~1.15.1", - "cookie-parser": "~1.4.3", - "debug": "~2.2.0", - "express": "~4.13.4", - "jade": "~1.11.0", - "morgan": "~1.7.0", - "pg": "^6.1.0", - "serve-favicon": "~2.3.0" + "body-parser": "^1.18.3", + "cookie-parser": "1.4.3", + "db-migrate": "^0.11.1", + "db-migrate-pg": "^0.4.0", + "debug": "^3.1.0", + "express": "^4.16.3", + "jade": "1.11.0", + "morgan": "^1.9.0", + "pg": "^7.4.3", + "serve-favicon": "^2.5.0" } } From 94fd40ba0de55ea3cec1c50aff0cb64f271cdbfa Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sun, 10 Jun 2018 19:02:26 +0100 Subject: [PATCH 03/13] setup migrations and remove old setup code --- .env | 3 ++ migrations/20180610171545-bootstrap-db.js | 53 +++++++++++++++++++ .../sqls/20180610171545-bootstrap-db-up.sql | 5 ++ server/models/database.js | 8 --- 4 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 .env create mode 100644 migrations/20180610171545-bootstrap-db.js create mode 100644 migrations/sqls/20180610171545-bootstrap-db-up.sql delete mode 100644 server/models/database.js diff --git a/.env b/.env new file mode 100644 index 0000000..a5dde8e --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +PORT=5000 +DATABASE_URL=postgres://postgres:ppp@localhost:5432/todos +PGSSLMODE=disable diff --git a/migrations/20180610171545-bootstrap-db.js b/migrations/20180610171545-bootstrap-db.js new file mode 100644 index 0000000..79ebbf0 --- /dev/null +++ b/migrations/20180610171545-bootstrap-db.js @@ -0,0 +1,53 @@ +'use strict'; + +var dbm; +var type; +var seed; +var fs = require('fs'); +var path = require('path'); +var Promise; + +/** + * We receive the dbmigrate dependency from dbmigrate initially. + * This enables us to not have to rely on NODE_PATH. + */ +exports.setup = function(options, seedLink) { + dbm = options.dbmigrate; + type = dbm.dataType; + seed = seedLink; + Promise = options.Promise; +}; + +exports.up = function(db) { + var filePath = path.join(__dirname, 'sqls', '20180610171545-bootstrap-db-up.sql'); + return new Promise( function( resolve, reject ) { + fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ + if (err) return reject(err); + console.log('received data: ' + data); + + resolve(data); + }); + }) + .then(function(data) { + return db.runSql(data); + }); +}; + +exports.down = function(db) { + var filePath = path.join(__dirname, 'sqls', '20180610171545-bootstrap-db-down.sql'); + return new Promise( function( resolve, reject ) { + fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ + if (err) return reject(err); + console.log('received data: ' + data); + + resolve(data); + }); + }) + .then(function(data) { + return db.runSql(data); + }); +}; + +exports._meta = { + "version": 1 +}; diff --git a/migrations/sqls/20180610171545-bootstrap-db-up.sql b/migrations/sqls/20180610171545-bootstrap-db-up.sql new file mode 100644 index 0000000..4ee69e3 --- /dev/null +++ b/migrations/sqls/20180610171545-bootstrap-db-up.sql @@ -0,0 +1,5 @@ +CREATE TABLE items( + id SERIAL PRIMARY KEY, + text VARCHAR NOT NULL, + complete BOOLEAN +); diff --git a/server/models/database.js b/server/models/database.js deleted file mode 100644 index c9d8c0a..0000000 --- a/server/models/database.js +++ /dev/null @@ -1,8 +0,0 @@ -const pg = require('pg'); -const connectionString = process.env.DATABASE_URL || 'postgres://localhost:5432/todo'; - -const client = new pg.Client(connectionString); -client.connect(); -const query = client.query( - 'CREATE TABLE items(id SERIAL PRIMARY KEY, text VARCHAR(40) not null, complete BOOLEAN)'); -query.on('end', () => { client.end(); }); From 7864c16c3ab50e4a6e65c90b692c39f5a42040f1 Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sun, 10 Jun 2018 19:02:58 +0100 Subject: [PATCH 04/13] fix up old code that doesn't work with new dep versions of PG clients --- server/routes/index.js | 51 +++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/server/routes/index.js b/server/routes/index.js index 40d4bb4..8499eb4 100644 --- a/server/routes/index.js +++ b/server/routes/index.js @@ -1,8 +1,11 @@ const express = require('express'); const router = express.Router(); -const pg = require('pg'); +const { Client } = require('pg'); +const connectionString = process.env.DATABASE_URL; +const pg = new Client({ connectionString }); +pg.connect(); const path = require('path'); -const connectionString = process.env.DATABASE_URL || 'postgres://localhost:5432/todo'; + router.get('/', (req, res, next) => { res.sendFile(path.join( @@ -12,12 +15,16 @@ router.get('/', (req, res, next) => { router.get('/api/v1/todos', (req, res, next) => { const results = []; // Get a Postgres client from the connection pool - pg.connect(connectionString, (err, client, done) => { + + return pg.query('SELECT * FROM items ORDER BY id ASC;') + .then(({ rows }) => res.json(rows)) + .catch(e => console.log(e) || res.status(500).json({success: false, data: e})); + + /*pg.connect(connectionString, (err, client, done) => { // Handle connection errors - if(err) { + if (err) { done(); - console.log(err); - return res.status(500).json({success: false, data: err}); + } // SQL Query > Select Data const query = client.query('SELECT * FROM items ORDER BY id ASC;'); @@ -30,15 +37,21 @@ router.get('/api/v1/todos', (req, res, next) => { done(); return res.json(results); }); - }); + });*/ }); router.post('/api/v1/todos', (req, res, next) => { const results = []; // Grab data from http request const data = {text: req.body.text, complete: false}; + + return pg.query('INSERT INTO items(text, complete) values($1, $2)', [data.text, data.complete]) + .then(() => pg.query('SELECT * FROM items ORDER BY id ASC')) + .then(({ rows }) => res.json(rows)) + .catch(e => console.log(e) || res.status(500).json({success: false, data: e})); + // Get a Postgres client from the connection pool - pg.connect(connectionString, (err, client, done) => { + /*pg.connect(connectionString, (err, client, done) => { // Handle connection errors if(err) { done(); @@ -59,7 +72,7 @@ router.post('/api/v1/todos', (req, res, next) => { done(); return res.json(results); }); - }); + });*/ }); router.put('/api/v1/todos/:todo_id', (req, res, next) => { @@ -68,8 +81,14 @@ router.put('/api/v1/todos/:todo_id', (req, res, next) => { const id = req.params.todo_id; // Grab data from http request const data = {text: req.body.text, complete: req.body.complete}; + + return pg.query('UPDATE items SET text=($1), complete=($2) WHERE id=($3)', [data.text, data.complete, id]) + .then(() => pg.query('SELECT * FROM items ORDER BY id ASC')) + .then(({ rows }) => res.json(rows)) + .catch(e => console.log(e) || res.status(500).json({success: false, data: e})); + // Get a Postgres client from the connection pool - pg.connect(connectionString, (err, client, done) => { + /*pg.connect(connectionString, (err, client, done) => { // Handle connection errors if(err) { done(); @@ -90,15 +109,21 @@ router.put('/api/v1/todos/:todo_id', (req, res, next) => { done(); return res.json(results); }); - }); + });*/ }); router.delete('/api/v1/todos/:todo_id', (req, res, next) => { const results = []; // Grab data from the URL parameters const id = req.params.todo_id; + + return pg.query('DELETE FROM items WHERE id=($1)', [id]) + .then(() => pg.query('SELECT * FROM items ORDER BY id ASC')) + .then(({ rows }) => res.json(rows)) + .catch(e => console.log(e) || res.status(500).json({success: false, data: e})); + // Get a Postgres client from the connection pool - pg.connect(connectionString, (err, client, done) => { + /*pg.connect(connectionString, (err, client, done) => { // Handle connection errors if(err) { done(); @@ -118,7 +143,7 @@ router.delete('/api/v1/todos/:todo_id', (req, res, next) => { done(); return res.json(results); }); - }); + });*/ }); module.exports = router; From be538fbb71c1063e29162679316f480ce5f3a7cf Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sun, 10 Jun 2018 19:03:14 +0100 Subject: [PATCH 05/13] setup for Heroku --- Procfile | 1 + 1 file changed, 1 insertion(+) create mode 100644 Procfile diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..063b78f --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: npm start From e32366385472a8a1fcd90ac64d6befc90992ce1b Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sun, 10 Jun 2018 19:08:13 +0100 Subject: [PATCH 06/13] setup a release task --- Procfile | 1 + package.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Procfile b/Procfile index 063b78f..1a303fb 100644 --- a/Procfile +++ b/Procfile @@ -1 +1,2 @@ web: npm start +release: npm run db-migrate -- up diff --git a/package.json b/package.json index cddd2ef..58db4bf 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "node ./bin/www" + "start": "node ./bin/www", + "db-migrate": "node ./node_modules/.bin/db-migrate" }, "dependencies": { "body-parser": "^1.18.3", From f1af90f0a0cdb94f05839cc9577108162ecee36f Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sun, 10 Jun 2018 19:28:07 +0100 Subject: [PATCH 07/13] add app.json --- app.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 app.json diff --git a/app.json b/app.json new file mode 100644 index 0000000..7500ddd --- /dev/null +++ b/app.json @@ -0,0 +1,19 @@ +{ + "name": "Sheffield Devops Demo Todos", + "description": "", + "scripts": {}, + "env": {}, + "formation": { + "web": { + "quantity": 1 + } + }, + "addons": [ + "heroku-postgresql" + ], + "buildpacks": [ + { + "url": "heroku/nodejs" + } + ] +} From 709021d00f3312540466b1d0865fea331cb3cdfc Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sun, 10 Jun 2018 20:01:04 +0100 Subject: [PATCH 08/13] add a resource for the environment label --- .env | 1 + server/routes/index.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.env b/.env index a5dde8e..27f4d23 100644 --- a/.env +++ b/.env @@ -1,3 +1,4 @@ PORT=5000 DATABASE_URL=postgres://postgres:ppp@localhost:5432/todos PGSSLMODE=disable +TODO_ENV=local-dev diff --git a/server/routes/index.js b/server/routes/index.js index 8499eb4..2a131c3 100644 --- a/server/routes/index.js +++ b/server/routes/index.js @@ -146,4 +146,7 @@ router.delete('/api/v1/todos/:todo_id', (req, res, next) => { });*/ }); +router.get('/api/v1/environment', (req, res, next) => + res.json({ environment: process.env.TODO_ENV || "¯\_(ツ)_/¯"})); + module.exports = router; From a71fa2f427882ffeaf8be93a841fafcccdef1483 Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sun, 10 Jun 2018 20:09:56 +0100 Subject: [PATCH 09/13] Create demo-script.md --- demo-script.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 demo-script.md diff --git a/demo-script.md b/demo-script.md new file mode 100644 index 0000000..41a0cf8 --- /dev/null +++ b/demo-script.md @@ -0,0 +1,45 @@ +## Setup project to ready for Heroku + +- nvm/npm +- clone repo +- update dependencies +- pull a postgres image +- run postgres image, remember to expose port on localhost +- psql -U ... -h ... +- create a db (chicken/egg problem if you don't create the DB first...) +- setup .env file +- install db-migrate (supports DATABASE_URL + dotenv) + db-migrate-pg +- install heroku cli +- npm start - oops no schema +- npm release (builds local schema) +- npm start + +## Create our first app + +- create app (shefdevops-todo-staging) +- add a postgres db +- enable automatic deploys (doesn't bootstrap) +- deploy +- show build log, release log, and app + +## Create a pipeline + +- add to a pipeline (shefdevops-demo) +- add a production app (shefdevops-todo-prod) +- add postgres DB +- deploy + +## Release a change + +- enable review apps (note app.json) +- fetch; create new branch with new /api/v1/environment endpoint +- push; create PR +- note review app; deploy it +- note endpoint doesn't know what env it is - add TODO_ENV environment variable +- merge PR; show review app is gone, and staging is deploying +- add TODO_ENV to staging +- show +- add TODO_env to production +- Promote; show endpoint works + +## DONE! From 11966d8e9d98a1d4c86ae0ca170d35c5864e1bb8 Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sun, 10 Jun 2018 20:12:51 +0100 Subject: [PATCH 10/13] Revert "add a resource for the environment label" This reverts commit 709021d00f3312540466b1d0865fea331cb3cdfc. --- .env | 1 - server/routes/index.js | 3 --- 2 files changed, 4 deletions(-) diff --git a/.env b/.env index 27f4d23..a5dde8e 100644 --- a/.env +++ b/.env @@ -1,4 +1,3 @@ PORT=5000 DATABASE_URL=postgres://postgres:ppp@localhost:5432/todos PGSSLMODE=disable -TODO_ENV=local-dev diff --git a/server/routes/index.js b/server/routes/index.js index 2a131c3..8499eb4 100644 --- a/server/routes/index.js +++ b/server/routes/index.js @@ -146,7 +146,4 @@ router.delete('/api/v1/todos/:todo_id', (req, res, next) => { });*/ }); -router.get('/api/v1/environment', (req, res, next) => - res.json({ environment: process.env.TODO_ENV || "¯\_(ツ)_/¯"})); - module.exports = router; From 40d459c73e744c61465b1fd63d9ca577c66fd0d1 Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sat, 11 Aug 2018 15:05:55 +0100 Subject: [PATCH 11/13] default to same app port that was originally defaulted to --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index a5dde8e..deff20a 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ -PORT=5000 +PORT=3000 DATABASE_URL=postgres://postgres:ppp@localhost:5432/todos PGSSLMODE=disable From c22230e8ec1cf2930d22bfc6a226a27bfbc388a3 Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sat, 11 Aug 2018 15:06:30 +0100 Subject: [PATCH 12/13] tidy up code updates for PR back --- demo-script.md | 45 -------------- server/routes/index.js | 131 ++++------------------------------------- 2 files changed, 10 insertions(+), 166 deletions(-) delete mode 100644 demo-script.md diff --git a/demo-script.md b/demo-script.md deleted file mode 100644 index 41a0cf8..0000000 --- a/demo-script.md +++ /dev/null @@ -1,45 +0,0 @@ -## Setup project to ready for Heroku - -- nvm/npm -- clone repo -- update dependencies -- pull a postgres image -- run postgres image, remember to expose port on localhost -- psql -U ... -h ... -- create a db (chicken/egg problem if you don't create the DB first...) -- setup .env file -- install db-migrate (supports DATABASE_URL + dotenv) + db-migrate-pg -- install heroku cli -- npm start - oops no schema -- npm release (builds local schema) -- npm start - -## Create our first app - -- create app (shefdevops-todo-staging) -- add a postgres db -- enable automatic deploys (doesn't bootstrap) -- deploy -- show build log, release log, and app - -## Create a pipeline - -- add to a pipeline (shefdevops-demo) -- add a production app (shefdevops-todo-prod) -- add postgres DB -- deploy - -## Release a change - -- enable review apps (note app.json) -- fetch; create new branch with new /api/v1/environment endpoint -- push; create PR -- note review app; deploy it -- note endpoint doesn't know what env it is - add TODO_ENV environment variable -- merge PR; show review app is gone, and staging is deploying -- add TODO_ENV to staging -- show -- add TODO_env to production -- Promote; show endpoint works - -## DONE! diff --git a/server/routes/index.js b/server/routes/index.js index 8499eb4..c264454 100644 --- a/server/routes/index.js +++ b/server/routes/index.js @@ -6,144 +6,33 @@ const pg = new Client({ connectionString }); pg.connect(); const path = require('path'); - router.get('/', (req, res, next) => { res.sendFile(path.join( __dirname, '..', '..', 'client', 'views', 'index.html')); }); -router.get('/api/v1/todos', (req, res, next) => { - const results = []; - // Get a Postgres client from the connection pool - - return pg.query('SELECT * FROM items ORDER BY id ASC;') +router.get('/api/v1/todos', (req, res, next) => pg.query('SELECT * FROM items ORDER BY id ASC;') .then(({ rows }) => res.json(rows)) - .catch(e => console.log(e) || res.status(500).json({success: false, data: e})); - - /*pg.connect(connectionString, (err, client, done) => { - // Handle connection errors - if (err) { - done(); + .catch(e => console.error(e) || res.status(500).json({success: false, data: e}))); - } - // SQL Query > Select Data - const query = client.query('SELECT * FROM items ORDER BY id ASC;'); - // Stream results back one row at a time - query.on('row', (row) => { - results.push(row); - }); - // After all data is returned, close connection and return results - query.on('end', () => { - done(); - return res.json(results); - }); - });*/ -}); - -router.post('/api/v1/todos', (req, res, next) => { - const results = []; - // Grab data from http request - const data = {text: req.body.text, complete: false}; - - return pg.query('INSERT INTO items(text, complete) values($1, $2)', [data.text, data.complete]) +router.post('/api/v1/todos', (req, res, next) => pg.query('INSERT INTO items(text, complete) values($1, $2)', [req.body.text, false]) .then(() => pg.query('SELECT * FROM items ORDER BY id ASC')) .then(({ rows }) => res.json(rows)) - .catch(e => console.log(e) || res.status(500).json({success: false, data: e})); - - // Get a Postgres client from the connection pool - /*pg.connect(connectionString, (err, client, done) => { - // Handle connection errors - if(err) { - done(); - console.log(err); - return res.status(500).json({success: false, data: err}); - } - // SQL Query > Insert Data - client.query('INSERT INTO items(text, complete) values($1, $2)', - [data.text, data.complete]); - // SQL Query > Select Data - const query = client.query('SELECT * FROM items ORDER BY id ASC'); - // Stream results back one row at a time - query.on('row', (row) => { - results.push(row); - }); - // After all data is returned, close connection and return results - query.on('end', () => { - done(); - return res.json(results); - }); - });*/ -}); + .catch(e => console.error(e) || res.status(500).json({success: false, data: e}))); router.put('/api/v1/todos/:todo_id', (req, res, next) => { - const results = []; - // Grab data from the URL parameters - const id = req.params.todo_id; - // Grab data from http request - const data = {text: req.body.text, complete: req.body.complete}; + const { text, complete } = req.body; + const { todo_id: id } = req.params; - return pg.query('UPDATE items SET text=($1), complete=($2) WHERE id=($3)', [data.text, data.complete, id]) + return pg.query('UPDATE items SET text=($1), complete=($2) WHERE id=($3)', [text, complete, id]) .then(() => pg.query('SELECT * FROM items ORDER BY id ASC')) .then(({ rows }) => res.json(rows)) .catch(e => console.log(e) || res.status(500).json({success: false, data: e})); + }); - // Get a Postgres client from the connection pool - /*pg.connect(connectionString, (err, client, done) => { - // Handle connection errors - if(err) { - done(); - console.log(err); - return res.status(500).json({success: false, data: err}); - } - // SQL Query > Update Data - client.query('UPDATE items SET text=($1), complete=($2) WHERE id=($3)', - [data.text, data.complete, id]); - // SQL Query > Select Data - const query = client.query("SELECT * FROM items ORDER BY id ASC"); - // Stream results back one row at a time - query.on('row', (row) => { - results.push(row); - }); - // After all data is returned, close connection and return results - query.on('end', function() { - done(); - return res.json(results); - }); - });*/ -}); - -router.delete('/api/v1/todos/:todo_id', (req, res, next) => { - const results = []; - // Grab data from the URL parameters - const id = req.params.todo_id; - - return pg.query('DELETE FROM items WHERE id=($1)', [id]) +router.delete('/api/v1/todos/:todo_id', (req, res, next) => pg.query('DELETE FROM items WHERE id=($1)', [req.params.todo_id]) .then(() => pg.query('SELECT * FROM items ORDER BY id ASC')) .then(({ rows }) => res.json(rows)) - .catch(e => console.log(e) || res.status(500).json({success: false, data: e})); - - // Get a Postgres client from the connection pool - /*pg.connect(connectionString, (err, client, done) => { - // Handle connection errors - if(err) { - done(); - console.log(err); - return res.status(500).json({success: false, data: err}); - } - // SQL Query > Delete Data - client.query('DELETE FROM items WHERE id=($1)', [id]); - // SQL Query > Select Data - var query = client.query('SELECT * FROM items ORDER BY id ASC'); - // Stream results back one row at a time - query.on('row', (row) => { - results.push(row); - }); - // After all data is returned, close connection and return results - query.on('end', () => { - done(); - return res.json(results); - }); - });*/ -}); + .catch(e => console.log(e) || res.status(500).json({success: false, data: e}))); module.exports = router; From 2bcc8e78f729ae6f6b45fbd1e50d6d3de0c6df91 Mon Sep 17 00:00:00 2001 From: Paul Brabban Date: Sat, 11 Aug 2018 15:07:07 +0100 Subject: [PATCH 13/13] update readme, use .env for config --- app.json | 2 +- bin/www | 3 +++ package.json | 1 + readme.md | 22 +++++++++++++++++++--- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app.json b/app.json index 7500ddd..8e01a31 100644 --- a/app.json +++ b/app.json @@ -1,5 +1,5 @@ { - "name": "Sheffield Devops Demo Todos", + "name": "node-postgres-todo", "description": "", "scripts": {}, "env": {}, diff --git a/bin/www b/bin/www index 96716ac..56adb2c 100755 --- a/bin/www +++ b/bin/www @@ -4,6 +4,9 @@ * Module dependencies. */ +// get environment from .env file, if present +require('dotenv').config(); + var app = require('../app'); var debug = require('debug')('node-postgres-todo:server'); var http = require('http'); diff --git a/package.json b/package.json index 58db4bf..cc6490d 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "db-migrate": "^0.11.1", "db-migrate-pg": "^0.4.0", "debug": "^3.1.0", + "dotenv": "^6.0.0", "express": "^4.16.3", "jade": "1.11.0", "morgan": "^1.9.0", diff --git a/readme.md b/readme.md index d68ecdc..f740654 100644 --- a/readme.md +++ b/readme.md @@ -7,9 +7,9 @@ This is a basic single page application built with Node, Express, Angular, and P ## Quick Start 1. Clone the repo -1. Install dependencies: `npm install` -1. Start your Postgres server and create a database called "todo" -1. Create the database tables: `node server/models/database.js` +1. Install dependencies: `$ npm install` +1. Start your Postgres server and create a database called "todos" +1. Create the database tables: `$ npm run db-migrate up` 1. Start the server: `$ npm start` ## Tests @@ -28,3 +28,19 @@ Using this load test it is possible to verify several things: See the comments in the [script](https://github.com/mjhea0/node-postgres-todo/blob/master/test/load-test.sh) for more information. +## Running on Heroku + +Files are provided to run this app on Heroku. +- `Procfile` - configures the app and release task that migrates the associated database +- `app.json` - configures the app Heroku CI, to run tests automatically as needed + +## Using a Dockerized PostgreSQL server + +If you have docker installed, you can run your PostgreSQL database in a container. +The following command will run a database at the latest PostgreSQL version. + +`docker run --rm -p"5432:5432" -e POSTGRES_PASSWORD=ppp -d postgres` + +Your host port `5432` to the containers port `5432`, so it will appear as if you have a local PostgreSQL install. +The password will be "ppp". +The `--rm` flag deletes the container when you shut it down - leave the flag off to keep it around.