Loading...

September 24, 2015

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:

  1. a config directory in the directory the application is running from
  2. the root of the directory the application is running from
  3. in a /config package on the classpath
  4. 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.