feat: add resilient container restart controls

This commit is contained in:
admin committed 2026-09-07 13:27:27 +02:00
1 parent 1bbb14470c
commit 7bb33e528c
13 files changed
+747 -28

No files matched your search

+24 -1
View File
@@ -9,6 +9,7 @@ import (
"os/signal"
"path/filepath"
"strings"
"sync"
"syscall"
"time"
@@ -66,6 +67,7 @@ func commandForInvocation(arguments []string) string {
}
func run(logger *slog.Logger) error {
startedAt := time.Now()
// Credentials and session data must never inherit a permissive process umask.
syscall.Umask(0o077)
cfg, err := config.Load()
@@ -103,7 +105,22 @@ func run(logger *slog.Logger) error {
logger.Info("removed AAAA records for disabled IPv6", "count", deleted)
}
}
serverUI, err := web.New(cfg, database, cipher, updater, softwareUpdates, logger)
restartRequested := make(chan struct{})
var restartOnce sync.Once
requestRestart := func() {
restartOnce.Do(func() {
// Docker applies restart policies only after a container has stayed up
// long enough to be considered successfully started. Keep very early
// UI requests alive until that safety window has passed.
delay := time.Until(startedAt.Add(11 * time.Second))
if delay > 0 {
time.AfterFunc(delay, func() { close(restartRequested) })
return
}
close(restartRequested)
})
}
serverUI, err := web.New(cfg, database, cipher, updater, softwareUpdates, logger, requestRestart)
if err != nil {
return err
}
@@ -133,6 +150,12 @@ func run(logger *slog.Logger) error {
return err
}
return nil
case <-restartRequested:
logger.Info("container restart requested")
stop()
shutdownCtx, cancel := context.WithTimeout(context.Background(), cfg.ShutdownTimeout)
defer cancel()
return httpServer.Shutdown(shutdownCtx)
case <-appCtx.Done():
logger.Info("shutdown requested")
shutdownCtx, cancel := context.WithTimeout(context.Background(), cfg.ShutdownTimeout)