Managing application configurations for the Play Framework projects isn’t really straightforward. When you start a new project with Play, you typically have only one application.conf
file with global settings. But then you need to configure the project for different environments, and you begin to create application.dev.conf
, application.test.conf
, application.demo.conf
, and other *.conf
files by copying the global settings from application.conf
to those files and changing necessary options for different environments.
The described approach, however, leads to a couple of problems:
- You repeat the same configurations in many files, which defies the Don’t Repeat Yourself principle.
- You may forget to change an important global setting in some of the configuration files.
The second problem can be especially annoying when you want to run a quick demo, but you didn’t update the configurations for the demo environment, and the application starts working incorrectly or even can’t run due to errors.
We’re going to review a simple way to avoid such situations and to efficiently manage the configurations for your Play Framework projects.
Breaking App Configurations into Smaller Configs
Let’s have a look at a typical application.conf
file you start with when developing a new project based on Play Framework:
# project_name/conf/application.conf
# ...
slick.dbs {
default {
profile = "slick.jdbc.PostgresProfile$"
db {
driver = "org.postgresql.Driver"
url = "jdbc:postgresql://localhost:5432/first_db"
user = "user"
password = "password"
connectionTimeout = 10s
}
}
}
gitlab {
url = "http://local-gitlab.com"
users {
root {
email = "rootgitlab@local-gitlab.com"
password = "password"
}
}
}
play.modules.enabled += "modules.UserModule"
# ...
Code language: PHP (php)
To break the application.conf
into separate files that will contain only specific settings, you can copy-paste the Slick configurations to conf/default/slick.conf
, GitLab configs to conf/default/gitlab.conf
, and so on, and then import these configurations into application.conf
.
For example, the play.modules.conf
file under conf/default/
will look like this:
# project_name/conf/default/play.modules.conf
# ...
play.modules.enabled += "modules.UserModule"
# ...
Code language: PHP (php)
And the conf/
directory will have the following structure:
conf/
├── default/
├── gitlab.conf
├── play.modules.conf
└── slick.conf
└── application.conf
Code language: JavaScript (javascript)
Your application.conf
file will only need to import the concrete configurations from the default/
directory using include
:
# ...
include "default/play.modules.conf"
include "default/slick.conf"
include "default/gitlab.conf"
# ...
Code language: PHP (php)
Creating Development Configuration
You can set up the development environment with the same approach as we described in the previous section. First, you need to create the application.dev.conf
file that will be importing configurations for the development environment.
Next, you need to create the conf/dev/
directory next to conf/default/
and save files with the development settings: dev/slick.conf
and dev/gitlab.conf
.
Finally, include these files into application.dev.conf
:
# ...
include "application.conf"
include "dev/slick.conf"
include "dev/gitlab.conf"
# ...
Code language: PHP (php)
Notice that the application.dev.conf
file first imports the default application configurations from application.conf
and only after that does it import the specific settings from dev/
. Also note that the development configs are included last and, therefore, they overwrite the default settings.
After all the arrangements, the conf/
directory structure looks like this:
conf/
├── default/
├── gitlab.conf
├── play.modules.conf
└── slick.conf
├── dev/
├── gitlab.conf
└── slick.conf
├── application.dev.conf
└── application.conf
Code language: JavaScript (javascript)
Now, to run your project with a specific configuration, just pass an argument — the name of the configuration file — to the -Dconfig.resource
property:
sbt "run -Dconfig.resource=application.dev.conf"
Code language: JavaScript (javascript)
This modular-ish DRY approach that we described will allow you to easily manage and scale settings for development, test, production, and other environments for your Play Framework-based applications.