Backups are .tar.gz archives of a consistent database snapshot (VACUUM INTO) plus the images folder. They run on a cron schedule, daily at 3:00 by default, and the newest N scheduled ones are kept (7 by default). Manual backups are never pruned. Settings → Backups offers schedule presets or a custom cron expression, retention, "Back up now", and download/delete for each backup. A small built-in parser handles standard 5-field cron syntax with names, ranges, steps and @daily-style shorthands. Backups go to CANON_BACKUP_DIR (default data/backups). Compose mounts a separate canon-backups volume at /backups, overridable with CANON_BACKUP_PATH. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
77 lines
2.1 KiB
Go
77 lines
2.1 KiB
Go
// Package config loads runtime configuration from environment variables.
|
|
package config
|
|
|
|
import (
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Config holds process-level settings. Anything the owner can change from the
|
|
// web UI lives in the database instead (see store.Settings); the API-key
|
|
// fields here only act as overrides when set.
|
|
type Config struct {
|
|
ListenAddr string
|
|
Host string
|
|
Port string
|
|
DataDir string
|
|
BackupDir string
|
|
AdminUsername string
|
|
AdminPassword string
|
|
SecureCookies bool
|
|
TrustProxy bool
|
|
|
|
// Optional overrides for provider credentials. When set, the matching
|
|
// setting is locked in the web UI.
|
|
TMDBKey string
|
|
TVDBKey string
|
|
TVDBPin string
|
|
IGDBClientID string
|
|
IGDBClientSecret string
|
|
}
|
|
|
|
func Load() Config {
|
|
// 0.0.0.0 accepts connections from other devices on the network, not
|
|
// just this machine. Use 127.0.0.1 to keep it local.
|
|
host := env("CANON_HOST", "0.0.0.0")
|
|
port := env("CANON_PORT", "4242")
|
|
dataDir := env("CANON_DATA_DIR", "./data")
|
|
return Config{
|
|
ListenAddr: env("CANON_LISTEN", net.JoinHostPort(host, port)),
|
|
Host: host,
|
|
Port: port,
|
|
DataDir: dataDir,
|
|
BackupDir: env("CANON_BACKUP_DIR", filepath.Join(dataDir, "backups")),
|
|
AdminUsername: env("CANON_ADMIN_USERNAME", ""),
|
|
AdminPassword: env("CANON_ADMIN_PASSWORD", ""),
|
|
SecureCookies: envBool("CANON_SECURE_COOKIES", false),
|
|
TrustProxy: envBool("CANON_TRUST_PROXY", false),
|
|
TMDBKey: env("CANON_TMDB_API_KEY", ""),
|
|
TVDBKey: env("CANON_TVDB_API_KEY", ""),
|
|
TVDBPin: env("CANON_TVDB_PIN", ""),
|
|
IGDBClientID: env("CANON_IGDB_CLIENT_ID", ""),
|
|
IGDBClientSecret: env("CANON_IGDB_CLIENT_SECRET", ""),
|
|
}
|
|
}
|
|
|
|
func env(key, def string) string {
|
|
if v, ok := os.LookupEnv(key); ok && strings.TrimSpace(v) != "" {
|
|
return strings.TrimSpace(v)
|
|
}
|
|
return def
|
|
}
|
|
|
|
func envBool(key string, def bool) bool {
|
|
v, ok := os.LookupEnv(key)
|
|
if !ok {
|
|
return def
|
|
}
|
|
b, err := strconv.ParseBool(strings.TrimSpace(v))
|
|
if err != nil {
|
|
return def
|
|
}
|
|
return b
|
|
}
|