AWS/azure (ubuntu) + Docker + Nodejs + Loadbalancer

Posted on Actualizado enn

  • Installing Docker in Ubuntu
    • In ec2(aws)/virtualmachine(azure) create a ubuntu server
    • Login to console using bitvise (ubuntu/publickey/global3[yourkey]), in Azure you can use a password too.
    • $ sudo apt-get update # Fetches the list of available updates
      $ sudo apt-get upgrade # Strictly upgrades the current packages
      $ sudo apt-get dist-upgrade # Installs updates (new ones)
    • $ sudo curl -fsSL https://get.docker.com/ | sh
    • $ sudo docker version
      • optional: down a hello image and run (copy to local)
      • $ sudo docker run hello-world
    • list image / containers
    • $ sudo docker images  / sudo docker ps -a
    • Create the image to upload to docker hub
  • NodeJS – server.js
var express=require('express')
var PORT=8080;
var app = express();
app.get('/', function(req,res){
	res.send('hi mother');
});
app.listen(PORT);
console.log('running on local '+PORT);
  • NodeJS – Package.json to configure needs
{
  "name": "hello",
  "version": "1.0.0",
  "main": "server.js",
  "author": "hemc",
  "description": "",
  "dependencies": {
    "express": "^4.15.2"
  }
}
  • Dockerfile (without extensión)
FROM node:6.9.4
EXPOSE 8080
WORKDIR /app
RUN npm install nodemon -g
COPY package.json /app/package.json
RUN npm install
COPY server.js /app
CMD ["nodejs", "/app/server.js"]
    all 3 in same folder, for example
  • Then we build the container image with a user to upload to dockerhub, local image name:
  • ~/nodeHello$ sudo docker build -t minode/test4 .  (point at the end)
  • Upload to docker hub
    • $sudo docker run -it minode/test4
      • new console
    • $sudo docker ps -a
      • containerid my user on dockerhub web image name
    • $sudo docker commit e1078f8d0cfb minode/onlinetest4
    • $sudo docker run -it minode/onlinetest4
      • uploading
    • $sudo docker login –username=minode
      • +password
    • $sudo docker push minode/onlinetest4

=============docker aws===============

  • Create cluser
    • t2 micro / instances 2 / key pairs (your keys) / port range 8080
  • Create task
    • default values
    • create container
      • default + minode/test4
  • Create service (back to cluster first tab)
    • numtask=4
  • Review EC2 / instances, verify inbound rules are port 8080 open
  • Verify ip:8080 of two instance
  • Loadbalancer
    • select vpc with access to zone where the instances are placed, security group with port 8080 open a follow loadbalancer classic tutorial
  • Delete cluster
    • Delete cluster in main page
    • Go inside task two times and desregister task
    • Delete load balancer and verify instances are deleted
  • To delete images
    • $ sudo docker rmi

Part 1


Part 2


Part 3


Part 4

(by the way, mute the videos, I was listening spain radio)

Reference

http://www.ybrikman.com/writing/2015/11/11/running-docker-aws-ground-up/

https://aws.amazon.com/es/getting-started/tutorials/deploy-docker-containers/

https://nodejs.org/en/docs/guides/nodejs-docker-webapp/

https://community.risingstack.com/deploying-node-js-microservices-to-aws-using-docker/

 

You can login into container with:

docker exec -it bash
and run:

apt-get update
apt-get install nano

Docker images are delivered trimmed to bare minimum – so no editor is installed with the shipped container. That’s why there’s a need to install it manually.

To show only running containers use:
docker ps
To show all containers use:
docker ps -a

Anuncios

docker nodejs

Posted on Actualizado enn

/////running nodejs like service////

sudo npm install forever -g
sudo ln -s "$(which nodejs)" /usr/local/bin/node

forever start server.js

forever stop server.js

http://stackoverflow.com/questions/12701259/how-to-make-a-node-js-application-run-permanently

http://stackoverflow.com/questions/4018154/node-js-as-a-background-service

http://stackoverflow.com/questions/30281057/node-forever-usr-bin-env-node-no-such-file-or-directory

http://www.slidequest.com/q/70ang

//////

graph android http://stackoverflow.com/questions/9741300/charts-for-android

http://mayankj00.blogspot.mx/2014/01/using-holograph-library-for-your.html

https://bitbucket.org/danielnadeau/holographlibrary/src/0b41d14f5724c8df3bdd2d64fa039dc531230d33/HoloGraphLibrarySample/res/values/dimens.xml?at=master&fileviewer=file-view-default

https://github.com/EddieRingle/HoloGraphLibrary/blob/master/sample/src/main/java/com/echo/holographlibrarysample/BarFragment.java

///

  • install docker
  • verify installation
    • $ sudo docker version
  • First container
    • $ sudo docker run hello-world
  • list containers
    • $ sudo docker ps -a
    • [containderid / ports / image / name / command / created / status]
  • Docker hub
  • Dockerfile
    • FROM node:6.9.4
      EXPOSE 8080
      WORKDIR /app
      RUN npm install nodemon -g
      COPY package.json /app/package.json
      RUN npm install
      COPY server.js /app
      CMD [“nodejs”, “/app/server.js”]
      #sudo docker build -t minode/node-web-app .
    • minode is your username in hub.docker.com
    • $ cd <your project directory>
      $ sudo docker build -t minode/node-web-app .
      #          ^    ^                     ^
      #        build  w/ tag            this directory
      
      # ... lots of output
  • Docker images
    • $ sudo docker images
    • $ sudo docker run -p 3000:8080 -d minode/node-web-app
    • [$ sudo docker run -it –rm –name myrunningapp minode/node-web-app 3000:8080]–rm remove container when exist
    • $ sudo docker ps
$ docker run -p 4500:4500 minode/node-web-app
#               ^^^^^^^^^
#          bind the exposed container port to host port (on the virtual machine)
  • Docker stop / start
    • $ sudo docker stop <CONTAINER ID>
    • $ sudo docker start <DOCKER NAME> –you can see that with sudo docker ps
  • deleting container, drop all info
    • $ sudo docker rm <drupal1>
  • publish
    • $sudo docker build -t “your_user_name/myapp” .
    • $ docker push <your_user_name/myapp>  / minode/node-web-app

 

 

sudo docke

 

/////////

$sudo docker run –name mynode -t -i node

Easy and simple hello world nodejs / express + pug

Posted on Actualizado enn

hello nodejs

file: server.js
var express=require('express')
var PORT=8080;

var app = express();
app.get('/', function(req,res){
res.send('hi mother');
});

app.listen(PORT);
console.log('running on local '+PORT);

//////////////////////////////////////////////

file: package.json

{
"name": "hello",
"version": "1.0.0",
"main": "server.js",

"author": "hemc",
"description": "desc",
"dependencies": {
}
}

/////////////////////////////////////////////
$npm install express
////////////////////////////////////////////
nodejs server.js
////////////////////////////////////////////
that’s it

open localhost:8080 or your ip:8080

//////////////////setting pug////////////////

package.json

{
"name": "restful-auth",
"main": "server.js",
"dependencies": {
"body-parser": "^1.9.3",
"express": "^4.9.8",
"jsonwebtoken": "^7.3.0",
"jwt-simple": "^0.3.1",
"mongoose": "^4.2.10",
"morgan": "^1.5.3",
"passport": "^0.3.0",
"passport-jwt": "^1.2.1",
"request": "^2.81.0",
"pug": "^2.0.0-beta.12",
"yelp": "^1.0.2"
}
}

server.js

var express 	= require('express');
var app         = express();
var port = process.env.PORT || 8080; // used to create, sign, and verify tokens
//
app.set('view engine','pug');

app.get('/signin',function(req,res){
res.render('template',{title:"Registro",message:"Página ejemplo de registro",id:"signin"});
});
app.get('/recoverypass',function(req,res){
res.render('template',{title:"Recupera contraseña",message:"Página ejemplo de recuperación contraseña",id:"recoverypass"});
});
//
app.listen(port);
console.log('Magic happens at http://localhost:' + port);

//views/template.pug

doctype html
html(lang="es")
  head
    title= Bienvenido
  body
    h1= message
    div
        ul
            li Por favor realice los pasos indicados
    label(for="ourname") Usuario
    br
    br
    input(name="ourname",type="text",id="ourid",placeholder="Usuario")
    br
    br
    if(id=="signin")
        label(for="ourname") Contraseña
        br
        br
        input(name="ourname2",type="password",id="ourname2",placeholder="Contraseña")
        br
        br
    input(value="Enviar",type="submit",id="submit")

complete

aws iot

Posted on Actualizado enn

1.[on the left] registry / things / [TempSensorThing]

A thing Amazon Resource Name uniquely identifies this thing.

arn:aws:iot:us-west-2:9xxxx810:thing/TempSensor

2.Interact

This thing already appears to be connected.[click on] connect a device, in this case we are going to select linux and nodejs

Next, get started, and download the connection kit, that will give you the private key and the certificate (TempSensor.public.key / TempSensor.private.key / TempSensor.cert.pem)

3.Rule

Add a rule [AddLectureThing]

SELECT sensorID, temperatura FROM ‘MyTopic’, these fields match the dynamodb fields on the last example [sensorID,temparatura], MyTopic will be used in the JS

device.publish(‘MyTopic’, JSON.stringify({sensorID: ”+Math.random(), temperatura: ”+Math.random()}));

Finally add the lambda function with previous lambda function created, in this case RegisterLecture

Captura

Now creating a Rule that send an email when temperature is bigger than X, in this case 45

First create another Rule as follow

Captura

in configuration action /  create new resource

Create new topic

CapturaCaptura1

validate by email

Captura

Captura

var iot = require('aws-iot-device-sdk');
var __dirname="certs";

var device = iot.device({
    keyPath: __dirname + '/TempSensorThing.private.key',
    certPath: __dirname + '/TempSensorThing.cert.pem',
    caPath: __dirname + '/root-CA.crt',
    clientID: 'Prueba',
    region: 'us-west-2'
});

/*
device
  .on('connect', function() {
    console.log('connect');
    device.subscribe('TempSensorThing');
    device.publish('TempSensorThing', JSON.stringify({sensorID: '004', temperatura: '70'}));
    console.log('connectsuccess');
  });

device
  .on('message', function(topic, payload) {
    console.log('message', topic, payload.toString());
  });
*/

device.on('connect', function() {
    console.log('connect');
    device.subscribe('testIN',function(error,result){
        console.log(result);
    })
});

device.on('close', function() {
    console.log('close');
});

device.on('reconnect', function() {
    console.log('reconnect');
});

device.on('offline', function() {
    console.log('offline');
});

device.on('message',function(topic,payload) {
    console.log('message',topic,payload.toString());
});

/*
var myVar = setInterval(myTimer, 5*1000);//cada 5 seg para prueba
//var myVar = setInterval(myTimer, 5*1000*60);//cada 5 min para prod

function myTimer() {
    var d = new Date();
    console.log('Enviando info '+d.toLocaleTimeString());
    var max=10000;var min=1;
    device.publish('MyTopic', JSON.stringify({sensorID: ''+Math.floor(Math.random() * (max - min + 1)) + min, temperatura: ''+Math.random() * (50 - 0) + 0}));
}
setInterval(callbackFunction(), interval);
*/

setInterval(function(){
    var d = new Date();
    var max=10000;var min=1;
    var temp=Math.random() * (50 - 0) + 0;
    //device.publish('MyTopic', JSON.stringify({sensorID: ''+Math.floor(Math.random() * (max - min + 1)) + min, temperatura: ''+temp}));
    device.publish('MyTopicEmail', JSON.stringify({sensorID: ''+Math.floor(Math.random() * (max - min + 1)) + min, temperatura: ''+temp}));
    console.log('Enviando info '+temp+' / '+d.toLocaleTimeString());
}, 5*1000);

 

{
    "name": "IoTNodeJS",
    "version": "1.0.0",
    "keywords": ["util", "functional", "server", "client", "browser"],
    "author": "Hugo de la Mora",
    "contributors": [],
    "dependencies": {
        "aws-iot-device-sdk": "*"
    }
}

aws lambda microservice, serverless

Posted on Actualizado enn

lambda allows us to execute  C#, NodeJS, Java8 o Python 2.7, without configure a server or virtual machine.

We are going to create a java class to be executed inside Lambda and we are going to insert a row in dynamodb.

Create a table in dynamodb, BitacoraLectura, primary key SensorID (string).

We create our jar to insert sensorid and temperature, we need to add the lib folder to our jar, then we need to upload it to S3

The lambda function has to be created as follow:

Blueprint: Blank Function
Triggers: none
Name: RegisterLecture
Description: RegisterLecture
RunTime: Java 8
Code entry type: Amazon S3
S3 Link: the ones that correspond
Handler: the ones that correspond package.class
Role: Create a new role from template(s)
Role Name: LambdaAddLecture
Policy templates: empty

Go to roles to modify the one created / services, iam, roles section, select “AmazonDynamoDBFullAccess”

Then click on the test button and send a json like this
{
“sensorId”: “temp001”,
“temp”: “28.30”
}

package lambdaaws;

import com.amazonaws.regions.Regions;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.HashMap;
import java.util.Map;

public class LambdaAWS implements RequestHandler<RequestClass, String> {

    @Override
    public String handleRequest(RequestClass i, Context cntxt) {
        cntxt.getLogger().log(("Entrada: "+i.sensorID+" "+ i.temperatura + "\n"));

        AmazonDynamoDB db = AmazonDynamoDBClientBuilder.standard().withRegion(Regions.US_WEST_2).build();
        String tableName = "BitacoraLectura";
        Map<String, AttributeValue> item = new HashMap<>();
        item.put("sensorID", new AttributeValue(i.sensorID));
        item.put("temperatura", new AttributeValue(i.temperatura));
        db.putItem(tableName, item);
        return "Agregado: "+i.sensorID+" "+i.temperatura;

    }
}

 

package lambdaaws;

public class RequestClass {
    String sensorID;
    String temperatura;

    public RequestClass() {
    }

    public String getSensorID() {
        return sensorID;
    }

    public void setSensorID(String sensorID) {
        this.sensorID = sensorID;
    }

    public String getTemperatura() {
        return temperatura;
    }

    public void setTemperatura(String temperatura) {
        this.temperatura = temperatura;
    }

}

Captura

aws api gateway

Posted on Actualizado enn

    1. Go to services and select api gateway under aplication services
    2. Create api, new api: Lectures, create
    3. Actions create resource: TempSensor, create resource
    4. Actions create method: post, then we integrate with a lambda function (see another post to create lambda function).
    5. You will get something like:
      You are about to give API Gateway permission to invoke your Lambda function:
      arn:aws:lambda:us-west-2:971111:function:RegisterLecture
    6. Click the test button (ligthening)
    7. in Request body, put the post in this case
    8. {
      “sensorID”: “temp001”,
      “temperatura”: “28.30”
      }

Request:/tempsensor Status: 200

Latency: 161 ms

Response Body

Agregado: temp001 28.30

9.Actions, deploy api, pick up [new], stagename:betahm, stage desc: blank, deployment desc: blank
10. After that we can use postman or RESTconsole to test Invoke URL, clicking the post/get method in left panel: https://aqxxxxkm6.execute-api.us-west-2.amazonaws.com/betahm/tempsensor

In case anyone else lands here with the same problem, here is what was going on: at the end of the tutorial, I clicked “Deploy API” in order to deploy the test call I had set up. This takes you to the “Stage Editor” for the given API stage. At the top of the editor page is an “Invoke URL”, which does not include the resource at the end of it. Clicking on the Invoke URL link brings up an authentication error response.

On the Stage Editor page, there is a left nav with the stage name. If you expand this you get a forward-slash; if you expand this, you get your resource. If you expand your resource you get your method, and if you click on the method you get an “Invoke URL” link (which is the same as the above but with the resource appended). This invoke URL link works, invoking the GET method and returning results.

Somewhat hidden, in my opinion, but once you know where to look for it it all makes sense.