One option for building is to package the environment-specific properties at build time (for example using maven profiles)
Another option is to set -Denv=production on your production environment, and on startup load the /${env}/config.properties. (spring allows that for example, but it can be done manually)
I’ve used both. The former means no additional environment configuration. The latter allows for using the same build on multiple environments.
The question: any other significant pros/cons, or is it virtually the same which approach will be chosen?
Related: Load environment-specific properties for use with PropertyPlaceholderConfigurer?
In my opinion having different outputs per environment is a major downside, as it means you need to build N copies of the app, run the same build commands N times, etc. It’s too easy to run into mistakes where you gave the “dev” version to the QA site, etc.
There’s a bit of a third option in between which I am a fan of – storing the configuration values on the servers themselves, separate from the application, and the application then either is written to know where to find these configuration files or you have some sort of script which “re-configures” the app by replacing tokens in it’s configuration files with the canonical values from the external files.
This way you can ship the same binary for all environments, and the external configurations can easily be placed under source control (for example, one file per environment) so changes can be audited, changes can be propagated automatically, etc.
This is also a convenient option if you work in a large organization where the developers are separate from the group that “operates” the application or is responsible for the different environments – since with this method, developers can know what to configure, but the other group is responsible for what configuration values to supply on each host.