4.3 Environments

Per Environment Configuration

Grails supports the concept of per environment configuration. The application.yml and application.groovy files in the grails-app/conf directory can use per-environment configuration using either YAML or the syntax provided by ConfigSlurper. As an example consider the following default application.yml definition provided by Grails:

  1. environments:
  2. development:
  3. dataSource:
  4. dbCreate: create-drop
  5. url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
  6. test:
  7. dataSource:
  8. dbCreate: update
  9. url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
  10. production:
  11. dataSource:
  12. dbCreate: update
  13. url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
  14. properties:
  15. jmxEnabled: true
  16. initialSize: 5
  17. ...

The above can be expressed in Groovy syntax in application.groovy as follows:

  1. dataSource {
  2. pooled = false
  3. driverClassName = "org.h2.Driver"
  4. username = "sa"
  5. password = ""
  6. }
  7. environments {
  8. development {
  9. dataSource {
  10. dbCreate = "create-drop"
  11. url = "jdbc:h2:mem:devDb"
  12. }
  13. }
  14. test {
  15. dataSource {
  16. dbCreate = "update"
  17. url = "jdbc:h2:mem:testDb"
  18. }
  19. }
  20. production {
  21. dataSource {
  22. dbCreate = "update"
  23. url = "jdbc:h2:prodDb"
  24. }
  25. }
  26. }

Notice how the common configuration is provided at the top level and then an environments block specifies per environment settings for the dbCreate and url properties of the DataSource.

Packaging and Running for Different Environments

Grails' command line has built in capabilities to execute any command within the context of a specific environment. The format is:

  1. grails <<environment>> <<command name>>

In addition, there are 3 preset environments known to Grails: dev, prod, and test for development, production and test. For example to create a WAR for the test environment you would run:

  1. grails test war

To target other environments you can pass a grails.env variable to any command:

  1. grails -Dgrails.env=UAT run-app

Programmatic Environment Detection

Within your code, such as in a Gant script or a bootstrap class you can detect the environment using the Environment class:

  1. import grails.util.Environment
  2. ...
  3. switch (Environment.current) {
  4. case Environment.DEVELOPMENT:
  5. configureForDevelopment()
  6. break
  7. case Environment.PRODUCTION:
  8. configureForProduction()
  9. break
  10. }

Per Environment Bootstrapping

It’s often desirable to run code when your application starts up on a per-environment basis. To do so you can use the grails-app/init/BootStrap.groovy file’s support for per-environment execution:

  1. def init = { ServletContext ctx ->
  2. environments {
  3. production {
  4. ctx.setAttribute("env", "prod")
  5. }
  6. development {
  7. ctx.setAttribute("env", "dev")
  8. }
  9. }
  10. ctx.setAttribute("foo", "bar")
  11. }

Generic Per Environment Execution

The previous BootStrap example uses the grails.util.Environment class internally to execute. You can also use this class yourself to execute your own environment specific logic:

  1. Environment.executeForCurrentEnvironment {
  2. production {
  3. // do something in production
  4. }
  5. development {
  6. // do something only in development
  7. }
  8. }