Overriding server connector config with env variables with dropwizard

StephenNYC picture StephenNYC · May 5, 2014 · Viewed 11.7k times · Source

I have posted this question on dw mailing list but didnt get an answer.

Can I assume the YML format below doesnt work for DW 0.7.0 anymore? (The use of @ char to insert env var)

server:
  applicationConnectors:
    - type: http
      bindHost: @OPENSHIFT_DIY_IP@
      port: @OPENSHIFT_DIY_PORT@

Error:

Malformed YAML at line: 28, column: 17; while scanning for the next token; found character @ '@' that cannot start any token. (Do not use @ for indentation); in 'reader', line 28, column 17: bindHost: @OPENSHIFT_DIY_IP@

So I decided to use this format:

server:
  type: simple
  applicationContextPath: /
  adminContextPath: /admin
  connector:
      type: http
      bindHost: localhost
      port: 8080

And tried to override it via jvm options:

java -Ddw.server.connector.bindHost=$OPENSHIFT_DIY_IP -Ddw.server.connector.port=$OPENSHIFT_DIY_PORT -jar target/myapp.jar server myapp.yml

My local env variables:

OPENSHIFT_DIY_IP=localhost
OPENSHIFT_DIY_PORT=8080

The error I got from this setup:

Exception in thread "main" java.lang.RuntimeException: java.net.SocketException: Unresolved address at org.eclipse.jetty.setuid.SetUIDListener.lifeCycleStarting(SetUIDListener.java:213) ... Caused by: java.net.SocketException: Unresolved address at sun.nio.ch.Net.translateToSocketException(Net.java:157) ... WARN [2014-05-03 20:11:19,412] org.eclipse.jetty.util.component.AbstractLifeCycle: FAILED org.eclipse.jetty.server.Server@91b85: java.lang.RuntimeException: java.net.SocketException: Unresolved address

What am I doing wrong?

Answer

WarFox picture WarFox · Aug 26, 2015

Starting from Dropwizard version 0.8.0, you can access environment variables from the configuration yml file. It also supports setting a default value in case the environment variable is not available. See the docs here.

Example

// put environment variable inside ${}
// use :- operator to provide default value

dbHost: ${DB_HOST}
dbPort: ${DB_PORT:-1234}
// dbPort = 1234, if DB_PORT environment variable has no value

Important Note: For this to work you need to set up a SubstitutingSourceProvider with an EnvironmentVariableSubstitutor.

// Enable variable substitution with environment variables
bootstrap.setConfigurationSourceProvider(
    new SubstitutingSourceProvider(
        bootstrap.getConfigurationSourceProvider(),
        new EnvironmentVariableSubstitutor())
);

Update: 15/Nov/2017 As mentioned by @EFreak in the comments section, new EnvironmentVariableSubstitutor() will throw UndefinedEnvironmentVariableException if the environment variable is not defined, unless you set strict mode to false by using new EnvironmentVariableSubstitutor(false) https://github.com/dropwizard/dropwizard/blob/master/dropwizard-configuration/src/main/java/io/dropwizard/configuration/EnvironmentVariableSubstitutor.java