apps/posts/main.go 2.3 K raw
1
package main
2
3
import (
4
	"log"
5
	"log/slog"
6
	"net/http"
7
	"os"
8
	"strings"
9
10
	poststorage "github.com/stevedylandev/andromeda/apps/posts/storage"
11
	"github.com/stevedylandev/andromeda/pkg/auth"
12
	"github.com/stevedylandev/andromeda/pkg/config"
13
	"github.com/stevedylandev/andromeda/pkg/sqlite"
14
)
15
16
func main() {
17
	config.LoadDotEnv(".env")
18
	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
19
20
	dbPath := config.Getenv("POSTS_DB_PATH", "posts.sqlite")
21
	db, err := sqlite.Open(dbPath, postsSchema)
22
	if err != nil {
23
		log.Fatal(err)
24
	}
25
	defer db.Close()
26
	if err := runMigrations(db); err != nil {
27
		log.Fatalf("migrations: %v", err)
28
	}
29
	seedDefaultSettings(db)
30
31
	uploadsDir := config.Getenv("UPLOADS_DIR", "uploads")
32
	if err := ensureDir(uploadsDir); err != nil {
33
		log.Fatalf("create uploads dir: %v", err)
34
	}
35
	storageBackend := poststorage.Backend(poststorage.NewLocal(uploadsDir))
36
	if os.Getenv("R2_BUCKET") != "" {
37
		r2, err := poststorage.NewR2(
38
			os.Getenv("R2_ACCOUNT_ID"),
39
			os.Getenv("R2_ACCESS_KEY_ID"),
40
			os.Getenv("R2_SECRET_ACCESS_KEY"),
41
			os.Getenv("R2_BUCKET"),
42
			os.Getenv("R2_PUBLIC_URL"),
43
		)
44
		if err != nil {
45
			log.Fatalf("configure r2: %v", err)
46
		}
47
		storageBackend = r2
48
		logger.Info("using R2 storage backend", "bucket", os.Getenv("R2_BUCKET"))
49
	} else {
50
		logger.Info("using local storage backend", "dir", uploadsDir)
51
	}
52
53
	password := os.Getenv("POSTS_PASSWORD")
54
	if password == "" {
55
		logger.Warn("POSTS_PASSWORD not set, using default 'changeme'")
56
		password = "changeme"
57
	}
58
59
	sessions := &auth.Store{DB: db, CookieName: "session", CookieSecure: config.GetenvBool("COOKIE_SECURE", false)}
60
	if err := sessions.EnsureSchema(); err != nil {
61
		log.Fatal(err)
62
	}
63
	sessions.PruneExpired()
64
65
	tmpl, err := buildTemplates()
66
	if err != nil {
67
		log.Fatal(err)
68
	}
69
	app := &App{
70
		DB:           db,
71
		Log:          logger,
72
		Templates:    tmpl,
73
		Sessions:     sessions,
74
		AppPassword:  password,
75
		CookieSecure: sessions.CookieSecure,
76
		UploadsDir:   uploadsDir,
77
		Storage:      storageBackend,
78
		SiteURL:      strings.TrimRight(config.Getenv("SITE_URL", "http://localhost:3000"), "/"),
79
	}
80
81
	addr := config.Getenv("HOST", "127.0.0.1") + ":" + config.Getenv("PORT", "3000")
82
	logger.Info("posts server running", "addr", addr)
83
	if err := http.ListenAndServe(addr, app.routes()); err != nil {
84
		log.Fatal(err)
85
	}
86
}