zondag 21 maart 2010

Grails application hosting on a Linux VPS

After some time of development the Agile Tracking Tool is now live at www.agiletrackingtool.com. This blog shows an overview of virtual hosting providers for java web-applications and my configurations steps for the linux host.

Finding a host provider

Where to start when selecting a host provider for a java based web application? Some time ago I started doing some research on the topic. One of the options would be direct hosting of a grails web application by the cloudfoundry.com. A nice blog by Marcel Overdijk describes this. This is however a bit more expensive (roughtly $75 a month) than a vps (starting at $20+ a month). Another option would be google app engine. My impression is that this however will take some time to further mature.
At Grails.org there is a nice overview of hosting providers. This blog and comments showed valuable information. On the grails mailing list the following names kept popping up (initial impression in braces):
Starting at around $20-22 per month (250 Mb).

Finally I selected eapps.com. Reasons: it was recommended to me by a fellow enthusiast at a nlgug meetup, it was on my short list, good reviews, their support pages are helpful (mentioned grails), they are in business since 1996. The nice thing about a provider in the US that their office-hours are my evening hours. 

Tip: If you know a nice grails website just use whois to find out who-is hosting.

Creating the account
After experimenting with some home virtual linux servers (virtualbox.org) it was time to take the plunge. On Friday evening I registered for an account at www.eapps.com. I selected a Linux VPS with 432 Mb memory. Postings already mentioned that 250 Mb is the minimum for running Grails apps.

After 10 mins I already received a call to verify my account details: "I am looking for B....".  My acount would be live in 5 minutes... Now that's fast. It indeed popup up at the servers administration page. Using the experience from configuring Linux servers at home I had my first grails application live within 2 hours after the account request.

Installing applications 













From the web-application page I selected to install the following applications:
  • Apache (webserver)
  • Tomcat 6 + mod_jk plugin (webserver for java web applications).
  • Mysql 5
  • Groovy + Grails (didn't expect that one).
  • Subversion (get my code from the repository)

    Configuring
    Logging into the server is done via ssh. I use vim (or emacs) to edit files.





      I changed the MySql configuration to use InnoDB engine to support transactions. Adding the following line to /etc/my.cnf  in section [mysqld] does the trick:
      default_storage_engine = InnoDB

      More information can be found on the mysql support page.


      The eapps support page for tomcat and mod_jk were very useful.

      Adjust /opt/tomcat6/conf/tomcat-users.xml to change the default (so easy to guess) password.

      Accessing the Tomcat server via the Apache webserver is done by the mod_jk plugin as described over here. After some time I finally figured out that I just had to add one line to grails web-application accessible via www.agiletrackingtool.com/mysecret. (mysecret are other 'secret' characters known to those one joining for early testing).














      Once the mod_jk configuration is working you can disable tomcat listening to port 8080 so the tomcat server can not be accessed directly from the outside (/opt/tomcat6/conf/server.xml):

      <!-- commented out
      <Connector port="8080" protocol="HTTP/1.1"
                 connectionTimeout="20000"
                 redirectPort="8443" />
      -->


      Tomcat JNDI
      Update March 24: The issue seems to be fixed using this solution. No broken Mysql connections this morning. 
      Update March 23: The Mysql brokken connection issue is still present. Even after setting 'autoReconnect=true'. The next step will be checking out this advise. Any help or suggestions are welcome! Very unpleasant issue... 
      Update March 21: After the web site is not used for a longer time a mysql connection error is reported (see issue). I tried to resolve the issue by configuring jndi on tomcat. Adjust (/opt/tomcat6/conf/context.xml) and and the "Resource" section:
      <Context>
      ....
      ..
      <Resource name="jdbc/agiletracking"
                  auth="Container"
                  type="javax.sql.DataSource"
                  username="mysecret"
                  password="also"
                  driverClassName="com.mysql.jdbc.Driver"
                  url="jdbc:mysql://localhost/agiletracking?autoReconnect=true"
                  maxActive="100"
                  maxIdle="8"/>

      ..
      ...
      </Context>

      JNDI in your grails application is configured in your DataSource.groovy:
      production {
        dataSource {
         dbCreate = "update"
         jndiName = "java:comp/env/jdbc/agiletracking" 
        }
       }

      Also make sure that /opt/tomcat6/lib contains the mysql-connector-java.jar (already installed by eapps.com).
      Update Jan 2011: Interestig link on how to configure mysql timeout on Dzone using DataSource.groovy (see comment).

       Tomcat memory
      By default tomcat is configured to use 64 Mb. Performance however dramatically increased when setting it to the recommended maximum size of 192 Mb  in /etc/tomcat6/tomcat.conf):

      # Initial Java Heap Size (in MB)
      wrapper.java.initmemory=192
      # Maximum Java Heap Size (in MB)
      wrapper.java.maxmemory=192

      This gives a great performance boots. With 64 Mb my web application was much slower as compared to running it on my local machine. With 192 Mb the performance feels much snappier.

      When idle Tomcat says: 
      Free memory: 110.83 MB Total memory: 185.62 MB Max memory: 185.62 Mb. 

      The Linux memory use ('free -m') shows:
                    total      used       free
      Mem (Mb):      432        299        132  

      Deployment of your grails war file is simple done by copying your file (sftp) to '/opt/tomcat6/webappsand restarting tomcat.

      That's it. Configuring my web-application on a vps turned out to be quite smooth going. Over time more settings will be tuned (mysql database size), but this proved to be a nice start.