I'm thinking about how should be the process to deploy my already locally tested rest api to the cloud, lets say an infrastructure as a service (not a platform as a service such as Heroku) like amazon.
I have my local envorinment set up with sbt up and running but my question is How should I deploy this in a production environment?
Is it sane to define a process in which the devops pulls the most recent changes from the git repo and then simply executes sbt run?
I want to know how does the teams that uses scala+spray+sbt deploys their apis to a production environment.
The heart of our services is scala + akka + spray + mongo. So we are using GitHub for version control. After merging checked PRs to the master branch, Jenkins automaticaly tests'n'builds project. If all tests were successful then Jenking runs a couple of scripts:
- Increment project version (currently written in shell, but will be changed to sbt)
- Run assembly task with sbt-assembly
- Run deploy script (written in Python with Fabric) wich deploys our jar to EC2
Basicaly on the thrid step you have a couple of choices:
Make a runnable jar using IO/Spray boot file:
object Boot extends App {
implicit val system = ActorSystem("ServiceName")
val log = system.log
val service = system.actorOf(Props[Service], name="serviceActor")
IO(Http) ! Http.Bind(service, interface = host, port = port)
}
Make a runnable jar as Akka's microkernel:
In this case you should extend Bootable trait and override startup
and shutdown
methods:
class Kernel extends Bootable {
// many lines of code
def startup() {
scheduler.start()
SomeActorSystem.startup()
}
def shutdown() {
scheduler.shutdown()
SomeActorSystem.shutdown()
system.shutdown()
}
}
Using a TypeSafe startscript:
Can't show an example, but it has a good intro on github =)
We are using all of this way in different cases.
You should build a jar with the plugin sbt-assembly
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.9.0")
Then you can run the jar in production with java -jar
If you give version number to your project, this is a rather classic process.
Hope it helps.
Never went to PRO with spray-akka. Only pet projects. My suggestions here should be taken as inspiration. I know some of the options I present are costly in terms of maintenance or prone to errors.
Packaging
I only used maven-shade-plugin (no experience with sbt) but I guess there's a similar solution.
Packaging Issues
There's few issues with this approach though. Akka and many of the spray modules use the references.conf and application.conf convention. When assembly/shading all your dependencies the resources (since they are named the same) may overwrite and you'd be unable to start the application.
The quick and dirty solution I found was to copy/paste the application and ref.conf of the dependencies into one controlled by me.