v0.327.1: files.<domain> reaches FileBrowser again — a file route by name, not Docker labels
gates / gates (push) Successful in 43s

v0.327.0's box walk: files.<domain> timed out on demo-hp and the N100. With labels, Traefik kept the address it chose at
container start (on felhom-filebrowser, before the gate joined traefik-public). FileBrowser now carries no Traefik
labels; dynamic/filebrowser.yml routes files.<domain> to http://filebrowser:80 by name, resolved per connection and
only while the gate keeps it on traefik-public. Test extended, red-proved.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-17 13:56:45 +02:00
parent 0c6ce9500c
commit 71fbef6bbe
5 changed files with 85 additions and 15 deletions
+27
View File
@@ -77,6 +77,11 @@ func (m *Manager) EnsureBaseStack() error {
if err := m.wireController(traefikDir); err != nil {
errs = append(errs, fmt.Sprintf("controller-route: %v", err))
}
// R-1126 (v0.327.1): files.<domain> as a file-provider route by NAME — published only while the gate keeps
// FileBrowser on traefik-public.
if err := m.ensureFileBrowserRoute(traefikDir); err != nil {
errs = append(errs, fmt.Sprintf("filebrowser-route: %v", err))
}
if m.cfg.Infrastructure.CFTunnelToken != "" {
// cloudflared moves to the tunnel network only once traefik is on it (it reaches traefik by name there); while
@@ -279,6 +284,28 @@ func (m *Manager) ensureFileBrowser(dir string) error {
return m.composeUp(dir)
}
// ensureFileBrowserRoute writes traefik's dynamic route for files.<domain> (infra.RenderFileBrowserRoute), only when its
// content changes, like wireController. No domain → nothing (no route without a name to serve).
func (m *Manager) ensureFileBrowserRoute(traefikDir string) error {
domain := m.cfg.Customer.Domain
if domain == "" {
return nil
}
dynDir := filepath.Join(traefikDir, "dynamic")
if err := os.MkdirAll(dynDir, 0o755); err != nil {
return fmt.Errorf("mkdir dynamic: %w", err)
}
path := filepath.Join(dynDir, "filebrowser.yml")
want := infra.RenderFileBrowserRoute(domain)
if cur, err := os.ReadFile(path); err != nil || string(cur) != want {
if err := os.WriteFile(path, []byte(want), 0o644); err != nil {
return fmt.Errorf("write filebrowser route: %w", err)
}
m.logger.Printf("[INFO] [infra] wrote filebrowser route → %s (Host files.%s → filebrowser:80 by name, R-1126)", path, domain)
}
return nil
}
// ensureServersTransports writes the traefik file-provider dynamic config defining named backend
// transports (the insecure-skip-verify transport for self-signed HTTPS backends like Crafty). Like
// wireController, it writes only when the content changes so the traefik file watcher doesn't reload