Prevents Docker disk bloat by adding log rotation (10MB max, 3 files) to all container creation and update paths, auto-pruning dangling images after deploy/remove/update, and a daily maintenance module that cleans build cache and warns on disk thresholds. Saves a deployment manifest in services.json at deploy time so users can restore all their apps after a Docker purge. Adds restore-all and restore-single endpoints that recreate containers, Caddy config, and DNS records from the saved manifests. Adds an hourly log collector and daily digest generator that summarizes errors, warnings, and events across all services into a single human-readable report with guidance on where to investigate. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
163 lines
6.5 KiB
JavaScript
163 lines
6.5 KiB
JavaScript
// DashCaddy Shared Constants
|
|
// Centralizes configuration values used across the application.
|
|
// Edit values here instead of hunting through server.js.
|
|
|
|
// ── App Identity ──────────────────────────────────────────────
|
|
const APP = {
|
|
NAME: 'DashCaddy',
|
|
VERSION: '1.1',
|
|
PORT: 3001,
|
|
USER_AGENTS: {
|
|
PROBE: 'DashCaddy-Probe/1.0',
|
|
API: 'DashCaddy/1.0',
|
|
HEALTH: 'DashCaddy-HealthCheck/1.0',
|
|
},
|
|
DEVICE_IDS: {
|
|
SSO: 'dashcaddy-sso', // Backend auth gate (never invalidates browser token)
|
|
BROWSER: 'dashcaddy-browser', // Browser-side localStorage token
|
|
},
|
|
};
|
|
|
|
// ── Default Ports for Media/Arr Apps ──────────────────────────
|
|
const APP_PORTS = {
|
|
plex: 32400,
|
|
radarr: 7878,
|
|
sonarr: 8989,
|
|
seerr: 5055,
|
|
lidarr: 8686,
|
|
prowlarr: 9696,
|
|
};
|
|
|
|
// Arr service discovery config (used by /api/arr/* endpoints)
|
|
const ARR_SERVICES = {
|
|
plex: { names: ['plex'], port: APP_PORTS.plex, configPath: 'Plex' },
|
|
radarr: { names: ['radarr'], port: APP_PORTS.radarr, configPath: 'radarr' },
|
|
sonarr: { names: ['sonarr'], port: APP_PORTS.sonarr, configPath: 'sonarr' },
|
|
seerr: { names: ['seerr', 'requests'], port: APP_PORTS.seerr, configPath: 'seerr' },
|
|
lidarr: { names: ['lidarr'], port: APP_PORTS.lidarr, configPath: 'lidarr' },
|
|
prowlarr: { names: ['prowlarr'], port: APP_PORTS.prowlarr, configPath: 'prowlarr' },
|
|
};
|
|
|
|
// ── Timeouts (ms) ─────────────────────────────────────────────
|
|
const TIMEOUTS = {
|
|
HTTP_DEFAULT: 5000, // Standard fetch/http timeout
|
|
HTTP_LONG: 10000, // DNS ops, downloads, login requests
|
|
DEPLOY_SETTLE: 3000, // Wait after container start before health check
|
|
CADDY_PRE_RELOAD: 2000, // Pause before Caddy reload
|
|
RETRY_SHORT: 1000, // Short retry delay
|
|
RETRY_MEDIUM: 2000, // Medium retry delay
|
|
SHUTDOWN_GRACE: 5000, // Graceful shutdown window
|
|
SHUTDOWN_ERROR: 1000, // Error shutdown window
|
|
PORT_CHECK: 2000, // TCP port availability check
|
|
};
|
|
|
|
// ── Retry Configuration ───────────────────────────────────────
|
|
const RETRIES = {
|
|
CADDY_RELOAD: 3, // Max attempts to reload Caddy
|
|
};
|
|
|
|
// ── Session / Cache Expiry (ms) ───────────────────────────────
|
|
const SESSION_TTL = {
|
|
IP_SESSION: 30 * 60 * 1000, // 30 min — router IP-based sessions
|
|
COOKIE_SESSION: 30 * 60 * 1000, // 30 min — cookie-based login sessions
|
|
TOKEN_SESSION: 60 * 60 * 1000, // 60 min — JWT/access token sessions (Jellyfin, Plex, etc.)
|
|
FAILED_LOGIN: 5 * 60 * 1000, // 5 min — cooldown after failed login
|
|
DNS_TOKEN: 6 * 60 * 60 * 1000, // 6 hrs — DNS auto-refresh interval
|
|
};
|
|
|
|
// ── Rate Limiting ─────────────────────────────────────────────
|
|
const RATE_LIMITS = {
|
|
GENERAL: {
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
max: 100,
|
|
},
|
|
STRICT: {
|
|
windowMs: 15 * 60 * 1000,
|
|
max: 20,
|
|
},
|
|
TOTP: {
|
|
windowMs: 15 * 60 * 1000,
|
|
max: 10,
|
|
},
|
|
};
|
|
|
|
// ── Caddy ─────────────────────────────────────────────────────
|
|
const CADDY = {
|
|
CONTENT_TYPE: 'text/caddyfile',
|
|
DEFAULT_DNS_PORT: '5380',
|
|
DEFAULT_TTL: 300,
|
|
TTL_MIN: 60,
|
|
TTL_MAX: 86400,
|
|
};
|
|
|
|
// ── Validation Patterns ─────────────────────────────────────────
|
|
const REGEX = {
|
|
SUBDOMAIN: /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/i,
|
|
DOMAIN: /^[a-z0-9]([a-z0-9.-]{0,251}[a-z0-9])?$/i,
|
|
};
|
|
|
|
// ── DNS ─────────────────────────────────────────────────────────
|
|
const DNS_RECORD_TYPES = ['A', 'AAAA', 'CNAME', 'MX', 'TXT', 'NS', 'SRV', 'PTR', 'SOA'];
|
|
|
|
// ── Docker ──────────────────────────────────────────────────────
|
|
const DOCKER = {
|
|
CONTAINER_PREFIX: 'sami-',
|
|
TIMEOUT: 30000, // 30s — timeout for docker pull/create operations
|
|
LOG_CONFIG: {
|
|
Type: 'json-file',
|
|
Config: { 'max-size': '10m', 'max-file': '3' } // 30MB max per container
|
|
},
|
|
MAINTENANCE: {
|
|
INTERVAL: 24 * 60 * 60 * 1000, // 24 hours
|
|
DISK_WARN_GB: 20, // Warn when Docker uses more than 20GB
|
|
},
|
|
DIGEST: {
|
|
COLLECT_INTERVAL: 60 * 60 * 1000, // Hourly log collection
|
|
DIGEST_HOUR: 0, // Generate daily digest at midnight
|
|
MAX_HOURLY_ENTRIES: 24, // Keep 24 hours of hourly summaries
|
|
MAX_DIGEST_FILES: 30, // Keep 30 days of daily digests
|
|
LOG_TAIL: 500, // Lines to fetch per container per hour
|
|
},
|
|
};
|
|
|
|
// ── Emby/Jellyfin Auth Header Builder ─────────────────────────
|
|
function buildMediaAuth(deviceId) {
|
|
return `MediaBrowser Client="${APP.NAME}", Device="${APP.NAME}", DeviceId="${deviceId}", Version="${APP.VERSION}"`;
|
|
}
|
|
|
|
// ── Plex Auth Headers ─────────────────────────────────────────
|
|
const PLEX = {
|
|
AUTH_URL: 'https://plex.tv/users/sign_in.json',
|
|
};
|
|
|
|
// ── Tailscale API ────────────────────────────────────────────
|
|
const TAILSCALE = {
|
|
API_BASE: 'https://api.tailscale.com/api/v2',
|
|
OAUTH_TOKEN_URL: 'https://api.tailscale.com/api/v2/oauth/token',
|
|
};
|
|
|
|
// ── Error Log ─────────────────────────────────────────────────
|
|
const LIMITS = {
|
|
ERROR_LOG_SIZE: 5 * 1024 * 1024, // 5 MB
|
|
BODY_DEFAULT: '1mb',
|
|
BODY_UPLOAD: '10mb',
|
|
};
|
|
|
|
module.exports = {
|
|
APP,
|
|
TAILSCALE,
|
|
APP_PORTS,
|
|
ARR_SERVICES,
|
|
TIMEOUTS,
|
|
RETRIES,
|
|
SESSION_TTL,
|
|
RATE_LIMITS,
|
|
CADDY,
|
|
PLEX,
|
|
LIMITS,
|
|
REGEX,
|
|
DNS_RECORD_TYPES,
|
|
DOCKER,
|
|
buildMediaAuth,
|
|
};
|