17

I've been reading lately a debate about "Where should properties that depend on the environment be stored?".

The classical way is to have multiple property files, one by environment, and based on an environment variable (DEV, PROD...), you choose where to read them when starting the application (like with Spring profiles).

On the other hand, if you are using a container to deploy your application, it's said that this kind of configuration should come from the environment itself (using environment variables that the application reads), so the image doesn't change between environments.

What are the pros and the cons of each approach? Is there a "best" approach for the container scenario?

  • What makes you think basing yourself on an environment variable to choose a file is not in line with using environment variable so the image doesn't change? (the main drawback is leaving prod credentials in dev and qa containers more than anything) – Tensibai Jan 23 '18 at 19:09
6

Who said that properties files and environment variables where mutually exclusive?

There is a distinction to be made between "where do I store my app configuration?" And "where does my app source it's configuration? "

The most likely outcome is that everyone probably should just keep doing what they are doing with configuration files as a storage mechanism (think long term, persistent state for as long as the environment exists).

However, rather than dropping that configuration file into the application context and letting it run the application should be able to just expect those variables to already be available in the environment when it starts up.

This means you need to have two deployment work flows -

  1. I deploy may application into an environment by going through X change control process and doing Y reviews with Z tool, whatever.
  2. I deploy my environment configuration into an environment by going through A change control process and doing B reviews with C tool, same process, different outcome.

To use an example of managing environment variables as Key Value pairs in a tool like consul, if you are storing configuration files in git then tools like git2consul with handle getting that configuration into the environment when it's updated.

If you have an app that is expecting that there will be config available as a configuration file then you can avoid shipping multiple copies of the configuration file with the app by building a deploy process with something like consul-template which has the capability to turn your consul values back into a file.

0

 The way we do it is we have 3 pieces (or artifacts) for every running application.

  1. The application we are developing. This is the same regardless of environment. To match your example, that will be the Spring application as a jar/war.
  2. The container that will run the application. This is the same regardless of environment. If using Spring Boot, you don't need Tomcat anymore and just the Java runtime. So use the openjdk Docker container.
  3. The configuration that the application needs. This is the only thing that is different across environments. In a Spring app, you'll likely be using a properties file.

The configuration file lives in a separate source control. This used to be Git, but we are now using a SaaS we built called Config, at http://www.configapp.com. Config's core feature is the easy handling of environment specific configuration. To run our application on a new server, we pull the Docker container, the application artifact, and the configuration file for that environment. In the container, we mount the directory where the application and the configuration file is stored, as part of the container run. Our application is the same. Our container/image is the same. Only the configuration file is different.

Regarding configuration file vs environment variables. For the longest time we were using configuration files. When we used PaaS/cloud, we used environment variables. It was extra work if you have a lot of configuration so we ended up using environment variables to determine the correct configuration file. We have one application that turned properties to environment variables, but that's atypical. If we have a company sanctioned centralized configuration server, we use that, otherwise we like the simplicity of configuration files.

So to summarize, we pull app.jar, app.properties, openjdk Docker. Then we run openjdk Docker mounting the location of app.jar and app.properties. The only thing environment specific is app.properties. To easily manage app.properties, regardless of how many property keys, environments, cluster/region instances, we use Config.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.