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"
|
||||
|
||||
tls:
|
||||
enabled: false # Flip to true for Let's Encrypt HTTPS
|
||||
email: "" # Required when enabled (e.g. admin@nextwks.eu)
|
||||
enabled: true # ← was false, now true
|
||||
email: "den@2-4-h.net" # ← Let's Encrypt account email
|
||||
|
||||
domain: "nextwks.eu" # Base domain for subdomain routing + certs
|
||||
|
|
|
|||
53
main.go
53
main.go
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
|
@ -154,7 +153,7 @@ func main() {
|
|||
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 {
|
||||
log.Println("NextWorkspace starting with TLS (certmagic)...")
|
||||
|
|
@ -165,27 +164,61 @@ func main() {
|
|||
Path: filepath.Join(configDir, "certs"),
|
||||
}
|
||||
|
||||
// Collect domains (from proxies.yaml + bare domain)
|
||||
var domains []string
|
||||
for subdomain := range proxies.Apps {
|
||||
domains = append(domains, subdomain+"."+cfg.Domain)
|
||||
}
|
||||
domains = append(domains, cfg.Domain)
|
||||
|
||||
// Obtain and manage certificates
|
||||
magic := certmagic.NewDefault()
|
||||
if err := magic.ManageSync(context.Background(), domains); err != nil {
|
||||
log.Fatalf("Failed to manage certificates: %v", err)
|
||||
}
|
||||
|
||||
tlsConfig := magic.TLSConfig()
|
||||
listener, err := tls.Listen("tcp", addr, tlsConfig)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to start TLS listener: %v", err)
|
||||
// HTTP redirect handler (on :80)
|
||||
redirectHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
target := "https://" + r.Host + r.URL.RequestURI()
|
||||
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)
|
||||
log.Fatal(http.Serve(listener, router))
|
||||
httpServer := &http.Server{
|
||||
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 {
|
||||
log.Printf("NextWorkspace listening on %s (no TLS)", addr)
|
||||
log.Fatal(http.ListenAndServe(addr, router))
|
||||
log.Printf("NextWorkspace listening on %s (no TLS)", httpAddr)
|
||||
log.Fatal(http.ListenAndServe(httpAddr, router))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue