I am new in Akka and want to set up different application.conf files per environment (test, staging, prod, etc.).
I read the documentation from Akka but I couldn't find a way to do it.
May you know any proper way to have multiple configuration files?
Akka uses the Typesafe Config Library.
The convenience method ConfigFactory.load() loads the following (first-listed are higher priority):
system properties
application.conf (all resources on classpath with this name)
application.json (all resources on classpath with this name)
application.properties (all resources on classpath with this name)
reference.conf (all resources on classpath with this name)
So we usually create an application.conf file in /resources folder.
For different environments, we can create environment specific files like
development.conf
production.conf
Using includes, include application.conf at the beginning and specify environment specific configurations which will override the application.conf.
To use a specific environment force a different config source (e.g. from command line -Dconfig.resource=environment.conf)
Start your application using below command:
$ sbt run -Dconfig.resource=development.conf
Here are couple ways to do it.
Add tags with in a file itself like
prod-config : { YOUR_CONFIGURATION_FOR_PROD }
test-config : { YOUR_CONFIGURATION_TEST_ENV }
and so-on
Make separate files for the each environment and rename it once after deploying them to specific environment. Say from application-prod.conf to application.conf
A possibility is have a single variable in application.conf which would be "confFile", based on an actual env like
confFile=${?CONF_FILE_NAME}
Then in your code, you load the correspondind file like this
val configFile = ConfigFactory.load().getString("confFile")
val appConf = ConfigFactory.load(configFile)
The options for this aren't so much related to Akka as it is to the config library. Akka uses the default config resolution unless you give it a Config instance.
With no specific user code to manually select a specific file you have a few options. I think the most useful are the system properties config.resource to choose a file on the class path (inside the app jar for example), config.file to use a file from the file system.
Of course you may still have reasons to write your own code to select files as the other answers suggested.
More details in the config library docs: https://github.com/lightbend/config#standard-behavior
Related
I have a config file in the below folder subtract
main
scala
resources
application.conf
and that contains
path{
http{
url = "http://testingurl"
}
}
I am reading using below code
import com.typesafe.config.Config;
val url = conf.getString("path.http.url")
I am reading this static information which is provided durng build time.
Now I want to read these in runtime, user should be able to modify configs even after jar is built.
my requirement is to modify url event after jar is build, I dont want to pass as a arguments to the main function because I have so many such values which needs to modified after jar built
See:
Lightbend Config Readme
Use at runtime:
-Dconfig.file=<relative or absolute path>
See:
For applications using application.{conf,json,properties},
system properties can be used to force a different config source
(e.g. from command line -Dconfig.file=path/to/config-file):
config.resource specifies a resource name - not a basename, i.e. application.conf not application
config.file specifies a filesystem path, again it should include the extension, not be a basename
config.url specifies a URL
These system properties specify a replacement for application.{conf,json,properties}, not an addition.
They only affect apps using the default ConfigFactory.load() configuration.
In the replacement config file, you can use include "application" to include the original default config file;
after the include statement you could go on to override certain settings.
I assume that a .jar file is build with a key provided as
val url = conf.getString("path.http.url")
and you are going to run this .jar every time with modified .config file
my requirement is to modify url event after jar is build,
a possible solution is to provide a array of the config values, where key remains same in .jar file
import com.typesafe.config.ConfigFactory
ConfigFactory.load().getStringList("url.key").stream().map(eachUrl => functionToBeCalled)
When developing a Play application, we use the standard configuration file in conf/application.conf. How can I use different conf files depending on whether I'm in debug or release mode?
Let's say you have prod.conf and debug.conf both in the conf folder, you can add the following system property:
-Dconfig.resource=(prod|debug).conf
if the files can't be packaged in the app in the conf folder and have to be external, for example, in /opt/conf, then you can add the following instead:
-Dconfig.file=/opt/conf/(prod|debug).conf
They can inherit a common configuration file and override values:
include "application.conf"
key.to.override=blah
See reference for more on this.
I am building a Scala Play 2.4 application which uses the typesafe activator.
I would like to run my tests 2 times with a different configuration file for each run.
How can I specify alternative config files, or override the config settings?
I currently run tests with the command "./activator test"
You can create different configuration files for different environments/purposes. For example, I have three configuration files for local testing, alpha deployment, and production deployment as in this project https://github.com/luongbalinh/play-mongo
You can specify the configuration for running as follows:
activator run -Dconfig.resource=application.conf
where application.conf is the configuration you want to use.
You can create different configuration files for different environments. To specify the configuration to use it with activator run, use the following command:
activator "run -Dconfig.resource=application.conf"
where the application.conf is the desired configuration. Without the quotes it did not work for me. This is using the same configuration parameters as you use when going into production mode as described here:
https://www.playframework.com/documentation/2.5.x/ProductionConfiguration#Specifying-an-alternate-configuration-file
Important to know is also that config.resource tries to locate the configuration within the conf/ folder, so no need to specify that as well. For full paths not among the resources, use config.file. Further reading is also in the above link.
The quotes need to be used because you do not want to send the -D to activator, but to the run command. Using the quotes, the activator's JVM gets no -D argument but it interprets "run -Dconfig.file=application.conf" and sets the config.file property accordingly, also in the activator's JVM.
This was already discussed here: Activator : Play Framework 2.3.x : run vs. start
Since all the above are partially incorrect, here is my hard wrought knowledge from the last weekend.
Use include "application.conf" not include "application" (which Akka does)
Configs must be named .conf or Play will discard them silently
You probably want -Dconfig.file=<file>.conf so you're not classpath dependent
Make sure your provide the full file path (e.g. /opt/configs/prod.conf)
Example
Here is an example of this we run:
#prod.conf
include "application"
akka.remote.hostname = "prod.blah.com"
# Example of passing in S3 keys
s3.awsAccessKeyId="YOUR_KEY"
s3.awsSecretAccessKey="YOUR_SECRET_KEY"
And just pass it in like so:
activator -Dconfig.file=/var/lib/jenkins/jenkins.conf test
of if you fancy SBT:
sbt -Dconfig.file=/var/lib/jenkins/jenkins.conf test
Dev Environment
Also note it's easy to make a developer.conf file as well, to keep all your passwords/local ports, and then set a .gitignore so dev's don't accidentally check them in.
The below command works with Play 2.5
$ activator -Dconfig.resource=jenkins.conf run
https://www.playframework.com/documentation/2.5.x/ProductionConfiguration
I've had a look around but it's not very clear to me how I can configure a set of environment specific variables for my Play framework application.
As an example, I would like to use an in memory database like h2 for local development but when I move to production or my pre-production environment I would like to be connecting to a postgres database.
How do I configure my app so that it will use the variables relevant to the environment it is being deployed to? This is a Scala Play app.
One option (as documented in the excellent play docs), is to specify conf files during app startup.
Using -Dconfig.resource will search for an alternative configuration file in the application classpath (you usually provide these alternative configuration files into your application conf/ directory before packaging). Play will look into conf/ so you don’t have to add conf/.
$ /path/to/bin/<project-name> -Dconfig.resource=prod.conf
Using -Dconfig.file you can specify an environment specific configuration file not packaged into the application artifacts:
$ start -Dconfig.file=/opt/conf/prod.conf
Using -Dconfig.url you can also specify a configuration file to be loaded from any URL:
$ start -Dconfig.url=http://conf.mycompany.com/conf/prod.conf
Note that you can always reference the original configuration file in a new prod.conf file using the include directive, such as:
include "application.conf"
key.to.override=blah
You can have Puppet or some similar tools to generate the needed parameters in environment.conf and place in a dedicated directory.
Then in application.conf, at the end of the file, have this:
include "file:///[your directory...]/environment.conf"
to override any testing or local values (e.g.DB parameteres) listed above
You can use different configuration files by overriding onLoadConfig method of the Global object like:
object Global extends GlobalSettings {
override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode): Configuration = {
val fileName = s"application.${mode.toString.toLowerCase}.conf"
config ++ Configuration(ConfigFactory.load(fileName))
}
}
This way you have 'application.test.conf' for test mode and 'application.dev.conf' for develop mode whereas you can use another config file in production via '-Dconfig.file' parameter.
At the moment, I'm hardcoding several variables like resource names and ports. I would like to move them out of my code.
What are recommended means of implementing a central configuration outside the actual code? Like a file maybe. So that, while the production and development are using same git repository, the configurations would be seperate. I am using Play 2 Framework on Scala.
I would suggest using the Typesafe Config library. It loads and parses files that can be a mix of .properties style, JSON, or extended JSON (called HOCON - "Human-Optimized Config Object Notation"), and is the configuration style used by Play 2 itself (and Akka, Spray, and a quickly growing list of other libraries).
In Play's standard application.conf file you can include files like so:
include "file:///..."
In this file you could override what properties you need to.
Additionally, (as documented in the excellent play docs), one can specify conf files during app startup like so:
Using -Dconfig.file
You can also specify another local configuration file not packaged into the application artifacts:
$ start -Dconfig.file=/opt/conf/prod.conf
Using -Dconfig.url
You can also specify a configuration file to be loaded from any URL:
$ start -Dconfig.url=http://conf.mycompany.com/conf/prod.conf
Note that you can always reference the original configuration file in a new prod.conf file using the include directive, such as:
include "application.conf"
key.to.override=blah
Configuration is likely a mean of taste, but Typesafe Config is one of the common libraries to use in scala/play ecosystem (e.g. it is used in akka).