app/ui: handle unspecified bind addresses and wait for server in ollama proxy (#13159)

This commit is contained in:
Eva H 2025-12-15 13:33:09 -05:00 committed by GitHub
parent abe67acf8a
commit 8dbc9e7b68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 54 additions and 28 deletions

View File

@ -12,13 +12,13 @@ import (
"log/slog" "log/slog"
"net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"net/url"
"os" "os"
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"slices" "slices"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
@ -117,40 +117,66 @@ func (s *Server) log() *slog.Logger {
// ollamaProxy creates a reverse proxy handler to the Ollama server // ollamaProxy creates a reverse proxy handler to the Ollama server
func (s *Server) ollamaProxy() http.Handler { func (s *Server) ollamaProxy() http.Handler {
ollamaHost := os.Getenv("OLLAMA_HOST") var (
if ollamaHost == "" { proxy http.Handler
ollamaHost = "http://127.0.0.1:11434" proxyMu sync.Mutex
} )
if !strings.HasPrefix(ollamaHost, "http://") && !strings.HasPrefix(ollamaHost, "https://") { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ollamaHost = "http://" + ollamaHost proxyMu.Lock()
} p := proxy
proxyMu.Unlock()
target, err := url.Parse(ollamaHost) if p == nil {
if err != nil { proxyMu.Lock()
s.log().Error("failed to parse OLLAMA_HOST", "error", err, "host", ollamaHost) if proxy == nil {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var err error
http.Error(w, "failed to configure proxy", http.StatusInternalServerError) for i := range 2 {
}) if i > 0 {
} s.log().Warn("ollama server not ready, retrying", "attempt", i+1)
time.Sleep(1 * time.Second)
}
s.log().Info("configuring ollama proxy", "target", target.String()) err = WaitForServer(context.Background(), 10*time.Second)
if err == nil {
break
}
}
proxy := httputil.NewSingleHostReverseProxy(target) if err != nil {
proxyMu.Unlock()
s.log().Error("ollama server not ready after retries", "error", err)
http.Error(w, "Ollama server is not ready", http.StatusServiceUnavailable)
return
}
originalDirector := proxy.Director target := envconfig.Host()
proxy.Director = func(req *http.Request) { s.log().Info("configuring ollama proxy", "target", target.String())
originalDirector(req)
req.Host = target.Host
s.log().Debug("proxying request", "method", req.Method, "path", req.URL.Path, "target", target.Host)
}
proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) { newProxy := httputil.NewSingleHostReverseProxy(target)
s.log().Error("proxy error", "error", err, "path", r.URL.Path, "target", target.String())
http.Error(w, "proxy error: "+err.Error(), http.StatusBadGateway)
}
return proxy originalDirector := newProxy.Director
newProxy.Director = func(req *http.Request) {
originalDirector(req)
req.Host = target.Host
s.log().Debug("proxying request", "method", req.Method, "path", req.URL.Path, "target", target.Host)
}
newProxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
s.log().Error("proxy error", "error", err, "path", r.URL.Path, "target", target.String())
http.Error(w, "proxy error: "+err.Error(), http.StatusBadGateway)
}
proxy = newProxy
p = newProxy
} else {
p = proxy
}
proxyMu.Unlock()
}
p.ServeHTTP(w, r)
})
} }
type errHandlerFunc func(http.ResponseWriter, *http.Request) error type errHandlerFunc func(http.ResponseWriter, *http.Request) error