feat: deploy modes (--destroy) + HTTPS with Let's Encrypt
This commit is contained in:
parent
29b9f3c159
commit
672653f731
2 changed files with 45 additions and 12 deletions
|
|
@ -3,7 +3,7 @@ server:
|
||||||
host: "0.0.0.0"
|
host: "0.0.0.0"
|
||||||
|
|
||||||
tls:
|
tls:
|
||||||
enabled: false # Flip to true for Let's Encrypt HTTPS
|
enabled: true # ← was false, now true
|
||||||
email: "" # Required when enabled (e.g. admin@nextwks.eu)
|
email: "den@2-4-h.net" # ← Let's Encrypt account email
|
||||||
|
|
||||||
domain: "nextwks.eu" # Base domain for subdomain routing + certs
|
domain: "nextwks.eu" # Base domain for subdomain routing + certs
|
||||||
|
|
|
||||||
53
main.go
53
main.go
|
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
@ -154,7 +153,7 @@ func main() {
|
||||||
boilerplateHandler(w, r)
|
boilerplateHandler(w, r)
|
||||||
})
|
})
|
||||||
|
|
||||||
addr := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)
|
httpAddr := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)
|
||||||
|
|
||||||
if cfg.TLS.Enabled {
|
if cfg.TLS.Enabled {
|
||||||
log.Println("NextWorkspace starting with TLS (certmagic)...")
|
log.Println("NextWorkspace starting with TLS (certmagic)...")
|
||||||
|
|
@ -165,27 +164,61 @@ func main() {
|
||||||
Path: filepath.Join(configDir, "certs"),
|
Path: filepath.Join(configDir, "certs"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Collect domains (from proxies.yaml + bare domain)
|
||||||
var domains []string
|
var domains []string
|
||||||
for subdomain := range proxies.Apps {
|
for subdomain := range proxies.Apps {
|
||||||
domains = append(domains, subdomain+"."+cfg.Domain)
|
domains = append(domains, subdomain+"."+cfg.Domain)
|
||||||
}
|
}
|
||||||
domains = append(domains, cfg.Domain)
|
domains = append(domains, cfg.Domain)
|
||||||
|
|
||||||
|
// Obtain and manage certificates
|
||||||
magic := certmagic.NewDefault()
|
magic := certmagic.NewDefault()
|
||||||
if err := magic.ManageSync(context.Background(), domains); err != nil {
|
if err := magic.ManageSync(context.Background(), domains); err != nil {
|
||||||
log.Fatalf("Failed to manage certificates: %v", err)
|
log.Fatalf("Failed to manage certificates: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfig := magic.TLSConfig()
|
// HTTP redirect handler (on :80)
|
||||||
listener, err := tls.Listen("tcp", addr, tlsConfig)
|
redirectHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if err != nil {
|
target := "https://" + r.Host + r.URL.RequestURI()
|
||||||
log.Fatalf("Failed to start TLS listener: %v", err)
|
http.Redirect(w, r, target, http.StatusMovedPermanently)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Wrap with ACME challenge handler for Let's Encrypt http-01 validation
|
||||||
|
var httpHandler http.Handler = redirectHandler
|
||||||
|
if len(magic.Issuers) > 0 {
|
||||||
|
if ai, ok := magic.Issuers[0].(*certmagic.ACMEIssuer); ok {
|
||||||
|
httpHandler = ai.HTTPChallengeHandler(redirectHandler)
|
||||||
|
log.Println("ACME challenge handler enabled on :80")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("NextWorkspace listening on %s (TLS)", addr)
|
httpServer := &http.Server{
|
||||||
log.Fatal(http.Serve(listener, router))
|
Addr: httpAddr,
|
||||||
|
Handler: httpHandler,
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTPS server with TLS
|
||||||
|
tlsConfig := magic.TLSConfig()
|
||||||
|
tlsConfig.NextProtos = append(tlsConfig.NextProtos, "h2") // HTTP/2 support
|
||||||
|
|
||||||
|
httpsServer := &http.Server{
|
||||||
|
Addr: ":443",
|
||||||
|
Handler: router,
|
||||||
|
TLSConfig: tlsConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start HTTP redirect server
|
||||||
|
go func() {
|
||||||
|
log.Printf("HTTP redirect listening on %s", httpAddr)
|
||||||
|
if err := httpServer.ListenAndServe(); err != nil {
|
||||||
|
log.Fatalf("HTTP server error: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
log.Println("HTTPS listening on :443")
|
||||||
|
log.Fatal(httpsServer.ListenAndServeTLS("", "")) // certmagic provides certs via TLSConfig
|
||||||
} else {
|
} else {
|
||||||
log.Printf("NextWorkspace listening on %s (no TLS)", addr)
|
log.Printf("NextWorkspace listening on %s (no TLS)", httpAddr)
|
||||||
log.Fatal(http.ListenAndServe(addr, router))
|
log.Fatal(http.ListenAndServe(httpAddr, router))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue