SBT using sbt-native-packager how to create different build files?

800 views Asked by At

I have a Play 2.3 Application, following the docs I can build a debian package, the problem comes when I want to build things like this:

I have different configurations for dev, qa and prod, and I want to build to 4 different packages, one that contains the code and the others that contains the configuration. so I will get this 4 packages:

app-version.deb [this contains the code]
app-config-dev-version.deb [this contains the dev configuration]
app-config-qa-version.deb [this contains the qa configuration]
app-config-prod-version.deb‏ [this contains the prod configuration]

but for installing app-version.deb I will need one of the others as a dependency depending on the machine.

machine-dev: app-version.deb and app-config-dev-version.deb
machine-qa:  app-version.deb and app-config-qa-version.deb
and so on ... 
1

There are 1 answers

2
Muki On

Configuring your application with additional debian packages is not a good idea in my experience. For a play application you have other options that are a lot easier to create and maintain.

Use multiple .conf files

Play uses the Typesafe Config Library. Create a configuration file for each of your environments, e.g.

conf/
  reference.conf   # contains default settings
  dev.conf
  qa.conf
  prod.conf

Now how to define which one gets packaged? Well there are a few options.

Package them all and choose at startup time

Package all and choose at startup time which to use:

./bin/your-app -Dconfig.resource=conf/prod.conf

This is straight forward and works if you have control over how things get started.

Package them all and choose package time

You can add the start command during build time via javaOptions in Universal. You can do this either with a Command Alias or a custom task

Copy and rename specific conf

Basically you choose (for example with a custom task as above) which configuration to include as application.conf.

mappings in Universal += {
  val conf = (resourceDirectory in Compile).value / "reference.conf"
  conf -> "conf/application.conf"
}

I recommend against that as you have no idea which package you are using at the moment.

UPDATE

Use submodules

Configurations/Scopes are more complicated and behave sometimes in unexpected ways. The easy alternative is to use submodules.

your-app/
  app
  conf
  ..
dev/
qa/
prod/

Your build.sbt would then contain something like this

lazy val app = project
  .in(file("your-app"))
  .enabledPlugins(PlayScala)
  .settings(
     // your settings
  )

lazy val dev = project
  .in(file("dev"))
  // this one is tricky. 
  // Maybe it works when using the PlayScala Plugin
  .enabledPlugins(PlayScala)
  .settings(
    // if you only use the JavaServerAppPackaging plugin 
    // you will need to specifiy a mainclass
    //mainClass in Compile := Some("")
)

// ... rest the same way

In the end you build with dev/debian:packageBin for development.