Grails Goodness: Using External Configuration Files Per Environment
Grails 3 is build on top of Spring Boot and this adds a lot of the Spring Boot features to our Grails application. For example in Spring Boot we can store configuration properties in an external file. A default Grails application already adds application.yml
in the grails-app/conf
directory. If we want to specify different values for a configuration property for each environment (like development, test and production) we can use environment
section in application.yml
. We know this from previous Grails versions with a Groovy configuration file Config.groovy
. But we can also create different configuration files per environment and set the value for the configuration property in each file. We can use the following naming pattern for the file: application-{env}.yml
or application-{env}.properties
. These files need be in:
- a
config
directory in the directory the application is running from - the root of the directory the application is running from
- in a
/config
package on the classpath - in the root of the classpath
The order is important, because properties defined in the first locations override the properties in the last locations. When we place the files in grails-app/conf
they get on the root of the classpath. We could also use for example src/main/resources/config
to place extra configuration files on the classpath.
Let's see this in action with a simple Grails application. We write an implementation of the CommandLineRunner
interface to show the value of the sample.conf
configuration property when the application starts:
// File: grails-app/init/com/mrhaki/grails/EnvironmentPrinter.groovy
package com.mrhaki.grails
import grails.config.Config
import grails.core.GrailsApplication
import grails.util.Environment
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.CommandLineRunner
import org.springframework.stereotype.Component
@Component
class EnvironmentPrinter implements CommandLineRunner {
@Autowired
GrailsApplication grailsApplication
@Override
void run(final String... args) throws Exception {
println "Running in ${Environment.current.name}"
// Get configuration from GrailsApplication.
final Config configuration = grailsApplication.config
// Get the value for sample.config.
final String sampleConfigValue = configuration.getProperty('sample.config')
// Print to standard out.
println "Value for sample.config configuration property = $sampleConfigValue"
}
}
We define the configuration property in grails-app/conf/application.yml
:
# File: grails-app/conf/application.yml
...
sample:
config: Value from application.yml
...
Next we create a file grails-app/conf/application-development.yml
which should be used when we run our Grails application in development mode:
# File: grails-app/conf/application-development.yml
sample:
config: Value from application-development.yml
Besides YAML format we can also use the plain old properties format files. We create grails-app/conf/application-production.properties
with a value for sample.config
used when Grails runs in production mode:
# File: grails-app/conf/application-production.properties
sample.config = Value from application-production.properties
Finally we add a configuration file for a custom Grails environment:
# File: grails-app/conf/application-custom.yml
sample:
config: Value from application-custom.yml
Now let's run the Grails application with different environments and see what value the sample.config
property has:
$ grails run-app
| Running application...
Running in development
Value for sample.config configuration property = Value from application-development.yml.
...
$ grails -Dgrails.env=custom run-app
| Running application...
Running in custom
Value for sample.config configuration property = Value from application-custom.yml.
...
$ grails prod run-app
| Running application...
Running in production
Value for sample.config configuration property = Value from application-production.properties.
...
Written with Grails 3.0.7.