One thing I never appreciated until I ran the same jar across dev, staging, and prod is how much of "config pain" is really "config layering pain." Where does a value come from? Which file wins? How do I keep a database password out of Git without wrapping the whole thing in a secrets manager on day one?

Solon has a pretty clean answer to all of this, and it fits in your head. Here's the mental model I use.

The main config file and environment switching

Your application config lives at resources/app.yml (or app.properties). It always loads. That's the base.

Environment-specific files sit next to it with an app-{env} name: