Open lr638638 opened 1 year ago
👋 Thanks for reporting!
A maintainer will take a look at your issue shortly. 👀
In the meantime: We are working on Viper v2 and we would love to hear your thoughts about what you like or don't like about Viper, so we can improve or fix those issues.
⏰ If you have a couple minutes, please take some time and share your thoughts: https://forms.gle/R6faU74qPRPAzchZ9
📣 If you've already given us your feedback, you can still help by spreading the news, either by sharing the above link or telling people about this on Twitter:
https://twitter.com/sagikazarmark/status/1306904078967074816
Thank you! ❤️
This issue is a confluence of some choices viper has made along with the behaviour of docker. The choice viper made was to watch folders and not specific config files in viper.go
configFile := filepath.Clean(filename)
configDir, _ := filepath.Split(configFile)
realConfigFile, _ := filepath.EvalSymlinks(filename)
...
watcher.Add(configDir)
Inside a docker container where you ONLY mount a file, not a folder
docker run -it --rm -v /etc/config.json:/etc/config/config.json container
folder based inotify
events are NOT triggered for folder /etc/config
when config.json
is changed (assuming that /etc/config
already exists in the container). You can fairly trivially observe this by compiling up the code below and running against a docker container
package main
import (
"log"
"os"
"github.com/fsnotify/fsnotify"
)
func main() {
// Create new watcher.
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()
// Start listening for events.
go func() {
for {
select {
case event, _ := <-watcher.Events:
log.Println("event:", event)
case err, _ := <-watcher.Errors:
log.Println("error:", err)
}
}
}()
log.Println("Watching: " + os.Args[1])
err = watcher.Add(os.Args[1])
if err != nil {
log.Fatal(err)
}
// Block main goroutine forever.
<-make(chan struct{})
}
Building this into a docker container
FROM ubuntu
COPY fsnotify-test /fsnotify-test
ENTRYPOINT ["/fsnotify-test"]
And running it against files and folders will show the difference. First cross-mount test
as a file, watch it directly and on the host touch test
once the container is running.
$ docker run -it --rm -v ./test:/test fsnotify-test /test
2023/11/22 14:51:14 Watching: /test
2023/11/22 14:52:46 event: CHMOD "/test"
Now watch /
rather than the file specifically and touch test
$ docker run -it --rm -v ./test:/test fsnotify-test /
2023/11/22 14:53:37 Watching: /
No notification.
Finally, cross-mount whole folder and watch whole folder, and touch test
$ docker run -it --rm -v ./:/config/ fsnotify-test /config
2023/11/22 14:54:55 Watching: /config
2023/11/22 14:54:59 event: CHMOD "/config/test"
@lr638638 This allows a temporary workaround to your issue which is to ensure that in a docker container you mount whole folders with your config in and not just a single file. If you do this you will see the modifications to the config files.
However, for viper, it would either be good to document that it ONLY really supports whole folder watching inside docker container (where many of your users will end up), or consider revisiting the choices in WatchConfig
and perhaps watching the specific files that you know hold the config rather than the folders.
Preflight Checklist
Viper Version
1.8.1
Go Version
1.16
Config Source
Files
Format
JSON
Repl.it link
No response
Code reproducing the issue
No response
Expected Behavior
My programs is running in docker (Docker version 19.03.5, build 633a0ea838)
docker run -it -v /etc/config.json:/etc/config/config.json
have add the code as bellow: c.Viper.OnConfigChange(func(e fsnotify.Event) { fmt.Println("abc:OnConfigChange") c.Update() }) c.Viper.WatchConfig()
modify /etc/config.json in local host
can't print log "abc:OnConfigChange"
modify the codes in viper.go:498 watcher.Add(configDir) watcher.Add(configFile) //add by me
Do step 1 and 3 again
print the log "abc:OnConfigChange"
It's have bug when the config file volume mount in docker.
Actual Behavior
My programs is running in docker (Docker version 19.03.5, build 633a0ea838)
docker run -it -v /etc/config.json:/etc/config/config.json
have add the code as bellow: c.Viper.OnConfigChange(func(e fsnotify.Event) { fmt.Println("abc:OnConfigChange") c.Update() }) c.Viper.WatchConfig()
modify /etc/config.json in local host
can't print log "abc:OnConfigChange"
modify the codes in viper.go:498 watcher.Add(configDir) watcher.Add(configFile) //add by me
Do step 1 and 3 again
print the log "abc:OnConfigChange"
It's have bug when the config file volume mount in docker.
Steps To Reproduce
My programs is running in docker (Docker version 19.03.5, build 633a0ea838)
docker run -it -v /etc/config.json:/etc/config/config.json
have add the code as bellow: c.Viper.OnConfigChange(func(e fsnotify.Event) { fmt.Println("abc:OnConfigChange") c.Update() }) c.Viper.WatchConfig()
modify /etc/config.json in local host
can't print log "abc:OnConfigChange"
modify the codes in viper.go:498 watcher.Add(configDir) watcher.Add(configFile) //add by me
Do step 1 and 3 again
print the log "abc:OnConfigChange"
It's have bug when the config file volume mount in docker.
Additional Information
My programs is running in docker (Docker version 19.03.5, build 633a0ea838)
docker run -it -v /etc/config.json:/etc/config/config.json
have add the code as bellow: c.Viper.OnConfigChange(func(e fsnotify.Event) { fmt.Println("abc:OnConfigChange") c.Update() }) c.Viper.WatchConfig()
modify /etc/config.json in local host
can't print log "abc:OnConfigChange"
modify the codes in viper.go:498 watcher.Add(configDir) watcher.Add(configFile) //add by me
Do step 1 and 3 again
print the log "abc:OnConfigChange"
It's have bug when the config file volume mount in docker.