Saturday, April 1, 2017

Configuring your own docker image for Meteor app deployment

This blog assumes a post 1.4 Meteor app, and its cloud deployment using the mup tool (Please see  this for npm download and find the code on https://github.com/zodern/meteor-up). Also see this for deployment on Digital Ocean using mup, although it is a bit dated. For example mup.json file has changed to mup.js and some of the json structure in there also differs.

The way that mup loosely works is that it compiles and tar-zips your application code, uploads it over to/opt/onlinetesting1/tmp on your cloud machine in addition to the docker run script to be run. On the cloud VM, the script (built by mup from mup.js) when run takes as an installation base, the docker image abernix/meteord (settable in mup.js) by pulling it from docker hub (e.g. download using 'docker pull abernix/meteord' command if you have docker installed on your machine, to get a feel), and finally runs the docker image with a volume mapping from /opt/onlinetesting1/tmp on the host machine ( your cloud VM) to /bundle in the docker container, and also passing various docker container environment settings for mongodb MONGO_URL and port, application server port, application name, meteor ROOT_URL etc.. The docker image 'entry point' was itself configured a priori (by the author of abernix/meteord) to run the meteor app server start up script when a container is created and run from the image. The docker run script is uploaded by mup to /opt/onlinetesting1/config/ on the host VM.

mup has a single point method of specifying the above settings as also all settings for the tool to log into the cloud VM using ssh. That single point is the mup.js file. Please see this for details. Please refer to  this to know how ssh login to your cloud VM works using an ssh-keygen authored digital certificate from your machine.

As happens very often, the above procedure didn't work OOTB for me. The docker image abernix/meteord comes with node 4.x and phantomjs 1.9.x preinstalled. But our meteor app for Online testing had problems with phantomjs 1.9.8.
 You may ask why we couldn't take the route of simply installing our version of phantomjs (2.1.1) into our cloud-installed docker container. The issue here is that even if we saved the container locally back to the image, the latter would get overwritten the next time we did a 'mup deploy' to deploy our new changes.

Here is what worked for me finally - create my own base docker image from abernix/meteord with pantomjs 2.1.1 (and vi editor !) installed. Then upload it to docker hub. Here are the steps :-

Create a folder called anything - 'dockerstuff' may be - somewhere. Then create a file called 'Dockerfile' in that folder. Also create a 'script.sh' file with the following code, in that folder.
#!/bin/bash

while true; do
    read -p "Give a y/n input"  yn

done

Don't forget to change its permissions to 777. Why a script that stops by expecting input ? Because we are going to keep the container alive by tying it with a process that potentially doesn't end. This is because we want to do something useful by opening a bash shell on the container, next, and we can't do that if the container has already finished with its start up script and stopped. There are probably other, even easier ways to do this, but this way works too. For other options see for example, this. Now put the following lines to execute the startup script, 'script.sh' in Dockerfile

FROM abernix/meteord:base
ADD script.sh / 
ENTRYPOINT /script.sh 
The ADD command adds the script.sh from the host into the / (root) folder of the container. The ENTRYPOINT command changes the startup process from the one for which the parent image (abernix/meteord) is configured to our simple one from script.sh.

Now build your image. At the shell prompt type

docker build -t test:base .
This creates a new image with the above entry point, but based otherwise on abernix/meteord.
To see a listing of all docker images, type
docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
test                         base               b30086a9e634        23 seconds ago        645 MB

abernix/meteord              base                edaae2ab7250        2 weeks ago         514 MB
Run the image b30086a9e634  to start a new docker container.
docker run -d  b30086a9e634
Here -d is for starting the container in the background. To see the container id type
docker ps -s
You get a listing like this
CONTAINER ID        IMAGE             COMMAND                  CREATED             STATUS              PORTS                        NAMES               SIZE
fecae970f27b        test:base   "/bin/sh -c /scrip..."   21 seconds ago        Up 21 seconds         0.0.0.0:80->80/tcp           quirky_allen      824 B (virtual 514 MB)

Create an interactive shell in this container

docker exec -it fecae970f27b bash
Now you are in a shell of the container, and as root user !
Remove all old phantomjs links and installations
rm -r /usr/local/bin/phantomjs /usr/bin/phantomjs /usr/local/share/phantomjs /usr/local/share/phantomjs-1.9.8-linux-x86_64
 Install latest phantomjs (it is 2.1.1 as of now)
npm install -g phantomjs-prebuilt
Install whatever else you want. For example, I installed the vi editor.
Exit the shell
exit
 Now you are back to you host machine shell prompt.
First thing, save your changes to the image.
docker commit fecae970f27b test:base
Now create your new image by now specifying test:base as parent in Dockerfile but reverting to the original entry point from abernix/meteord
 FROM test:base 
ENTRYPOINT bash $METEORD_DIR/run_app.sh

Then create the image. Lets call it ssashita/testjha
docker build -t ssashita/testjha:base .
Then check that the ssashita/testjha:base image got created by running
docker images

Now we have an image that has the correct version of phantomjs. We now need to upload this on docker hub so that mup tool can pull it from the cloud VM.
For this I first need to login to my docker account (create one if you don't have one, and follow along on the site and create a public repository. It's easy).
docker login --username=ssashita

Now push the image to your dock hub account
 docker push ssashita/testjha 
 This might take a while to finish.

Next go to your app deploy folder ( mine is .deploy under the app root). Edit the mup.js file.
Change docker.image to "ssashita/testjha:base" (from abernix/meteord:base).

That's it. Follow rest of the instructions in this to complete the cloud deployment. For example you will need a
mup setup
followed by
mup deploy 


Sunday, January 8, 2017

Bayesian Networks - part 1

 Imagine this very common situation. You have to go to the movies after office. There is a 50% chance you will get delayed at work. There are 3 routes A, B and C for you to get to the cinema hall from your office, and you are likely to take them with probabilities 0.4, 0.2 and 0.4 respectively.
Whether you reach the cinema hall on time or not, depends on whether you got delayed at work and which route you took. The probabilities of reaching on time or not vary as in the table



You have different queries to make. For example, given that you left work late but still reached on time, what is the route you are most likely to have taken ? Or, given that you chose route C, what is the likelihood that you reached the cinema hall on time ? Or, given that you started late and took route C what is the likelihood that you reached the hall on time ?
 The answers to these questions can easily be answered by constructing a Bayesian network for the problem. This is how the network looks like.

For every node you specify the probability values. For the 'LeaveOffice' node variable you specify the two probability values for leaving office late and on time (50%). For the 'RouteTaken' node you specify the probability values for routes A, B and C (0.4,0.2  and 0.4). Finally for the 'ReachOnTime' node variable you specify the probability values conditional to joint of the LeaveOffice and RouteTaken events, as in the table above.
 An analysis of this network gives the following answers to our questions.
Q1. Given that you left work late but still reached on time, what is the route you are most likely to have taken ?
The answer is C, which is clear from the output of the analysis


Q2. Given that you chose route C, what is the likelihood that you reached the cinema hall on time ?
The answer is 50%.


Q3. Given that you started late and took route C what is the likelihood that you reached the hall on time ?
The answer is 40%


There are many other questions like these that the Bayesian net can answer.

Output images taken using the  UnBBayes software. ( UnBBayes is a free software: you can redistribute it and/or modify it under the terms of the GNU General Public Licence as published by the Free Software Foundation, either version 3 of the license, or (at your option) any later version. )

Is this stock advise worth taking seriously?

 Introduction Business related TV channels and newspapers are replete with stock advisory from investment firms and certified individua...