This blog will be my notepad of things i learn , new programming language, tools , compilers etc.This blog is more of my penesive to see how much my understanding of things have evolved.
As part of the mongodb course, one of the assignment required to complete the backend of the blog.I wanted to get my hands a bit more dirty and so i decided to deploy the entire application to heroku with mongolab as the backend.The following are the steps that i followed to make the site work in heroku and mongolab.
Deploying the site to Heroku
Heroku has build packs which are essentially set of language tools that are needed for deploying your application. Since in heroku we deploy application by pushing code, build packs provide the basic infrastructure thats needed to compile/interpret your code.
Install the heroku toolbet as it provides a set of command line tools for deploying application easily to heroku.
login to heroku using the following
$ heroku login
Enter your Heroku credentials.
Email: adam@example.com
Password (typing will be hidden):
Authentication successful.
Create a new application using ** heroku create ** .This creates a dyno that can be used to deploy your application.
Now the application is deployed to heroku, we need to make sure that its working and we can open the application using
Pradheep (master) hw4-3 $ heroku open
Opening infinite-shore-9738... done
7.When i opened the application page it was throwing page not found error.So in order to figure out the error we can see the logs by using command
Pradheep (master) hw4-3 $ heroku logs
2015-12-01T18:54:17.334789+00:00 heroku[web.1]: Starting process with command `python ./blog.py`
2015-12-01T18:54:19.342818+00:00 app[web.1]: Bottle v0.12.9 server starting up (using WSGIRefServer())...
2015-12-01T18:54:19.342862+00:00 app[web.1]: Listening on http://localhost:8082/
2015-12-01T18:54:19.342874+00:00 app[web.1]: Hit Ctrl-C to quit.
2015-12-01T18:54:19.342876+00:00 app[web.1]:
2015-12-01T18:55:17.799116+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch <--------------- This is error
2015-12-01T18:55:17.799116+00:00 heroku[web.1]: Stopping process with SIGKILL
2015-12-01T18:55:18.475966+00:00 heroku[web.1]: State changed from starting to crashed
2015-12-01T18:55:18.458035+00:00 heroku[web.1]: Process exited with status 137
2015-12-01T18:55:19.155515+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=infinite-shore-9738.herokuapp.com request_id=79d4746f-8a61-409e-b970-49c99f7ef3c3 fwd="72.177.207.73" dyno= connect= service= status=503 bytes=
2015-12-01T18:55:19.701594+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=infinite-shore-9738.herokuapp.com request_id=a38c3ce7-eb7e-4b88-ad3d-a79eabbe0b61 fwd="72.177.207.73" dyno= connect= service= status=503 bytes=
Looking at the logs above its clear that we are not binding to the correct port. Revel applications must bind to the port that the heroku application specify using the enviornment variable $PORT. So we modify the application to make it listen to the $PORT.
bottle.run(host='0.0.0.0', port=int(os.environ['PORT'])) # Start the webserver running and wait for requests
In the above example, as the default application used bottle i modified the application a bit to use the enviornment variable $PORT
Heroku also needs a Procfile to help it understand how it needs to start the application.
Now push the changes again using git push and look at the heroku logs to see what went wrong and fix it untill the application is running properly.
Also make sure that you are trying to access a page that is doesnot use database query as we have not yet connected a mongodb to the application yet.
11. To open the heroku application logs or login to the application use * heroku run bash* command as below
Pradheep (master *) hw4-3 $ heroku run bash
Running bash on infinite-shore-9738… up, run.5908
12. If you application has crashed and you need to start it again then use the * ps:webscale * option
heroku ps:scale web=1
```
The default free tier provides only 1 tier so set the value is set to 1 above.
In the next post i will discuss how i hooked up mongolab to our blog application.
For those people who don’t know what CI is, continue reading this paragraph . The general way most development team used to work earlier was , team members develop their code in isolation in separate branches and after everyone is done , the integration team would pull all the changes and integrate everything.This is a hard process, as there are merge conflicts due to overlapping changes,memory leaks detection becomes hard as loads of changes, bug isolation is hard as no one is sure which code introduced it and so on. In general, significant dev team was spent on integration and testing.However,CI makes all these process simple by automating tests with unit tests, integration tests so that bugs are detected early and in isolation.More on CI here
But running Continuous integration, for developers of open source was bit difficult.One has to setup a Jenkins server locally and run it for every merge. It would be better, if we are able to run CI on each pull requests that others send. The solution is Travis and it works with all github projects out of the box.
I was excited to see Travis support by default in github and free for all projects that are open sourced. I decided to give it a shot. Though i could have done a small code to test its no fun but nothing beats automating a full project.So looking around i found redis has not updated itself with travis support. Redis in fact runs all the tests in http://ci.redis.io/ .I felt running these tests as part of the each pull requests to redis would be awesome. So here is how i got the basic travis setup to work.
Adding travis to any project in github is easy. Just add .travis.yml in the top directory of your repo and you are done.
So the first step in .travis.yml file is to define the language and the compiler you want the project to compile.
Natively travis support gcc and clang. So i added the below lines .travis.yml
Travis provides travis-lint that can check for errors in travis.yml file . You can install travis-lint using the following command
gem install travis-lint
And then you can check .yml file using the command
travis-lint [path to your .travis.yml]
Adding the above changes to the repo and pushing it to the github was all the basic configuration that was needed.Then i had to add my repo to travis.The steps to add a repo into travis is very straight forward and step by step instructions can be found in this site
The travis.yml file has different sections similar to rpm packaging to control the build, test and deployment. To build and test your application the script sections must contain your application specific build and test specification.So i added the below lines to .travis.yml
Pushing the above to github automatically triggers travis to run the test.Result of one such build is here.Travis was reporting error and looking at the logs it was clear that the setup needed tcl and it was not available causing the test to fail.So the next step was to add tcl package.
Travis tests all the applications on top of Ubuntu and installs some of language specfic packages.But not all packages are installed and one can install any package by using the apt-get command.Since the packages must be added before the make test, i added install tcl 8.5 in before_script section to .travis.yml
The before_script section, as you might have guessed, is executed before the script section.This installs tcl and since there was no dependency problem anymore tests ran successfully.If you look at the link you will see tha the tests are run both in clang and gcc. This is because we had asked for clang and gcc as compilers in the compiler section.
The next step was to make the code run in both in OSX and linux.Currently travis only supports 64 bit OS Linux and support for OSX is in beta. There is plans to add support for FreeBSD.Back to what I was doing, to add OS support i added the following lines
But there was one more thing, i need to install tcl for OSX. So i ended up modifying the before_script with the following lines
Brew is the unofficial package manager for OSX.
Cautious readers would notice that i added brew tap homebrew/dupes.This is because OSX comes preloaded with tcl and in order to make sure that users dont override the default package, brew uses the dupes to make sure that people who are installing knows what they are doing.
Finally i sent a pull request to redis and i am currently not sure when it will get integrated.The entire pull request is here.The changes are the basic and if the pull request is accepted i am planning to add matrix build and also move the changes to new test infrastructure.
I wnated to get my hands dirty with go and so i thought i would install it in mac.So as usual i was trying to install using brew.The installation went smooth but whenever i was trying to install a package i was thrown an error as below
The problem is that both the GOPATH and GOROOT was not set properly and PATH was not updated correctly.After several trial and error methods and of course at last google to the rescue i was able to finally get it working
For bash put the below in ~/.bashrc
# don't forget to change your path correctly!
export GOPATH=$HOME/golang
export GOROOT=/usr/local/opt/go/libexec
export PATH=$PATH:$GOPATH/bin
export PATH=$PATH:$GOROOT/bin
For zsh which is the default shell in mac (~/.zshrc)
# don't forget to change your path correctly!
export GOPATH=$HOME/golang
export GOROOT=/usr/local/opt/go/libexec
export PATH=$PATH:$GOPATH/bin
export PATH=$PATH:$GOROOT/bin
You can of course change the GOPATH to any of your project specific workspace.Just update the corresponding path in your folder you are interested.
Just make sure that there is no space in the folder path as i find it causes too much problem :(. The easier way to get around is by soft linking the destination path to the one which has no space :)