ilyakaznacheev / cleanenv

✨Clean and minimalistic environment configuration reader for Golang
MIT License
1.66k stars 115 forks source link

What is the correct location for the config.yml? #115

Closed SPMatthewMcD closed 1 year ago

SPMatthewMcD commented 1 year ago

Thank you for this solution. I implemented it and was running in minutes.

Question: I am running on Linux and for this web service project I have found that my app only reads the config.yml if I launch the service from the same directory as the web service (where the config file resides as well). This works fine: cd \usr\bin\myapp myapp &

This does not work: \usr\bin\myapp\myapp & I am using the recommended code: err := cleanenv.ReadConfig("config.yml", &cfg)

I'd like to be able to start the service in the background and have it read the config from the execution directory. (Or is there a better method? Should I pass the config file location as a cmd line parameter?) Sorry if this is basic, I am new to Linux development.

Thanks again for your help.

SPMatthewMcD commented 1 year ago

Follow up,

I found the Example Simple Example that uses command line argument for the config file location.

The issue I am having is if the config file is not found it bails and does not process my env-default values.

It seems that this line in the readme is incorrect:

if no value was found on the first two steps, the field will be filled with the default value (env-default tag) if it is set.

saddit commented 1 year ago

You had better use this way

wd, err := os.Getwd()
if err != nil {
    panic(err)
}
cleanenv.ReadConfig(filepath.Join(wd, "config.yml"), &cfg)

And if the file couldn't be found, it would be better to handle it by yourself using ReadEnv(&cfg)

SPMatthewMcD commented 1 year ago

Thanks, I'll try that. Any idea why the defaults are not being read in the event the config is not found?

ilyakaznacheev commented 1 year ago

Hey, thanks for the useful question. I'm here to clarify. So the quote

if no value was found on the first two steps, the field will be filled with the default value (env-default tag) if it is set.

means that there is no such value in the file provided, i.e. field is missing. But when a file provided with a command-line parameter is missing, I consider it an error, and I think it should not be silenced.

For example, you run your app in some container as a part of some CD process in Kubernetes, and the config file is attached from the config map to the pod. There is big room for error when the file will be not there at the end. If the library will just ignores the fact, that the file provided is not found, it will be difficult to troubleshoot the resulting state of the application. And this is an example from my own experience.

Generally speaking, I consider such behavior as a bit of "magic" I'm trying to avoid in this library. At least this follows the "fail fast" principle, which I think is appropriate according to the application initialization phase.

Also, you should be able to start the app from any directory and specify the config file from any other directory like that:

go run path/to/application/*.go -config path/to/configuration/file/config.yaml

All OS-specific path resolving logic should work here, like absolute or relative path, etc.