refactor: remove standalone proxies, add Traefik provider with Docker labels

Standalone proxy removal:
- Delete store, API handlers, proxy manager, health monitor, validator, hints
- Delete frontend pages (proxies list, create, edit) and components (ProxyCard, ProxyForm, ProxyFilter, ProxyGroup, ValidationChecklist)
- Remove proxy routes from router, nav items, dashboard references
- Clean up SystemHealthCard to remove proxy section

Traefik provider:
- Add TraefikProvider implementing proxy.Provider via Docker labels
- ContainerLabels() returns traefik.enable, router rule, entrypoints, service port, TLS cert resolver, docker network
- ConfigureRoute() returns router name (labels handle routing at container creation)
- DeleteRoute() is no-op (container removal auto-deregisters)
- Ping() checks Traefik API health (optional)
- Wire ContainerLabels into deployer (executeDeploy + blueGreenDeploy)
- Add Traefik settings: entrypoint, cert_resolver, network, api_url
- Add traefik option to proxy provider selector in settings UI
- Show conditional Traefik config fields
- Add i18n keys (EN + RU)
This commit is contained in:
2026-04-04 22:54:31 +03:00
parent 216bd7e2db
commit 308547a3d7
35 changed files with 237 additions and 2356 deletions
+24 -2
View File
@@ -35,6 +35,10 @@ type settingsRequest struct {
CloudflareAPIToken string `json:"cloudflare_api_token"`
CloudflareZoneID *string `json:"cloudflare_zone_id,omitempty"`
ProxyProvider *string `json:"proxy_provider,omitempty"`
TraefikEntrypoint *string `json:"traefik_entrypoint,omitempty"`
TraefikCertResolver *string `json:"traefik_cert_resolver,omitempty"`
TraefikNetwork *string `json:"traefik_network,omitempty"`
TraefikAPIURL *string `json:"traefik_api_url,omitempty"`
BackupEnabled *bool `json:"backup_enabled,omitempty"`
BackupIntervalHours *int `json:"backup_interval_hours,omitempty"`
BackupRetentionCount *int `json:"backup_retention_count,omitempty"`
@@ -67,6 +71,10 @@ func (s *Server) getSettings(w http.ResponseWriter, r *http.Request) {
"has_cloudflare_api_token": settings.CloudflareAPIToken != "",
"cloudflare_zone_id": settings.CloudflareZoneID,
"proxy_provider": settings.ProxyProvider,
"traefik_entrypoint": settings.TraefikEntrypoint,
"traefik_cert_resolver": settings.TraefikCertResolver,
"traefik_network": settings.TraefikNetwork,
"traefik_api_url": settings.TraefikAPIURL,
"backup_enabled": settings.BackupEnabled,
"backup_interval_hours": settings.BackupIntervalHours,
"backup_retention_count": settings.BackupRetentionCount,
@@ -171,13 +179,27 @@ func (s *Server) updateSettings(w http.ResponseWriter, r *http.Request) {
// Proxy provider setting.
if req.ProxyProvider != nil {
prov := *req.ProxyProvider
if prov != "" && prov != "none" && prov != "npm" {
respondError(w, http.StatusBadRequest, "proxy_provider must be 'none' or 'npm'")
if prov != "" && prov != "none" && prov != "npm" && prov != "traefik" {
respondError(w, http.StatusBadRequest, "proxy_provider must be 'none', 'npm', or 'traefik'")
return
}
updated.ProxyProvider = prov
}
// Traefik provider settings.
if req.TraefikEntrypoint != nil {
updated.TraefikEntrypoint = *req.TraefikEntrypoint
}
if req.TraefikCertResolver != nil {
updated.TraefikCertResolver = *req.TraefikCertResolver
}
if req.TraefikNetwork != nil {
updated.TraefikNetwork = *req.TraefikNetwork
}
if req.TraefikAPIURL != nil {
updated.TraefikAPIURL = *req.TraefikAPIURL
}
// Backup settings.
if req.BackupEnabled != nil {
updated.BackupEnabled = *req.BackupEnabled