I'm using the sbt native packager plugin to create a zip file of my application for deployment to elastic beanstalk. I would like to set environment variables in my beanstalk environment and have those be used to configure my application at runtime. I've attempted to reference the env variables in my Procfile like so:
web: ./bin/bridgeservice -Dhttp.port=$PORT
This does not work as $PORT
is not interpolated by the start script generated by the packager.
I've also attempted to define the variables in my build.sbt like so:
import scala.util.Properties
javaOptions in Universal ++= Seq(
"-Dhttp.port=" + Properties.envOrElse("PORT", "9004"),
)
This also does not work as the packager expects the PORT
env variable at the time of building the distributable zip and hardcodes the default value of 9004 in an application.ini file.
Is it possible to dynamically pass java options based on environment variables at application startup?
The settings in javaOptions in Universal
are compiled into conf/application.ini file, but accordingly to sbt-native-packager docs application.ini currently does not support variable substitution:
The file will be installed to ${app_home}/conf/application.ini and read from there by the startscript. You can use # for comments and new lines as you like. This file currently doesn’t has any variable substitution. We recommend using the build.sbt if you need any information from your build.
So,the env var based runtime settings can be achieved in several ways:
Solution #1. Add extra definitions to generated start script
In build.sbt:
bashScriptExtraDefines += """addJava "-Dhttp.port=${PORT:-9004}""""
Check out Application and runtime configuration documentation for more info.
Solution #2: Set JAVA_OPTS env var in the target server
Just set JAVA_OPTS
environment variable on the target server and make it available for the start script. This can be the easiest solution for environments like AWS ElasticBeanstalk where env vars can be set on the app's environment configuration page.
Not sure if this will help, but I had similar issue when building docker images of my multi module project.
I ended with this:
def sysPropOrDefault(propName: String, default: String): String = Option(System.getProperty(propName)).getOrElse(default)
val somePort = sysPropOrDefault("port", "9004")
and in the project definition:
lazy val someProject = project("some-project")
.enablePlugins(JavaServerAppPackaging)
.settings(
javaOptions in Universal ++= Seq(
s"-Dhttp.port=$somePort"
)
)
Adding javaOptions to project settings level was crucial in my case. And s before option is not a typo.
When running command from terminal I called:
sbt clean update -Dport=9005 docker:publishLocal
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With