├── .gitignore ├── annotations.txt ├── preclass ├── kubeconfig │ ├── api-svc.json │ ├── api.json │ ├── postgres-svc.json │ └── postgres.json ├── nodejs-with-postgres-api-example │ ├── .dockerignore │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── docker-compose.yml │ ├── index.js │ ├── package.json │ └── run.sh └── run.sh └── recorded ├── .vscode └── settings.json ├── kubeconfig ├── api-deployment.json ├── api-svc.json ├── postgres-sts.json └── postgres-svc.json ├── nodejs-with-postgres-api-example ├── .dockerignore ├── .gitignore ├── Dockerfile ├── README.md ├── docker-compose.yml ├── index.js ├── package.json └── run.sh └── scripts.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* 117 | -------------------------------------------------------------------------------- /annotations.txt: -------------------------------------------------------------------------------- 1 | git clone https://github.com/ErickWendel/nodejs-with-postgres-api-example 2 | docker-compose up 3 | npm run testAll 4 | localhost:3000/documentation 5 | 6 | dockerhub.com 7 | -> create account 8 | 9 | docker login 10 | 11 | docker build -t app nodejs-with-postgres-api-example 12 | 13 | docker tag app erickwendel/nodejs-with-postgres-api-example 14 | 15 | docker push erickwendel/nodejs-with-postgres-api-example 16 | 17 | # ------ 18 | 19 | minikube start 20 | kubectl get node 21 | kubectl get svc 22 | 23 | minikube dashboard 24 | 25 | mkdir kubeconfig 26 | create postgres.json 27 | kubectl create -f postgres.json 28 | kubectl get sts -w 29 | kubectl describe statefulset postgres 30 | kubectl get pod 31 | kubectl describe pod 32 | 33 | create postgres-svc.json 34 | kubectl create -f postgres.json 35 | kubectl get svc -w 36 | kubectl describe service postgres-svc 37 | 38 | create api.json 39 | kubectl create -f api.json 40 | kubectl get deploy -w 41 | kubectl describe deploy api-heroes 42 | kubectl get pod -w 43 | kubectl logs api-heroes-76b6bd4d7c-559r5 44 | create api-svc.json 45 | kubectl create -f api-svc.json 46 | kubectl get svc -w 47 | kubectl describe service api-heroes-svc 48 | 49 | minikube service api-heroes 50 | URL:/documentation 51 | 52 | change run.sh 53 | -> HOST 54 | npm run testAll 55 | -------------------------------------------------------------------------------- /preclass/kubeconfig/api-svc.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Service", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "api-heroes-svc", 6 | "labels": { 7 | "version": "v1", 8 | "app": "api-heroes" 9 | } 10 | }, 11 | "spec": { 12 | "selector": { 13 | "app": "api-heroes" 14 | 15 | }, 16 | "type": "LoadBalancer", 17 | "ports": [{ 18 | "protocol": "TCP", 19 | "port": 3000, 20 | "targetPort": 3000 21 | }] 22 | } 23 | } -------------------------------------------------------------------------------- /preclass/kubeconfig/api.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "apps/v1", 3 | "kind": "Deployment", 4 | "metadata": { 5 | "name": "api-heroes", 6 | "labels": { 7 | "app": "api-heroes" 8 | } 9 | }, 10 | "spec": { 11 | "replicas": 1, 12 | "selector": { 13 | "matchLabels": { 14 | "app": "api-heroes" 15 | } 16 | }, 17 | 18 | "template": { 19 | "metadata": { 20 | "labels": { 21 | "app": "api-heroes" 22 | } 23 | }, 24 | "spec": { 25 | "containers": [ 26 | { 27 | "name": "api-heroes", 28 | "image": "erickwendel/nodejs-with-postgres-api-example", 29 | "ports": [ 30 | { 31 | "containerPort": 3000 32 | } 33 | ], 34 | "env": [ 35 | { 36 | "name": "POSTGRES_HOST", 37 | "value": "postgres:mysecretpassword@postgres-svc" 38 | }, 39 | { 40 | "name": "POSTGRES_DB", 41 | "value": "heroes" 42 | }, 43 | { 44 | "name": "PORT", 45 | "value": "3000" 46 | } 47 | ] 48 | } 49 | ] 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /preclass/kubeconfig/postgres-svc.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Service", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "postgres-svc", 6 | "labels": { 7 | "version": "v1", 8 | "app": "postgres" 9 | } 10 | }, 11 | "spec": { 12 | "selector": { 13 | "app": "postgres" 14 | }, 15 | "type": "ClusterIP", 16 | "ports": [{ 17 | "protocol": "TCP", 18 | "port": 5432, 19 | "targetPort": 5432 20 | }] 21 | } 22 | } -------------------------------------------------------------------------------- /preclass/kubeconfig/postgres.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "apps/v1", 3 | "kind": "StatefulSet", 4 | "metadata": { 5 | "name": "postgres", 6 | "labels": { 7 | "app": "postgres" 8 | } 9 | }, 10 | "spec": { 11 | "serviceName": "postgres-svc", 12 | "replicas": 1, 13 | "selector": { 14 | "matchLabels": { 15 | "app": "postgres" 16 | } 17 | }, 18 | "volumeClaimTemplates": [ 19 | { 20 | "metadata": { 21 | "name": "db-storage" 22 | }, 23 | "spec": { 24 | "storageClassName": "standard", 25 | "accessModes": ["ReadWriteOnce"], 26 | "resources": { 27 | "requests": { 28 | "storage": "1Gi" 29 | } 30 | } 31 | } 32 | } 33 | ], 34 | "template": { 35 | "metadata": { 36 | "labels": { 37 | "app": "postgres" 38 | } 39 | }, 40 | "spec": { 41 | "containers": [ 42 | { 43 | "name": "postgres", 44 | "image": "postgres:latest", 45 | "env": [ 46 | { 47 | "name": "POSTGRES_DB", 48 | "value": "heroes" 49 | }, 50 | { 51 | "name": "POSTGRES_PASSWORD", 52 | "value": "mysecretpassword" 53 | } 54 | ], 55 | "ports": [ 56 | { 57 | "containerPort": 5432, 58 | "name": "postgredb" 59 | } 60 | ], 61 | "volumeMounts": [ 62 | { 63 | "mountPath": "/var/lib/postgresql/data", 64 | "name": "db-storage" 65 | } 66 | ] 67 | } 68 | ] 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /preclass/nodejs-with-postgres-api-example/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /preclass/nodejs-with-postgres-api-example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /preclass/nodejs-with-postgres-api-example/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10-alpine 2 | 3 | RUN mkdir -p /src 4 | 5 | COPY package.json src/package.json 6 | 7 | WORKDIR /src 8 | 9 | RUN npm install --only=production --silent 10 | 11 | COPY . /src 12 | 13 | CMD npm start -------------------------------------------------------------------------------- /preclass/nodejs-with-postgres-api-example/README.md: -------------------------------------------------------------------------------- 1 | ## Node.js with Postgres Example 2 | 3 | Swagger Page of that application 7 | 8 | ### Requirements 9 | 10 | * Node.js v8+ or Docker and Docker Compose 11 | * Postgres running on local instance or Docker 12 | 13 | ### Running on localMachine 14 | 15 | * Install dependencies - `npm i` 16 | * Run project - `npm start` 17 | 18 | ### OR: Docker 19 | 20 | * `docker-compose up` 21 | 22 | ### OR: Alternatives on pulling from Docker hub 23 | 24 | * Docker hub image: [erickwendel/nodejs-with-postgres-api-example](https://hub.docker.com/r/erickwendel/nodejs-with-postgres-api-example/) 25 | 26 | ```shell 27 | docker run -d -p 5432:5432 --name postgres \ 28 | --env POSTGRES_PASSWORD=mysecretpassword \ 29 | --env POSTGRES_DB=heroes\ 30 | postgres 31 | ``` 32 | 33 | ```shell 34 | docker run -p 3000:3000 \ 35 | --link postgres:postgres \ 36 | -e POSTGRES_HOST=postgres:mysecretpassword@postgres:5432 \ 37 | -e POSTGRES_DB=heroes \ 38 | -e POSTGRES_SSL=false \ 39 | erickwendel/nodejs-with-postgres-api-example:latest 40 | ``` 41 | 42 | ### Viewing 43 | 44 | * Go to swagger page - `localhost:3000/documentation` 45 | -------------------------------------------------------------------------------- /preclass/nodejs-with-postgres-api-example/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | api-heroes-postgres: 4 | container_name: api-heroes-postgres 5 | build: . 6 | ports: 7 | - 3000:3000 8 | environment: 9 | POSTGRES_HOST: postgres:mysecretpassword@postgres:5432 10 | PORT: 3000 11 | 12 | depends_on: 13 | - postgres 14 | links: 15 | - postgres 16 | 17 | postgres: 18 | container_name: postgres 19 | restart: always 20 | image: postgres 21 | ports: 22 | - 5432:5432 23 | environment: 24 | POSTGRES_PASSWORD: mysecretpassword 25 | POSTGRES_DB: heroes -------------------------------------------------------------------------------- /preclass/nodejs-with-postgres-api-example/index.js: -------------------------------------------------------------------------------- 1 | const Joi = require('joi') 2 | const Sequelize = require('sequelize') 3 | const Hapi = require('hapi'); 4 | const Inert = require("inert"); 5 | const Vision = require("vision"); 6 | const HapiSwagger = require("hapi-swagger"); 7 | const port = process.env.PORT || 3000; 8 | const server = new Hapi.Server( 9 | { 10 | port 11 | } 12 | ); 13 | 14 | const failAction = async (request, h, err) => { 15 | console.error('err', err) 16 | throw err; 17 | } 18 | 19 | (async () => { 20 | if (!process.env.POSTGRES_HOST) { 21 | throw Error( 22 | "process.env.POSTGRES_HOST must be a: user:pass@ipService:port ", 23 | ); 24 | } 25 | const sequelize = new Sequelize( 26 | `postgres://${process.env.POSTGRES_HOST}/${process.env.POSTGRES_DB || "heroes"}`, 27 | { 28 | ssl: process.env.POSTGRES_SSL, 29 | dialectOptions: { 30 | ssl: process.env.POSTGRES_SSL, 31 | }, 32 | } 33 | ); 34 | await sequelize.authenticate(); 35 | console.log("postgres is running"); 36 | 37 | const Hero = sequelize.define("hero", { 38 | name: Sequelize.STRING, 39 | power: Sequelize.STRING, 40 | }); 41 | 42 | await Hero.sync({ force: true }); 43 | 44 | await server.register([ 45 | Inert, 46 | Vision, 47 | { 48 | plugin: HapiSwagger, 49 | options: { 50 | info: { 51 | title: "Node.js with Postgres Example - Erick Wendel", 52 | version: "1.0", 53 | }, 54 | } 55 | }, 56 | ]); 57 | 58 | server.route([ 59 | { 60 | method: "GET", 61 | path: "/heroes", 62 | handler: () => { 63 | return Hero.findAll(); 64 | }, 65 | config: { 66 | description: "List All heroes", 67 | notes: "heroes from database", 68 | tags: ["api"], 69 | }, 70 | }, 71 | { 72 | method: "GET", 73 | path: "/heroes/{id}", 74 | handler: (req) => { 75 | return Hero.findAll({ where: { id: req.params.id } }); 76 | }, 77 | config: { 78 | description: "Get a hero", 79 | notes: "heroes from database", 80 | tags: ["api"], 81 | }, 82 | }, 83 | { 84 | method: "POST", 85 | path: "/heroes", 86 | config: { 87 | handler: (req) => { 88 | const { payload } = req; 89 | return Hero.create(payload); 90 | }, 91 | description: "Create a hero", 92 | notes: "create a hero", 93 | tags: ["api"], 94 | validate: { 95 | failAction, 96 | 97 | payload: { 98 | name: Joi.string().required(), 99 | power: Joi.string().required(), 100 | }, 101 | }, 102 | }, 103 | }, 104 | { 105 | method: "PUT", 106 | path: "/heroes/{id}", 107 | config: { 108 | handler: (req) => { 109 | const { payload } = req; 110 | return Hero.update(payload, { where: { id: req.params.id } }); 111 | }, 112 | description: "Create a hero", 113 | notes: "create a hero", 114 | tags: ["api"], 115 | validate: { 116 | failAction, 117 | params: { 118 | id: Joi.string().required(), 119 | }, 120 | payload: { 121 | name: Joi.string(), 122 | power: Joi.string(), 123 | }, 124 | }, 125 | }, 126 | }, 127 | 128 | { 129 | method: "DELETE", 130 | path: "/heroes/{id}", 131 | config: { 132 | handler: (req) => { 133 | return Hero.destroy({ where: { id: req.params.id } }); 134 | }, 135 | description: "Delete a hero", 136 | notes: "Delete a hero", 137 | tags: ["api"], 138 | validate: { 139 | failAction, 140 | params: { 141 | id: Joi.string().required(), 142 | }, 143 | }, 144 | }, 145 | }, 146 | ]); 147 | 148 | await server.start(); 149 | console.log("server running at", server.info.port); 150 | })(); 151 | -------------------------------------------------------------------------------- /preclass/nodejs-with-postgres-api-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docker-registry", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "npx pm2-docker index.js", 8 | "testAll": "sh run.sh" 9 | }, 10 | "keywords": [], 11 | "author": "erickwendel", 12 | "license": "ISC", 13 | "dependencies": { 14 | "hapi": "18.1.0", 15 | "hapi-swagger": "9.4.2", 16 | "inert": "5.1.3", 17 | "joi": "14.3.1", 18 | "pg": "7.10.0", 19 | "pg-hstore": "2.3.2", 20 | "pm2": "3.5.0", 21 | "sequelize": "5.6.1", 22 | "vision": "5.4.4" 23 | }, 24 | "devDependencies": {} 25 | } 26 | -------------------------------------------------------------------------------- /preclass/nodejs-with-postgres-api-example/run.sh: -------------------------------------------------------------------------------- 1 | HOST=localhost:3000 2 | # HOST=http://192.168.64.5:30875 3 | 4 | echo '\n\n creating Chapolin' 5 | CREATE=$( 6 | curl --silent -X POST \ 7 | --header "Content-Type: application/json" \ 8 | --data-binary '{"name":"Chapolin","power":"Strength"}' \ 9 | $HOST/heroes 10 | ) 11 | 12 | echo $CREATE | jq 13 | 14 | ID=$(echo $CREATE | jq .id) 15 | 16 | echo "\n\n requesting chapolin $ID" 17 | curl --silent $HOST/heroes/$ID | jq 18 | 19 | echo '\n\n requesting all heroes' 20 | curl --silent $HOST/heroes | jq 21 | 22 | echo "\n\n updating chapolin $ID" 23 | curl --silent -X PUT \ 24 | --header "Content-Type: application/json" \ 25 | --data-binary '{"name":"Batman","power":"Rich"}' \ 26 | $HOST/heroes/$ID \ 27 | | jq 28 | 29 | echo "\n\n requesting id: $ID" 30 | curl --silent $HOST/heroes/$ID | jq 31 | 32 | echo "\n\n removing id: $ID" 33 | curl --silent -X DELETE \ 34 | --header "Content-Type: application/json" \ 35 | $HOST/heroes/$ID \ 36 | | jq 37 | 38 | echo '\n\n requesting all heroes' 39 | curl --silent $HOST/heroes | jq 40 | -------------------------------------------------------------------------------- /preclass/run.sh: -------------------------------------------------------------------------------- 1 | docker login 2 | 3 | docker build -t app nodejs-with-postgres-api-example 4 | 5 | docker tag app erickwendel/nodejs-with-postgres-api-example 6 | 7 | docker push erickwendel/nodejs-with-postgres-api-example 8 | 9 | # ------ 10 | 11 | minikube start 12 | kubectl get node 13 | kubectl get svc 14 | 15 | minikube dashboard 16 | 17 | kubectl create -f postgres.json 18 | kubectl describe statefulset postgres-demo 19 | kubectl get sts -w 20 | 21 | minikube service postgres-svc -------------------------------------------------------------------------------- /recorded/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "window.zoomLevel": 3 3 | } -------------------------------------------------------------------------------- /recorded/kubeconfig/api-deployment.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "apps/v1", 3 | "kind": "Deployment", 4 | "metadata": { 5 | "name": "api-heroes", 6 | "labels": { 7 | "app": "api-heroes" 8 | } 9 | }, 10 | "spec": { 11 | "replicas": 4, 12 | "selector": { 13 | "matchLabels": { 14 | "app": "api-heroes" 15 | } 16 | }, 17 | "template": { 18 | "metadata": { 19 | "labels": { 20 | "app": "api-heroes" 21 | } 22 | }, 23 | "spec": { 24 | "containers": [ 25 | { 26 | "name": "api-heroes", 27 | "image": "erickwendel/nodejs-with-postgres-api-example", 28 | "ports": [{ 29 | "containerPort": 4000 30 | }], 31 | "env": [ 32 | { 33 | "name": "POSTGRES_HOST", 34 | "value": "postgres:mysecretpassword@postgres-svc" 35 | }, 36 | { 37 | "name": "POSTGRES_DB", 38 | "value": "heroes" 39 | }, 40 | 41 | { 42 | "name": "PORT", 43 | "value": "4000" 44 | } 45 | 46 | ] 47 | } 48 | ] 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /recorded/kubeconfig/api-svc.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Service", 3 | "apiVersion": "v1" , 4 | "metadata": { 5 | "name": "api-heroes-svc", 6 | "labels": { 7 | "version": "v1", 8 | "app": "api-heroes" 9 | } 10 | }, 11 | "spec": { 12 | "selector": { 13 | "app": "api-heroes" 14 | }, 15 | "type": "LoadBalancer", 16 | "ports": [{ 17 | "protocol": "TCP", 18 | "port": 4000, 19 | "targetPort": 4000 20 | }] 21 | } 22 | } -------------------------------------------------------------------------------- /recorded/kubeconfig/postgres-sts.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "apps/v1", 3 | "kind": "StatefulSet", 4 | "metadata": { 5 | "name": "postgres", 6 | "labels": { 7 | "app": "postgres" 8 | } 9 | }, 10 | "spec": { 11 | "serviceName": "postgres-svc", 12 | "replicas": 1, 13 | "selector": { 14 | "matchLabels": { 15 | "app": "postgres" 16 | } 17 | }, 18 | "volumeClaimTemplates": [ 19 | { 20 | "metadata": { 21 | "name": "db-storage" 22 | }, 23 | "spec": { 24 | "storageClassName": "standard", 25 | "accessModes": [ "ReadWriteOnce"], 26 | "resources": { 27 | "requests": { 28 | "storage": "1Gi" 29 | } 30 | } 31 | } 32 | } 33 | ], 34 | "template": { 35 | "metadata": { 36 | "labels": { 37 | "app": "postgres" 38 | } 39 | }, 40 | "spec": { 41 | "containers": [ 42 | { 43 | "name": "postgres", 44 | "image": "postgres:latest", 45 | "env": [ 46 | { 47 | "name": "POSTGRES_PASSWORD", 48 | "value": "mysecretpassword" 49 | }, 50 | { 51 | "name": "POSTGRES_DB", 52 | "value": "heroes" 53 | } 54 | ], 55 | "ports": [ 56 | { 57 | "containerPort": 5432, 58 | "name": "postgres" 59 | } 60 | ], 61 | "volumeMounts": [ 62 | { 63 | "mountPath": "/var/lib/postgresql/data", 64 | "name": "db-storage" 65 | } 66 | ] 67 | } 68 | ] 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /recorded/kubeconfig/postgres-svc.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Service", 3 | "apiVersion": "v1" , 4 | "metadata": { 5 | "name": "postgres-svc", 6 | "labels": { 7 | "version": "v1", 8 | "app": "postgres" 9 | } 10 | }, 11 | "spec": { 12 | "selector": { 13 | "app": "postgres" 14 | }, 15 | "type": "ClusterIP", 16 | "ports": [{ 17 | "protocol": "TCP", 18 | "port": 5432, 19 | "targetPort": 5432 20 | }] 21 | } 22 | } -------------------------------------------------------------------------------- /recorded/nodejs-with-postgres-api-example/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /recorded/nodejs-with-postgres-api-example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /recorded/nodejs-with-postgres-api-example/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10-alpine 2 | 3 | RUN mkdir -p /src 4 | 5 | COPY package.json src/package.json 6 | 7 | WORKDIR /src 8 | 9 | RUN npm install --only=production --silent 10 | 11 | COPY . /src 12 | 13 | CMD npm start -------------------------------------------------------------------------------- /recorded/nodejs-with-postgres-api-example/README.md: -------------------------------------------------------------------------------- 1 | ## Node.js with Postgres Example 2 | 3 | Swagger Page of that application 7 | 8 | ### Requirements 9 | 10 | * Node.js v8+ or Docker and Docker Compose 11 | * Postgres running on local instance or Docker 12 | 13 | ### Running on localMachine 14 | 15 | * Install dependencies - `npm i` 16 | * Run project - `npm start` 17 | 18 | ### OR: Docker 19 | 20 | * `docker-compose up` 21 | 22 | ### OR: Alternatives on pulling from Docker hub 23 | 24 | * Docker hub image: [erickwendel/nodejs-with-postgres-api-example](https://hub.docker.com/r/erickwendel/nodejs-with-postgres-api-example/) 25 | 26 | ```shell 27 | docker run -d -p 5432:5432 --name postgres \ 28 | --env POSTGRES_PASSWORD=mysecretpassword \ 29 | --env POSTGRES_DB=heroes\ 30 | postgres 31 | ``` 32 | 33 | ```shell 34 | docker run -p 3000:3000 \ 35 | --link postgres:postgres \ 36 | -e POSTGRES_HOST=postgres:mysecretpassword@postgres:5432 \ 37 | -e POSTGRES_DB=heroes \ 38 | -e POSTGRES_SSL=false \ 39 | erickwendel/nodejs-with-postgres-api-example:latest 40 | ``` 41 | 42 | ### Viewing 43 | 44 | * Go to swagger page - `localhost:3000/documentation` 45 | -------------------------------------------------------------------------------- /recorded/nodejs-with-postgres-api-example/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | api-heroes-postgres: 4 | container_name: api-heroes-postgres 5 | build: . 6 | ports: 7 | - 3000:3000 8 | environment: 9 | POSTGRES_HOST: postgres:mysecretpassword@postgres:5432 10 | PORT: 3000 11 | 12 | depends_on: 13 | - postgres 14 | links: 15 | - postgres 16 | 17 | postgres: 18 | container_name: postgres 19 | restart: always 20 | image: postgres 21 | ports: 22 | - 5432:5432 23 | environment: 24 | POSTGRES_PASSWORD: mysecretpassword 25 | POSTGRES_DB: heroes -------------------------------------------------------------------------------- /recorded/nodejs-with-postgres-api-example/index.js: -------------------------------------------------------------------------------- 1 | const Joi = require('joi') 2 | const Sequelize = require('sequelize') 3 | const Hapi = require('hapi'); 4 | const Inert = require("inert"); 5 | const Vision = require("vision"); 6 | const HapiSwagger = require("hapi-swagger"); 7 | const port = process.env.PORT || 3000; 8 | const server = new Hapi.Server( 9 | { 10 | port 11 | } 12 | ); 13 | 14 | const failAction = async (request, h, err) => { 15 | console.error('err', err) 16 | throw err; 17 | } 18 | 19 | (async () => { 20 | if (!process.env.POSTGRES_HOST) { 21 | throw Error( 22 | "process.env.POSTGRES_HOST must be a: user:pass@ipService:port ", 23 | ); 24 | } 25 | const sequelize = new Sequelize( 26 | `postgres://${process.env.POSTGRES_HOST}/${process.env.POSTGRES_DB || "heroes"}`, 27 | { 28 | ssl: process.env.POSTGRES_SSL, 29 | dialectOptions: { 30 | ssl: process.env.POSTGRES_SSL, 31 | }, 32 | } 33 | ); 34 | await sequelize.authenticate(); 35 | console.log("postgres is running"); 36 | 37 | const Hero = sequelize.define("hero", { 38 | name: Sequelize.STRING, 39 | power: Sequelize.STRING, 40 | }); 41 | 42 | await Hero.sync({ force: true }); 43 | 44 | await server.register([ 45 | Inert, 46 | Vision, 47 | { 48 | plugin: HapiSwagger, 49 | options: { 50 | info: { 51 | title: "Node.js with Postgres Example - Erick Wendel", 52 | version: "1.0", 53 | }, 54 | } 55 | }, 56 | ]); 57 | 58 | server.route([ 59 | { 60 | method: "GET", 61 | path: "/heroes", 62 | handler: () => { 63 | return Hero.findAll(); 64 | }, 65 | config: { 66 | description: "List All heroes", 67 | notes: "heroes from database", 68 | tags: ["api"], 69 | }, 70 | }, 71 | { 72 | method: "GET", 73 | path: "/heroes/{id}", 74 | handler: (req) => { 75 | return Hero.findAll({ where: { id: req.params.id } }); 76 | }, 77 | config: { 78 | description: "Get a hero", 79 | notes: "heroes from database", 80 | tags: ["api"], 81 | }, 82 | }, 83 | { 84 | method: "POST", 85 | path: "/heroes", 86 | config: { 87 | handler: (req) => { 88 | const { payload } = req; 89 | return Hero.create(payload); 90 | }, 91 | description: "Create a hero", 92 | notes: "create a hero", 93 | tags: ["api"], 94 | validate: { 95 | failAction, 96 | 97 | payload: { 98 | name: Joi.string().required(), 99 | power: Joi.string().required(), 100 | }, 101 | }, 102 | }, 103 | }, 104 | { 105 | method: "PUT", 106 | path: "/heroes/{id}", 107 | config: { 108 | handler: (req) => { 109 | const { payload } = req; 110 | return Hero.update(payload, { where: { id: req.params.id } }); 111 | }, 112 | description: "Create a hero", 113 | notes: "create a hero", 114 | tags: ["api"], 115 | validate: { 116 | failAction, 117 | params: { 118 | id: Joi.string().required(), 119 | }, 120 | payload: { 121 | name: Joi.string(), 122 | power: Joi.string(), 123 | }, 124 | }, 125 | }, 126 | }, 127 | 128 | { 129 | method: "DELETE", 130 | path: "/heroes/{id}", 131 | config: { 132 | handler: (req) => { 133 | return Hero.destroy({ where: { id: req.params.id } }); 134 | }, 135 | description: "Delete a hero", 136 | notes: "Delete a hero", 137 | tags: ["api"], 138 | validate: { 139 | failAction, 140 | params: { 141 | id: Joi.string().required(), 142 | }, 143 | }, 144 | }, 145 | }, 146 | ]); 147 | 148 | await server.start(); 149 | console.log("server running at", server.info.port); 150 | })(); 151 | -------------------------------------------------------------------------------- /recorded/nodejs-with-postgres-api-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docker-registry", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "npx pm2-docker index.js", 8 | "testAll": "sh run.sh" 9 | }, 10 | "keywords": [], 11 | "author": "erickwendel", 12 | "license": "ISC", 13 | "dependencies": { 14 | "hapi": "18.1.0", 15 | "hapi-swagger": "9.4.2", 16 | "inert": "5.1.3", 17 | "joi": "14.3.1", 18 | "pg": "7.10.0", 19 | "pg-hstore": "2.3.2", 20 | "pm2": "3.5.0", 21 | "sequelize": "5.6.1", 22 | "vision": "5.4.4" 23 | }, 24 | "devDependencies": {} 25 | } 26 | -------------------------------------------------------------------------------- /recorded/nodejs-with-postgres-api-example/run.sh: -------------------------------------------------------------------------------- 1 | HOST=localhost:3000 2 | HOST=http://192.168.64.6:31505 3 | 4 | echo '\n\n creating Chapolin' 5 | CREATE=$( 6 | curl --silent -X POST \ 7 | --header "Content-Type: application/json" \ 8 | --data-binary '{"name":"Chapolin","power":"Strength"}' \ 9 | $HOST/heroes 10 | ) 11 | 12 | echo $CREATE | jq 13 | 14 | ID=$(echo $CREATE | jq .id) 15 | 16 | echo "\n\n requesting chapolin $ID" 17 | curl --silent $HOST/heroes/$ID | jq 18 | 19 | echo '\n\n requesting all heroes' 20 | curl --silent $HOST/heroes | jq 21 | 22 | echo "\n\n updating chapolin $ID" 23 | curl --silent -X PUT \ 24 | --header "Content-Type: application/json" \ 25 | --data-binary '{"name":"Batman","power":"Rich"}' \ 26 | $HOST/heroes/$ID \ 27 | | jq 28 | 29 | echo "\n\n requesting id: $ID" 30 | curl --silent $HOST/heroes/$ID | jq 31 | 32 | echo "\n\n removing id: $ID" 33 | curl --silent -X DELETE \ 34 | --header "Content-Type: application/json" \ 35 | $HOST/heroes/$ID \ 36 | | jq 37 | 38 | echo '\n\n requesting all heroes' 39 | curl --silent $HOST/heroes | jq 40 | -------------------------------------------------------------------------------- /recorded/scripts.sh: -------------------------------------------------------------------------------- 1 | docker login 2 | 3 | docker build -t app \ 4 | nodejs-with-postgres-api-example 5 | 6 | docker image ls | grep postgres 7 | 8 | # cria um apelido para a imagem, com o usuario do dockerhub/repositorio 9 | docker tag app erickwendel/nodejs-with-postgres-api-example 10 | # sobe para o dockerhub 11 | docker push erickwendel/nodejs-with-postgres-api-example 12 | 13 | # ---- 14 | minikube start 15 | minikube dashboard 16 | 17 | kubectl get nodes 18 | kubectl describe nodes 19 | 20 | kubectl create -f postgres-sts.json 21 | 22 | kubectl get statefulset 23 | kubectl get pod 24 | kubectl logs postgres-0 25 | 26 | kubectl describe sts postgres 27 | kubectl describe pod postgres-0 28 | 29 | kubectl get svc 30 | kubectl describe service postgres-svc 31 | 32 | kubectl get deploy 33 | kubectl describe deploy api-heroes 34 | kubectl get pod 35 | kubectl describe pod api-heroes-5d96dd4c87-wxvhf 36 | kubectl logs api-heroes-5d96dd4c87-wxvhf 37 | kubectl logs -f api-heroes-5d96dd4c87-wxvhf 38 | 39 | kubectl apply -f api-deployment.json 40 | 41 | minikube service api-heroes-svc --url 42 | 43 | kubectl delete -f . 44 | kubectl create -f . 45 | 46 | minikube delete --------------------------------------------------------------------------------