Monday, December 31, 2018

mocha test hapi rest api oop javascript

1. At first, Verify the status of our code, or clone it.

educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ hg status

2. This is our package.json


educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ cat package.json 
{
  "name": "rest_echo_hapi",
  "version": "1.0.0",
  "description": "This README would normally document whatever steps are necessary to get your application up and running.",
  "main": "server/index.js",
  "scripts": {
    "start": "node server/index.js",
    "test": "mocha --recursive ./test/**.js"
  },
  "keywords": [],
  "author": "maximilianou@gmail.com",
  "license": "MIT",
  "dependencies": {
    "hapi": "^17.8.1",
    "isemail": "^3.2.0",
    "mocha": "^5.2.0",
    "node-fetch": "^2.3.0"
  }
}

3. I'll try to run the test program, widthout the libraries installed

educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ npm test

> rest_echo_hapi@1.0.0 test /home/educacion/src/resthapi/v3/rest_echo_hapi
> mocha --recursive ./test/**.js

sh: 1: mocha: not found
npm ERR! Test failed.  See above for more details.

4. Now i'm installing manualy, with npm, mocha the test suite, and node-fetch to have most standard fetch library updated. I'm sure this fetch is going to be part of our nodejs api. Standards are the most important thing a developer must be confident with.

educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ npm install mocha node-fetch


5. And, now, we are running the test, and the OK result, baby steps, it's really the minimal code size.

educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ npm test
> rest_echo_hapi@1.0.0 test /home/educacion/src/resthapi/v3/rest_echo_hapi
> mocha --recursive ./test/**.js
  routes :: server
    method http GET /
      ✓ should return text (43ms)
    method http POST /
      ✓ should return text
    metodo http PUT /
      ✓ should return text
    metodo http DELETE /
      ✓ should return text
  4 passing (67ms)

6. Here we have our test code, plain, one line assert focus, just to run our baby steps. Testing GET POST PUT DELETE minimal, hardcodeing configuration like 127.0.0.1 and others. But having a structure of describe() one scenario, describe() each case, it check one value item in each case. Here we have the assert.ok() and the RegExp() from the standard node api, following our Standard way of programming, having our code clean from temporal dependencies in libraries that will may change, but we expect some standards to be done. ( This kind of temporal dependencies problems happended to some project where i was working some time ago, when the browsers doesn't support JSON parse and stringify, so i start using, from our Master Programmer, our Master Key Programmer, Doublas Crockford, his version of the standard, so we don't have to worry about the future, because he does!, https://github.com/douglascrockford/JSON-js, some time later i don't have to change my older code, because his library was thought with the stantard in mind, so JSON.parse() JSON.stringify() was all done native in the browser one day, now. )

educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ cat test/server_index_test.js 
const assert = require('assert');
const fetch = require('node-fetch');
describe('routes :: server', () => {
  describe('method http GET /', () => {
    it('should return text', (done) => {
      const thevalue = "Mafalda";
      fetch( 'http://127.0.0.1:3002/'+thevalue
      ).then( res => res.text() 
      ).then(
        (body) => {
          assert.ok( new RegExp(thevalue+"$").test(
            JSON.parse(body)) , ":::Data Error!!!");
          done();
        }
      ).catch(done);
      });
    });      
  describe('method http POST /', () => {
    it('should return text', (done) => {
      const thevalue = "Larguirucho";
      fetch(
        'http://127.0.0.1:3002/msg', {
          method: 'POST',
          body:    JSON.stringify(thevalue),
          headers: { 'Content-Type': 'application/json' },
      }        
      ).then( res => res.text() 
      ).then(
        (body) => {
          assert.ok( new RegExp(thevalue+"$").test(
            JSON.parse(body)) , ":::Data Error!!!");
          done();
        }
      ).catch(done);
    });
  });
  describe('metodo http PUT /', () => {
    it('should return text', (done) => {
      const thevalue = "Profesor Neurus";
      fetch(
        'http://127.0.0.1:3002/msg', {
          method: 'PUT',
          body:    JSON.stringify(thevalue),
          headers: { 'Content-Type': 'application/json' },
      }        
      ).then( res => res.text() 
      ).then(
        (body) => {
          assert.ok( new RegExp(thevalue+"$").test(
            JSON.parse(body)) , ":::Data Error!!!");
          done();
        }
      ).catch(done);
    });
  });  
  describe('metodo http DELETE /', () => {
    it('should return text', (done) => {
      const thevalue = "Pedrito";
      fetch( 'http://127.0.0.1:3002/'+thevalue
      ).then( res => res.text() 
      ).then(
        (body) => {
          assert.ok( new RegExp(thevalue+"$").test(
            JSON.parse(body)) , ":::Data Error!!!");
          done();
        }
      ).catch(done);
    });
  });
});

7. Here we have our server REST API with JSON body request and JSON body response. Body or parameter depending on POST PUT, GET DELETE, in case.

educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ cat server/index.js 
const Hapi = require('hapi');
class EchoServerHapi{
    constructor(args){
        this.server = Hapi.server(args);
    }
    async init(){
        try {
          await this.routing();
          await this.server.start();
          console.log(`Here we have the echo Server Hapi running:: ${this.server.info.uri}`);
        } catch (error) {
          console.log('Error while trying to run echo Server Hapi:: ' + error.message);
        }
    }
    async routing(){
        this.server.route({
            method: 'GET',
            path: '/',
            handler: (request, h) => {
                return JSON.stringify('Hello, Javascript Developer');
            }
        });        
        this.server.route({
            method: 'GET',
            path: '/{name}',
            handler: (request, h) => {
                return JSON.stringify('Hello, ' + encodeURIComponent(request.params.name) );
            }
        });
        this.server.route({
            method: 'POST',
            path: '/msg',
            handler: (request, h) => {
                return JSON.stringify(request.payload);
            }
        });
        this.server.route({
            method: 'PUT',
            path: '/msg',
            handler: (request, h) => {
                return JSON.stringify(request.payload);
            }
        });
        this.server.route({
            method: 'DELETE',
            path: '/{name}',
            handler: (request, h) => {
                return JSON.stringify( 'Bye, ' + encodeURIComponent(request.params.name) );
            }
        });
    }
}
const firstEchoServer = new EchoServerHapi({
  port: 3002,
  host: '0.0.0.0',
  app: {}
});
firstEchoServer.init();

8. Our Dockerfile is just to have the posibility to change code when we are running our development environment API REST.

educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ cat Dockerfile 
FROM node
WORKDIR /code
RUN npm set prefix /usr/local && npm install -g nodemon
COPY package.json /code/package.json
RUN npm set prefix /usr/local && npm install && npm ls
RUN mv /code/node_modules /node_modules
COPY . /code
#EXPOSE 3000  # expose but no publish, except useing docker -P
CMD ["npm", "start"]

9. And, containers compose in docker-compose.yml, to have running the services

educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ cat docker-compose.yml 
version: "2"
services:
  web:
    build: .
    command: nodemon -L --inspect=0.0.0.0:5858
    volumes:
      - .:/code
    ports:
      - "3002:3002"
      - "5858:5858"

10. Once it's running OK, upload to the repository, to our bitbucket mercurial.

educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ hg commit -u maximilianou@gmail.com -m 'testing mocha, first steps '
educacion@educacion:~/src/resthapi/v3/rest_echo_hapi$ hg push


Wednesday, December 26, 2018

docker rest api hapijs nodejs vscode realtime development


1. The javascript echo parameter server hapi 

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ cat server/index.js 
const Hapi = require('hapi');
class EchoServerHapi{
    constructor(args){
        this.server = Hapi.server(args);
    }
    async init(){
        try {
          await this.routing();
          await this.server.start();
          console.log(`Here we have the echo Server Hapi running:: ${this.server.info.uri}`);
        } catch (error) {
          console.log('Error while trying to run echo Server Hapi:: ' + error.message);
        }
    }
    async routing(){
        this.server.route({
            method: 'GET',
            path: '/',
            handler: (request, h) => {
                return 'Hello, Javascript Developer! ! !\n';
            }
        });        
        this.server.route({
            method: 'GET',
            path: '/{name}',
            handler: (request, h) => {
                return 'Hello, ' + encodeURIComponent(request.params.name) + '!\n';
            }
        });
        this.server.route({
            method: 'POST',
            path: '/msg',
            handler: (request, h) => {
                return "POSTing:: "+JSON.stringify(request.payload) + '\n';
            }
        });
        this.server.route({
            method: 'PUT',
            path: '/msg',
            handler: (request, h) => {
                return "PUTing:: "+JSON.stringify(request.payload) + '\n';
            }
        });
        this.server.route({
            method: 'DELETE',
            path: '/{name}',
            handler: (request, h) => {
                return 'Bye, ' + encodeURIComponent(request.params.name) + '!\n';
            }
        });
    }
}
/* LOOK THIS COMMENT, NO localhost, just 0.0.0.0 */
/*const firstEchoServer = new EchoServerHapi({
    port: 3001,
    host: 'localhost',
    app: {}
  });*/
  const firstEchoServer = new EchoServerHapi({
    port: 3001,
    host: '0.0.0.0',
    app: {}
  });
firstEchoServer.init();

2. The node package.json done with npm

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ cat package.json 
{
  "name": "rest_echo_hapi",
  "version": "1.0.0",
  "description": "This README would normally document whatever steps are necessary to get your application up and running.",
  "main": "server/index.js",
  "scripts": {
    "start": "node server/index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "maximilianou@gmail.com",
  "license": "MIT",
  "dependencies": {
    "hapi": "^17.8.1",
    "isemail": "^3.2.0"
  }
}

3. The Dockerfile to run and modify the javascript program

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ cat Dockerfile 
FROM node
WORKDIR /code
RUN npm set prefix /usr/local && npm install -g nodemon
COPY package.json /code/package.json
RUN npm set prefix /usr/local && npm install && npm ls
RUN mv /code/node_modules /node_modules
COPY . /code
#EXPOSE 3000  # expose but no publish, except useing docker -P
CMD ["npm", "start"]

4. The docker compose to run the composition of service docker having volume shared path

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ cat docker-compose.yml 
version: "2"
services:
  web:
    build: .
    command: nodemon -L --inspect=0.0.0.0:5858
    volumes:
      - .:/code
    ports:
      - "3001:3001"
      - "5858:5858"

5. Starting from command line with npm, from package.json

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ npm start
> rest_echo_hapi@1.0.0 start /home/educacion/src/resthapi/v2/rest_echo_hapi
> node server/index.js
Here we have the echo Server Hapi running:: http://0.0.0.0:3001

6. Starting from docker compose

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ docker-compose up
Starting restechohapi_web_1
Attaching to restechohapi_web_1
web_1  | [nodemon] 1.18.7
web_1  | [nodemon] to restart at any time, enter `rs`
web_1  | [nodemon] watching: *.*
web_1  | [nodemon] starting `node --inspect=0.0.0.0:5858 server/index.js`
web_1  | Debugger listening on ws://0.0.0.0:5858/e6293311-3e2c-4f77-af38-d087a52d30c3
web_1  | For help, see: https://nodejs.org/en/docs/inspector
web_1  | Here we have the echo Server Hapi running:: http://0.0.0.0:3001

7. Checking GET, POST, PUT and DELETE echoing the parameter in each case.

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ curl http://0.0.0.0:3001
Hello, Javascript Developer! ! !
educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ curl http://127.0.0.1:3001
Hello, Javascript Developer! ! !
educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ curl http://localhost:3001
Hello, Javascript Developer! ! !

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ curl http://localhost:3001/Hijitus
Hello, Hijitus!

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ curl --request DELETE http://localhost:3001/Larguirucho
Bye, Larguirucho!

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ curl --header "Content-Type: application/json" --request POST --data '{"name":"Pucho"}' http://localhost:3001/msg
POSTing:: {"name":"Pucho"}

educacion@educacion:~/src/resthapi/v2/rest_echo_hapi$ curl --header "Content-Type: application/json" --request PUT --data '{"name":"Profesor Neurus"}' http://localhost:3001/msg
PUTing:: {"name":"Profesor Neurus"}




Friday, December 21, 2018

rest hapi echo


1. At first, we create the repository, i'm using bitbucket and mercurial

2. We clone the repository locally

educacion@educacion:~/src/resthapi$ hg clone https://bitbucket.org/maximilianou/rest_echo_hapi/

3. List this folder to see the files.

educacion@educacion:~/src/resthapi$ ls
rest_echo_hapi

4. Change Dir, inside the path where you will have the code.

educacion@educacion:~/src/resthapi$ cd rest_echo_hapi/

educacion@educacion:~/src/resthapi/rest_echo_hapi$ ls -a
.  ..  .hg  LICENSE.txt  README.md

5. Create the package.json

educacion@educacion:~/src/resthapi/rest_echo_hapi$ npm init -y

6. let see the repository files status sync

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg status
? package.json

7. Add new files

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg add .

8. Verify the locally status change.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg status
A package.json

9. Commit changes in the local repository.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg commit -m 'initial commit' -u maximilianou@gmail.com

10. Upload Changes to the remote repository ( origin master ) 

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg push

11. Let's install Hapijs

educacion@educacion:~/src/resthapi/rest_echo_hapi$ npm install hapi --save

12. Verify the changes in package.json

educacion@educacion:~/src/resthapi/rest_echo_hapi$ cat package.json 
{
  "name": "rest_echo_hapi",
  "version": "1.0.0",
  "description": "This README would normally document whatever steps are necessary to get your application up and running.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "hapi": "^17.8.1"
  }
}

13. Add to .hgignore what does'nt have to be sync to the central ( remote ) repository.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ vi .hgignore

14. Let's see the content of my hgignore now.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ cat .hgignore 
# Add any directories, files, or patterns you don't want to be tracked by version control
# Project #
# System #
.DS_Store
# Mercurial #
.orig
# Node #
node_modules/
# Grunt build #
dist/
# Bower #
bower_components/
public/system/lib
.bower-cache/
.bower-registry/
.bower-tmp/
.tmp/
# IDE #
nbproject/
.idea/
atlassian-ide-plugin.xml

15. Add configuration files for this instance of reposisory.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg add .
adding .hgignore
adding package-lock.json

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg status
M package.json
A .hgignore
A package-lock.json

16. Commit this repository sanity change.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg commit -m 'repository sanity' -u maximilianou@gmail.com

17. Upload to the central repository

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg push

18. Now, we can create a directory structure, just to beginning with the right foot, then walk.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ mkdir server

19. Create our first javascript server file, or program.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ touch server/index.js

20. Here we create the server in port 3000, localhost. Object Oriented Programming.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ cat server/index.js 
const Hapi = require('hapi');
class EchoServerHapi{
    constructor(args){
        this.server = Hapi.server(args);
    };
    async init(){
        try {
          await this.server.start();
          console.log(`Here we have the echo Server Hapi running:: ${this.server.info.uri}`);
        } catch (error) {
          console.log('Error while trying to run echo Server Hapi:: ' + error.message);
        }
      };      
};
const firstEchoServer = new EchoServerHapi({
    port: 3000,
    host: 'localhost',
    app: {}
  });
firstEchoServer.init();

21. It is running.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ node server/index.js 
Here we have the echo Server Hapi running:: http://localhost:3000

22. And.. the route is not specified.

educacion@educacion:~$ curl http://localhost:3000/
{"statusCode":404,"error":"Not Found","message":"Not Found"}

23. Adding some route. Simple way at first, just a method routing() in the class.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ cat server/index.js 
const Hapi = require('hapi');
class EchoServerHapi{
    constructor(args){
        this.server = Hapi.server(args);
    }
    async init(){
        try {
          await this.routing();
          await this.server.start();
          console.log(`Here we have the echo Server Hapi running:: ${this.server.info.uri}`);
        } catch (error) {
          console.log('Error while trying to run echo Server Hapi:: ' + error.message);
        }
    }
    async routing(){
        this.server.route({
            method: 'GET',
            path: '/',
            handler: (request, h) => {
                return 'Hello, Javascript Developer!\n';
            }
        });        
        this.server.route({
            method: 'GET',
            path: '/{name}',
            handler: (request, h) => {
                return 'Hello, ' + encodeURIComponent(request.params.name) + '!\n';
            }
        });
    }
}
const firstEchoServer = new EchoServerHapi({
    port: 3000,
    host: 'localhost',
    app: {}
  });
firstEchoServer.init();

24. running the server, from the command line.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ node server/index.js 
Here we have the echo Server Hapi running:: http://localhost:3000

25. Checking the path /

educacion@educacion:~/src/resthapi/rest_echo_hapi$ curl http://localhost:3000/
Hello, Javascript Developer!

26. Checking the path /Mafalda, just an Example Case!!

educacion@educacion:~/src/resthapi/rest_echo_hapi$ curl http://localhost:3000/Mafalda
Hello, Mafalda!

27. Upload changes to the central repository.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg status
M server/index.js
educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg commit -u maximilianou@gmail.com -m 'Hello URL routing()'
educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg status
educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg push

28. Now, adding GET, POST, PUT to our near rest echo.

const Hapi = require('hapi');
class EchoServerHapi{
    constructor(args){
        this.server = Hapi.server(args);
    }
    async init(){
        try {
          await this.routing();
          await this.server.start();
          console.log(`Here we have the echo Server Hapi running:: ${this.server.info.uri}`);
        } catch (error) {
          console.log('Error while trying to run echo Server Hapi:: ' + error.message);
        }
    }
    async routing(){
        this.server.route({
            method: 'GET',
            path: '/',
            handler: (request, h) => {
                return 'Hello, Javascript Developer!\n';
            }
        });        
        this.server.route({
            method: 'GET',
            path: '/{name}',
            handler: (request, h) => {
                return 'Hello, ' + encodeURIComponent(request.params.name) + '!\n';
            }
        });
        this.server.route({
            method: 'POST',
            path: '/msg',
            handler: (request, h) => {
                return "POSTing:: "+JSON.stringify(request.payload) + '\n';
            }
        });
        this.server.route({
            method: 'PUT',
            path: '/msg',
            handler: (request, h) => {
                return "PUTing:: "+JSON.stringify(request.payload) + '\n';
            }
        });
    }
}
const firstEchoServer = new EchoServerHapi({
    port: 3000,
    host: 'localhost',
    app: {}
  });
firstEchoServer.init();

29. Now, checking the post and put, with --data, body of http for POST and PUT, Reference: https://tools.ietf.org/html/rfc2616

educacion@educacion:~/src/resthapi/rest_echo_hapi$ curl --header "Content-Type: application/json" --request POST --data '{"clave":"valor"}' http://localhost:3000/msg
POSTing:: {"clave":"valor"}

educacion@educacion:~/src/resthapi/rest_echo_hapi$ curl --header "Content-Type: application/json" --request PUT --data '{"clave":"valor"}' http://localhost:3000/msg
PUTing:: {"clave":"valor"}

30. Commiting changes to the central repository.

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg status
M server/index.js

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg commit -u maximilianou@gmail.com -m 'post, put method echo'

educacion@educacion:~/src/resthapi/rest_echo_hapi$ hg push


31. Compliting echo rest, get, post, put, and DELETE here

const Hapi = require('hapi');
class EchoServerHapi{
    constructor(args){
        this.server = Hapi.server(args);
    }
    async init(){
        try {
          await this.routing();
          await this.server.start();
          console.log(`Here we have the echo Server Hapi running:: ${this.server.info.uri}`);
        } catch (error) {
          console.log('Error while trying to run echo Server Hapi:: ' + error.message);
        }
    }
    async routing(){
        this.server.route({
            method: 'GET',
            path: '/',
            handler: (request, h) => {
                return 'Hello, Javascript Developer!\n';
            }
        });        
        this.server.route({
            method: 'GET',
            path: '/{name}',
            handler: (request, h) => {
                return 'Hello, ' + encodeURIComponent(request.params.name) + '!\n';
            }
        });
        this.server.route({
            method: 'POST',
            path: '/msg',
            handler: (request, h) => {
                return "POSTing:: "+JSON.stringify(request.payload) + '\n';
            }
        });
        this.server.route({
            method: 'PUT',
            path: '/msg',
            handler: (request, h) => {
                return "PUTing:: "+JSON.stringify(request.payload) + '\n';
            }
        });
        this.server.route({
            method: 'DELETE',
            path: '/{name}',
            handler: (request, h) => {
                return 'Bye, ' + encodeURIComponent(request.params.name) + '!\n';
            }
        });
    }
}
const firstEchoServer = new EchoServerHapi({
    port: 3000,
    host: 'localhost',
    app: {}
  });
firstEchoServer.init();

32. Checking HTTP DELETE, data into the url, like http get.

educacion@educacion:~$ curl --request DELETE http://localhost:3000/Pedrito
Bye, Pedrito!



Monday, December 17, 2018

Docker 12 Factor Methodology Step 01 Codebase Repository git


$ git clone https://bitbucket.org/maximilianou/messageapp

educacion@educacion:~/src/docker12factor/messageapp$ git status

educacion@educacion:~/src/docker12factor/messageapp$ git add .

educacion@educacion:~/src/docker12factor/messageapp$ git commit -m 'first commit'

educacion@educacion:~/src/docker12factor/messageapp$ git push origin master



Docker 12 Factors Methodology Step 00 Application NodeJS Debian REST api



root@educacion:/home/educacion/src/docker12factor# apt install dirmngr

root@educacion:/home/educacion/src/docker12factor# apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4

root@educacion:/home/educacion/src/docker12factor# echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.0 main" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list

root@educacion:/home/educacion/src/docker12factor# apt update -y

root@educacion:/home/educacion/src/docker12factor# apt install -y mongodb-org

root@educacion:/home/educacion/src/docker12factor# service mongod status

root@educacion:/home/educacion/src/docker12factor# service mongod start

root@educacion:/home/educacion/src/docker12factor# mongo

> help;
> exit;

educacion@educacion:~/src/docker12factor$ npm init

educacion@educacion:~/src/docker12factor$ npm get prefix
/usr
educacion@educacion:~/src/docker12factor$ npm set prefix /usr/local
educacion@educacion:~/src/docker12factor$ npm get prefix 
/usr/local

educacion@educacion:~/src/docker12factor$ npm install sails -g

educacion@educacion:~/src/docker12factor$ sails new messageApp
 Choose a template for your new Sails app:
 1. Web App  ·  Extensible project with auth, login, & password recovery
 2. Empty    ·  An empty Sails app, yours to configure
 (type "?" for help, or  to cancel)
? 2

educacion@educacion:~/src/docker12factor$ cd messageApp

educacion@educacion:~/src/docker12factor$ sails generate api message

educacion@educacion:~/src/docker12factor$ sails lift


educacion@educacion:~/src/docker12factor/messageApp$ curl --header "Content-Type: application/json"   --request POST   --data '"text":"Hello Javascript FullStack DevOps"}'   http://localhost:1337/message

educacion@educacion:~/src/docker12factor/messageApp$ curl --header "Content-Type: application/json"   --request POST   --data '"text":"Hola Javascript FullStack DevOps"}'   http://localhost:1337/message

educacion@educacion:~/src/docker12factor/messageApp$ curl http://localhost:1337/message/
[
  {
    "text": "Hello Javascript FullStack DevOps",
    "createdAt": 1545061317524,
    "updatedAt": 1545061317524,
    "id": 1
  },
  {
    "text": "Hola Javascript FullStack DevOps",
    "createdAt": 1545061415586,
    "updatedAt": 1545061415586,
    "id": 2
  }
]


educacion@educacion:~/src/docker12factor/messageApp$ curl --header "Content-Type: application/json"   --request PUT  --data '{"ext":"Hello Javascript FullStack !! DevOps !!"}'   http://localhost:1337/message/2

educacion@educacion:~/src/docker12factor/messageApp$ curl http://localhost:1337/message/
[
  {
    "text": "Hello Javascript FullStack DevOps",
    "createdAt": 1545061317524,
    "updatedAt": 1545061317524,
    "id": 1
  },
  {
    "text": "Hello Javascript FullStack !! DevOps !!",
    "createdAt": 1545061415586,
    "updatedAt": 1545065865167,
    "id": 2
  }
]


educacion@educacion:~/src/docker12factor/messageApp$ curl   --request DELETE   http://localhost:1337/message/1

educacion@educacion:~/src/docker12factor/messageApp$ curl http://localhost:1337/message/
[
  {
    "text": "Hello Javascript FullStack !! DevOps !!",
    "createdAt": 1545061415586,
    "updatedAt": 1545065865167,
    "id": 2
  }
]


Reference: 
https://github.com/docker/labs/blob/master/12factor/00_application.md
https://docs.mongodb.com/manual/tutorial/install-mongodb-on-debian/

Tuesday, December 4, 2018

docker nodejs IDE visual studio 2018


educacion@educacion:~/src/docker02$ cat Dockerfile 
FROM node
WORKDIR /code
RUN npm install -g nodemon
COPY package.json /code/package.json
RUN npm install && npm ls
RUN mv /code/node_modules /node_modules
COPY . /code
CMD ["npm", "start"]


educacion@educacion:~/src/docker02$ cat  docker-compose.yml 
version: "2"
services:
  web:
    build: .
    command: nodemon -L --inspect=0.0.0.0:5858
    volumes:
      - .:/code
    ports:
      - "8000:8000"
      - "5858:5858"


educacion@educacion:~/src/docker02$ cat package.json 
{
    "main": "app.js",
    "dependencies": {
        "express": "~4.14.0",
        "express-handlebars": "~3.0.0"
    }
}


educacion@educacion:~/src/docker02$ cat app.js
const express = require('express');
const expressHandlebars = require('express-handlebars');
const http = require('http');
const PORT = 8000;
const LINES = [
    "One thing at the time.",
    "Start from the beginning!",
    "Up to date!",
    "As Simple As Possible",
];
let lineIndex = 0;
const app = express();
app.engine('html', expressHandlebars());
app.set('view engine', 'html');
app.set('views', __dirname);
app.get('/', (req, res) => {
    let message = LINES[lineIndex];
    lineIndex += 1;
    if (lineIndex >= LINES.length) {
        lineIndex = 0;
    }
    res.render('index', {message: message});
});
http.Server(app).listen(PORT, () => {
    console.log("HTTP server listening on port %s", PORT);
});



educacion@educacion:~/src/docker02$ cat index.html
< !doctype html>
< html>
    < head>
        < meta http-equiv="refresh" content="2">
        < style type="text/css">
            .sample_docker_nodejs {
                font-family: Helvetica, Arial, sans-serif;
                font-weight: 600;
                font-size: 56pt;
                text-transform: uppercase;
                text-align: center;
                background: #3c3;
                color: white;
            }
        < /style>
    < /head>
    < body class='sample_docker_nodejs'>“{{message}}”
< /html>


root@educacion:/home/educacion# apt install libgconf-2-4 desktop-file-utils 
mime-support gconf2-common gconf-service


educacion@educacion:~/src/docker02$ docker-compose up
Creating network "docker02_default" with the default driver
Building web
Step 1/8 : FROM node
 ---> e6825fa3bd20
Step 2/8 : WORKDIR /code
 ---> Running in 7f475c6a9926
Removing intermediate container 7f475c6a9926
 ---> 325c768f008c
Step 3/8 : RUN npm install -g nodemon
 ---> Running in 37c3e446896d
/usr/local/bin/nodemon -> /usr/local/lib/node_modules/nodemon/bin/nodemon.js

> nodemon@1.18.7 postinstall /usr/local/lib/node_modules/nodemon
> node bin/postinstall || exit 0

Love nodemon? You can now support the project via the open collective:
 > https://opencollective.com/nodemon/donate

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 
(node_modules/nodemon/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform 
for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} 
(current: {"os":"linux","arch":"x64"})

+ nodemon@1.18.7
added 223 packages from 130 contributors in 291.478s
Removing intermediate container 37c3e446896d
 ---> a7a86d38c2a1
Step 4/8 : COPY package.json /code/package.json
 ---> 80630e53397b
Step 5/8 : RUN npm install && npm ls
 ---> Running in c7347533b05c
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN code No description
npm WARN code No repository field.
npm WARN code No license field.

added 70 packages from 80 contributors in 474.487s
/code
+-- express@4.14.1
| +-- accepts@1.3.5
| | +-- mime-types@2.1.21
..........................

Removing intermediate container c7347533b05c
 ---> 5d15000e4998
Step 6/8 : RUN mv /code/node_modules /node_modules
 ---> Running in e7368c6b5409
Removing intermediate container e7368c6b5409
 ---> c80d1a0c6d8a
Step 7/8 : COPY . /code
 ---> 69f216de5856
Step 8/8 : CMD ["npm", "start"]
 ---> Running in 220eb2ed498c
Removing intermediate container 220eb2ed498c
 ---> 9ce32b100e72
Successfully built 9ce32b100e72
Successfully tagged docker02_web:latest
WARNING: Image for service web was built because it did not already exist. To rebuild this image 
you must use `docker-compose build` or `docker-compose up --build`.
Creating docker02_web_1
Attaching to docker02_web_1
web_1  | [nodemon] 1.18.7
web_1  | [nodemon] to restart at any time, enter `rs`
web_1  | [nodemon] watching: *.*
web_1  | [nodemon] starting `node --inspect=0.0.0.0:5858 app.js`
web_1  | Debugger listening on ws://0.0.0.0:5858/08100114-cd8e-4e44-be6f-855309ffa8b6
web_1  | For help, see: https://nodejs.org/en/docs/inspector
web_1  | HTTP server listening on port 8000


http://localhost:8000/

 * Edit with VSCode in realtime!


 * Connect with a container in runtime!

educacion@educacion:~/src/docker02$ docker exec -i -t docker02_web_1 /bin/bash

Reference:
https://github.com/elPoeta/docker-nodejs-postgres-example
https://github.com/docker/labs/blob/master/developer-tools/README.md
https://code.visualstudio.com/
https://github.com/docker/labs/blob/master/developer-tools/nodejs-debugging/VSCode-README.md


Thursday, November 29, 2018

docker install debian stretch 2018


root@educacion:~# apt update

root@educacion:~# apt install \
     apt-transport-https \
     ca-certificates \
     curl \
     gnupg2 \
     software-properties-common

root@educacion:~# curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -

root@educacion:~# apt-key fingerprint 0EBFCD88

root@educacion:~# add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"

root@educacion:~# apt update

root@educacion:~# apt upgrade

root@educacion:~# apt install docker-ce

root@educacion:~# docker run hello-world

-( root@educacion:~# apt install docker-compose ) # OLD release of docker-compose, we must install from git repo
-( root@educacion:~# apt remove docker-compose )

root@educacion:~# usermod -aG docker educacion

root@educacion:~# usermod -aG staff educacion

educacion@educacion:~$ curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

educacion@educacion:~$ chmod +x /usr/local/bin/docker-compose

educacion@educacion:~$ docker-compose --version


educacion@educacion:~$ docker run hello-world


root@educacion:/etc/docker# cat daemon.json 
{
"log-driver": "json-file",
"log-opts": {
    "max-size": "5m",    
    "max-file": "3"    
    }
} 


version: '3.2'
services:
  nginx:
    image: 'nginx:latest'
    ports:
      - '80:80'
    logging:
      driver: "json-file"
      options:
        max-size: "1m"
        max-file: "3"

Reference:
https://gist.github.com/elPoeta/2e0490f61b978da0379f26fec91695e5
https://www.docker.com/