MyFirstLiftApp(tm) + Deployment story 2016?

67 views
Skip to first unread message

Henrik Härkönen

unread,
Sep 1, 2016, 12:42:51 PM9/1/16
to Lift
Hi all!

Wohoo, I got my first real Lift app up and running (on the scary wide internets)!

It's a scrum planning poker app, just something I wanted to put together for our team at work, to try out lift.

If you wish to check it out, it's here: Plapo Party! (Plapo = Planning Poker, how ingenious...)

Pretty basic stuff, and still work in progress, but I'm quite happy with the comet functionality: the number of voters and completed ones are updated nicely, also the results page uses comet. The button for going to next voting round activates only after all users have voted etc.

There was one iPhone 5S user for who the comet didn't work for some reason, but for me it did just fine (I have one too), couldn't figure out what was failing.
I guess I have to add some fallback solution, manual ajax refresh or something...

Currently I'm running it on a virtual server, and I pull from a GIT repo and then start it with sbt console ("container:start") and Nginx redirects there, but I'd like to deploy it properly at some point, when active development is over.

What are the current best practices for deployment?

I was reading some old threads and there were nice tips, WAR, standalone "RunWebApp" style etc, but I'm not sure what to aim for. I tried installing jetty on my machine (latest Ubuntu) and put the war file I got with "packageWar" command to /usr/share/jetty/webapps/ but I got this error:

Message: java.lang.NullPointerException: Looking for Connection Identifier ConnectionIdentifier(lift) but failed to find either a JNDI data source with the name lift or a lift connection manager with the correct name

I read some older reports about it, but I think my connection identifier should be ok? It's from the version 2.6 starter template:

    if (!DB.jndiJdbcConnAvailable_?) {
      sys.props.put("h2.implicitRelativePath", "true")
      val vendor =
        new StandardDBVendor(Props.get("db.driver") openOr "org.h2.Driver",
          Props.get("db.url") openOr
            "jdbc:h2:lift_proto.db;AUTO_SERVER=TRUE",
          Props.get("db.user"), Props.get("db.password"))

      LiftRules.unloadHooks.append(vendor.closeAllConnections_! _)

      DB.defineConnectionManager(util.DefaultConnectionIdentifier, vendor)
    }

The Jetty I installed was Jetty8 and also the container:start command launche Jetty 8.x, but could it be some file permission thingie, if this writes the DB somewhere?
I'm not using any of the DB functionality, all session related data is in-memory structures for now at least.


Cheers,
Henrik.

Brett Grace

unread,
Sep 1, 2016, 9:16:29 PM9/1/16
to Lift
I use xsbt-web-plugin to embed Jetty, and then sbt-assembly to create a standalone jar. Then an init script (well, systemd service) to start the daemon.

Not sure what's going on with your database related error. Maybe you can verify if the vendor is getting set up properly. For example, it wouldn't work if you had something wrong with your configuration or if it couldn't find the driver in the classpath.

For the database error, I'm not sure what's going on. Maybe the system can't find your configuration, or you don't have the h2 drivers in your classpath.do you have those drivers in your classpath?

Diego Medina

unread,
Sep 1, 2016, 9:55:33 PM9/1/16
to Lift
Comments inline:

On Thu, Sep 1, 2016 at 12:42 PM, Henrik Härkönen <heha...@gmail.com> wrote:
Hi all!

Wohoo, I got my first real Lift app up and running (on the scary wide internets)!

Awesome news!

 

Currently I'm running it on a virtual server, and I pull from a GIT repo and then start it with sbt console ("container:start") and Nginx redirects there, but I'd like to deploy it properly at some point, when active development is over.

What are the current best practices for deployment?


I personally use the same tools Brett mentioned 

xsbt-web-plugin to embed Jetty, and then sbt-assembly to create a standalone jar. Then an init script (well, systemd service) to start the daemon.

if you need any help there, I should have some demo app with that config somewhere in github.

At work we moved to using https://github.com/xerial/sbt-pack

To trigger the actual deployment, we have a combination of tools.

1. We have jenkins that pulls from master every time we merged  pull request
2. It then runs tests and builds our deployment files (this is where you can use sbt assembly)
3. When we are ready to deploy it, we use hubot on flowdock and tell it to deploy, it then runs some magic scripts that copy the jar(s) to our web servers, and restarts the service to pickup the new jars
4. enjoy new features :)

 

I was reading some old threads and there were nice tips, WAR, standalone "RunWebApp" style etc, but I'm not sure what to aim for. I tried installing jetty on my machine (latest Ubuntu) and put the war file I got with "packageWar" command to /usr/share/jetty/webapps/ but I got this error:



I haven't used an installed jetty in a really long time so no comments here

Best regards,

Diego
 
Message: java.lang.NullPointerException: Looking for Connection Identifier ConnectionIdentifier(lift) but failed to find either a JNDI data source with the name lift or a lift connection manager with the correct name

I read some older reports about it, but I think my connection identifier should be ok? It's from the version 2.6 starter template:

    if (!DB.jndiJdbcConnAvailable_?) {
      sys.props.put("h2.implicitRelativePath", "true")
      val vendor =
        new StandardDBVendor(Props.get("db.driver") openOr "org.h2.Driver",
          Props.get("db.url") openOr
            "jdbc:h2:lift_proto.db;AUTO_SERVER=TRUE",
          Props.get("db.user"), Props.get("db.password"))

      LiftRules.unloadHooks.append(vendor.closeAllConnections_! _)

      DB.defineConnectionManager(util.DefaultConnectionIdentifier, vendor)
    }

The Jetty I installed was Jetty8 and also the container:start command launche Jetty 8.x, but could it be some file permission thingie, if this writes the DB somewhere?
I'm not using any of the DB functionality, all session related data is in-memory structures for now at least.


Cheers,
Henrik.

--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

---
You received this message because you are subscribed to the Google Groups "Lift" group.
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Diego Medina
Lift/Scala Consultant
di...@fmpwizard.com
http://blog.fmpwizard.com/

Henrik Härkönen

unread,
Sep 2, 2016, 1:24:48 AM9/2/16
to Lift

Thank you Brett and Diego, those tools look promising! Especially the xsbt-web-plugin seems to promote itself as a tool to go forward with cloud platforms.
Jelastic somehow seems to appeal to me, I'd like to try it out. Another way to go about it would be use Docker. IntellijIDEA  has now Docker build support, could be handy option as well.

Exciting. :)

-Henrik

Henrik Härkönen

unread,
Sep 4, 2016, 1:00:51 PM9/4/16
to lif...@googlegroups.com
Ok I put an PostgreSQL server running on the server and made the db connection there, now it works. Seems that the default H2 setup works so that the H2 is started on the SBT scripting, but when packaging to WAR, it obviously isnt' "there". :)

Can Lift be started without a DB setup?

That would be most convenient currently for me, since I don't use it in that project at all. I tried to remove the whole block from Boot.scala, but I guess the J2EE container thingie is looking for the JNDI-whatever...?

-Henrik

Peter Petersson

unread,
Sep 4, 2016, 1:19:41 PM9/4/16
to lif...@googlegroups.com

Yes lift can be started without a DB setup,

maybe you forgot to remove some of the db import(s), like mapper or something ?

best regards Peter Petersson
--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

---
You received this message because you are subscribed to the Google Groups "Lift" group.
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+u...@googlegroups.com.

Henrik Härkönen

unread,
Sep 4, 2016, 1:34:21 PM9/4/16
to lif...@googlegroups.com
D'oh! Indeed, I still had imported mapper! :)

Thanks!

-Henrik

You received this message because you are subscribed to a topic in the Google Groups "Lift" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/liftweb/eERStLaRCPQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to liftweb+u...@googlegroups.com.

Henrik Härkönen

unread,
Sep 4, 2016, 1:48:56 PM9/4/16
to lif...@googlegroups.com
Ok, now that I don't have to run postgresql on the server, I decided to test the jetty deployment.

It was easy.

- apt install jetty8 (or 9, tested now with 8)
- SBT: "compile" and then "packageWar"
- copy the WAR to /usr/share/jetty8/webapps/root.war

and works perfectly. I thought this approach would be nice, so that I can have easily multiple apps running there and just point nginx to right app, according to hostname, and no need for custom startup scripts etc, when the host reboots. This seems... "clean" and straightforward solution for now.

Thanks all!

-Henrik

Antonio Salazar Cardozo

unread,
Sep 6, 2016, 1:30:22 PM9/6/16
to Lift, heha...@iki.fi
Awesome! Glad you got everything sorted :)
Antonio
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

---
You received this message because you are subscribed to a topic in the Google Groups "Lift" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/liftweb/eERStLaRCPQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to liftweb+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages