With Play 1.2, I can prefix the configuration keys with the framework ID or application mode as follows:
# Production configuration
%prod.http.port=80
%prod.
I have had this question for a long time as well and below is the best approach I've learned so far, I got a hint when asking a similar question on the Play 2 google group.
In you application.config use the following syntax to override a configuration value when a system parameter is present:
# Local machine fallback URI
mongodb.uri="mongodb://192.168.56.101:27017/application"
# Env variable override
mongodb.uri=${?MONGOLAB_URI}
The question mark means that you don't override with the env variable if it is not set. If you just use ${MONGOLAB_URI} you expect the variable to be set and, I assume, you get an exception of some kind if it is not set.
For completeness, here is an example of how you'd read the value:
lazy val mongoUri = current.configuration.getString("mongodb.uri").getOrElse("mongodb:///")
With this approach there is one caveat: make sure you keep your system param configuration in a SCM of some kind.
I'm using this solution:
in application.conf
I've defined the default configurations,
in myUsername.conf
I've included the default configuration and overridden the user specific configuration:
include "application.conf"
logger.application=DEBUG
then in Global.java
I've loaded the user specific configuration (if exists):
public Configuration onLoadConfig(Configuration config, File path,
ClassLoader classloader) {
String username = System.getProperty("user.name");
File confFile = new File(new File(path, "conf"), username + ".conf");
if (confFile.exists()) {
Logger.info("configuration file {} found", confFile.getName());
return new Configuration(ConfigFactory.load(confFile.getName()));
} else {
Logger.info(
"configuration file {} not found, using default application.conf",
confFile.getAbsolutePath());
return null;
}
}
Play 2 doesn't force you to use any particular method to manage your environments. But it provides you with powerful and flexible tools to implement it yourself according to the needs of your project.
For instance a common pattern is keeping common environment settings in one file and having environment-specific overrides in other files. In order to do that you will need a custom Global object (you can put it right into the ./app/Global.scala
). The following code is valid as of Play 2.1.1 (Scala 2.10):
import java.io.File
import play.api._
import com.typesafe.config.ConfigFactory
object Global extends GlobalSettings {
override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode): Configuration = {
val modeSpecificConfig = config ++ Configuration(ConfigFactory.load(s"application.${mode.toString.toLowerCase}.conf"))
super.onLoadConfig(modeSpecificConfig, path, classloader, mode)
}
}
Now you can put application.dev.conf
, application.test.conf
, and application.prod.conf
into your ./conf
with environment specific overrides (while keeping common settings in application.conf
).
In this sample we're relying on the Play's own mode
which usually makes sense, but you can be as granular as you want and use environment variables or whatever you feel like.
See also: Typesafe Config
You have to define a different configuration file with the appropriate properties
http://www.playframework.org/documentation/2.0/Configuration
There is also a inclusion mechanism that helps you define default values in application.conf and overrides only what is needed for production
We just have multiple application.conf files, the default is used during development and we have a prod-applicaton.conf that we simply copy into place when we deploy.
If you want to be indepentent from restrited scala run modes you can use JVM properties. Put modified @coffesnake example to ./app/Global.scala :
import java.io.File
import play.api._
import com.typesafe.config.ConfigFactory
object Global extends GlobalSettings {
override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode): Configuration = {
val environment = System.getProperty("environment")
val environmentSpecificConfig = config ++ Configuration(ConfigFactory.load(s"application.${environment}.conf"))
super.onLoadConfig(environmentSpecificConfig, path, classloader, mode)
}
}
Next run play play
and start app with environment param run -Denvironment=prod-server1
Don't join both command, it doesn't work then
Global configuration will be overrided with environment specific properties from file:
./conf/application.prod-server1.conf
EDIT:
From time perspective I saw this workaround is unnecessary. It is better to use Play build-in config loading mechanism
-Dconfig.file=/etc/play-application/foo-production.conf