refac: rethought the complete workflow and deployement flow ; docs etc.

This commit is contained in:
fsylvain committed 2026-09-23 17:36:36 +02:00
1 parent 4a6209a8db
commit 09bd5afa4a
26 files changed
+800 -334

No files matched your search

+109 -37
View File
@@ -3,67 +3,139 @@ package main
import (
"RenewCMS/api"
validator "RenewCMS/api/pkg/validator"
"context"
"errors"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/go-chi/chi/v5"
"github.com/joho/godotenv"
)
var version = "dev"
const (
readHeaderTimeout = 10 * time.Second
readTimeout = 30 * time.Second
writeTimeout = 60 * time.Second
idleTimeout = 120 * time.Second
shutdownTimeout = 10 * time.Second
)
var possibleEnvFileLocations = []string{".env", "../.env"}
var envVarsToLoad = []string{
"HOST",
"PORT",
var requiredEnvVars = []string{
"PUBLIC_URL",
"JWT_SECRET",
"ENVIRONMENT",
"CORS_ALLOWED_ORIGINS",
"DB_FILE",
"UPLOAD_DIR",
"SMTP_EMAIL",
"SMTP_PASSWORD",
"SMTP_HOST",
"SMTP_PORT",
}
var envDefaults = map[string]string{
"ENVIRONMENT": "production",
"PORT": "8080",
"DB_FILE": "./data/renewcms.db",
"UPLOAD_DIR": "./data/uploads",
}
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
initEnvVariables()
container, closeDb := api.InitContainer()
defer closeDatabase(closeDb)
validator.InitValidator()
server := newServer(api.InitRoutes(container))
return serveUntilStopped(server)
}
func initEnvVariables() {
var err error
loadEnvFile()
applyEnvDefaults()
ensureRequiredEnvVars()
}
func loadEnvFile() {
for _, envLocation := range possibleEnvFileLocations {
err = godotenv.Load(envLocation)
if err == nil {
break
if godotenv.Load(envLocation) == nil {
return
}
}
if err != nil {
fmt.Println("WARNING: Could not load any .env file")
}
log.Println("WARNING: Could not load any .env file")
}
for _, envVar := range envVarsToLoad {
if _, ok := os.LookupEnv(envVar); !ok {
func applyEnvDefaults() {
for envVar, value := range envDefaults {
if _, isSet := os.LookupEnv(envVar); !isSet {
_ = os.Setenv(envVar, value)
}
}
}
func ensureRequiredEnvVars() {
for _, envVar := range requiredEnvVars {
if _, isSet := os.LookupEnv(envVar); !isSet {
panic(fmt.Sprintf("Environment variable %s is not set", envVar))
}
}
}
func initServer() *chi.Mux {
initEnvVariables()
container := api.InitContainer()
validator.InitValidator()
return api.InitRoutes(container)
}
func startServer(router *chi.Mux) error {
fmt.Println("Server starting on http://" + os.Getenv("HOST"))
err := http.ListenAndServe(":"+os.Getenv("PORT"), router)
return err
}
func main() {
router := initServer()
err := startServer(router)
if err != nil {
panic(err)
func closeDatabase(closeDb func() error) {
if err := closeDb(); err != nil {
log.Println("error closing database:", err)
}
}
func newServer(handler http.Handler) *http.Server {
return &http.Server{
Addr: ":" + os.Getenv("PORT"),
Handler: handler,
ReadHeaderTimeout: readHeaderTimeout,
ReadTimeout: readTimeout,
WriteTimeout: writeTimeout,
IdleTimeout: idleTimeout,
}
}
func serveUntilStopped(server *http.Server) error {
stopSignal, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
serverErr := make(chan error, 1)
go listen(server, serverErr)
select {
case err := <-serverErr:
return err
case <-stopSignal.Done():
return shutdown(server)
}
}
func listen(server *http.Server, serverErr chan<- error) {
log.Printf("RenewCMS %s (%s) listening on %s, public URL %s", version, os.Getenv("ENVIRONMENT"), server.Addr, os.Getenv("PUBLIC_URL"))
err := server.ListenAndServe()
if errors.Is(err, http.ErrServerClosed) {
err = nil
}
serverErr <- err
}
func shutdown(server *http.Server) error {
log.Println("shutting down...")
ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
defer cancel()
return server.Shutdown(ctx)
}