forked from Eful97/Pictorium
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
160 lines (152 loc) · 9 KB
/
Copy pathdocker-compose.yml
File metadata and controls
160 lines (152 loc) · 9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
services:
pictorium:
build:
context: .
dockerfile: Dockerfile
image: eful97/pictorium:latest
container_name: pictorium
restart: unless-stopped
ports:
# Host bind/porta configurabili (default 0.0.0.0:8080). La porta interna
# resta 8080 (PORT/HOSTNAME sotto + healthcheck): cambia solo l'esposizione.
- "${PICTORIUM_BIND_IP:-0.0.0.0}:${PICTORIUM_HOST_PORT:-8080}:8080"
environment:
# ── Chiavi API ──
# Priorità: header `x-api-key` > query `api_key`/`mdblist_key` > fallback
# d'istanza qui sotto (opt-in, vedi resolveRequestApiKey in src/lib/tmdb.ts).
# Il fallback d'istanza è per deploy personali single-user; su istanze
# pubbliche multi-utente NON impostarlo (ogni richiesta porta la sua chiave).
# Consigliato per integratori: TMDB per-utente + MDBList d'istanza
# (il mdblist_key per-richiesta frammenta la cache poster) — docs/INTEGRATION.md.
- PICTORIUM_TMDB_KEY=${PICTORIUM_TMDB_KEY:-${POSTERIUM_TMDB_KEY:-}}
- PICTORIUM_MDBLIST_KEY=${PICTORIUM_MDBLIST_KEY:-${POSTERIUM_MDBLIST_KEY:-}}
- PICTORIUM_TVDB_API_KEY=${PICTORIUM_TVDB_API_KEY:-${POSTERIUM_TVDB_API_KEY:-}}
# ── Custom Rating Provider ──
# Endpoint/header configurabili anche dall'editor (vince sul qui sotto);
# la chiave resta SEMPRE env (mai in UI/token/URL).
- PICTORIUM_CUSTOM_RATING_ENABLED=${PICTORIUM_CUSTOM_RATING_ENABLED:-${POSTERIUM_CUSTOM_RATING_ENABLED:-}}
- PICTORIUM_CUSTOM_RATING_ENDPOINT=${PICTORIUM_CUSTOM_RATING_ENDPOINT:-${POSTERIUM_CUSTOM_RATING_ENDPOINT:-}}
- PICTORIUM_CUSTOM_RATING_API_KEY=${PICTORIUM_CUSTOM_RATING_API_KEY:-${POSTERIUM_CUSTOM_RATING_API_KEY:-}}
- PICTORIUM_CUSTOM_RATING_API_KEY_HEADER=${PICTORIUM_CUSTOM_RATING_API_KEY_HEADER:-${POSTERIUM_CUSTOM_RATING_API_KEY_HEADER:-}}
- PICTORIUM_CUSTOM_RATINGS=${PICTORIUM_CUSTOM_RATINGS:-${POSTERIUM_CUSTOM_RATINGS:-}}
# ── Opzionali — Multi-utente (istanza pubblica per-UUID) ──
# PICTORIUM_MULTI_USER=1 abilita mapping/default/chiavi per UUID
# (POST /api/users, gestione su /u/<uuid>/configure). Default off =
# single-user invariato. PROFILE_ENCRYPTION_KEY obbligatoria con flag
# ON (fail-closed sul salvataggio chiavi); retention cleanup inattivi
# (0 = mai). Quota poster per UUID via MAX_MAPPINGS, cap namespace via
# MAX_USERS. Con flag ON le richieste scoped (?u=) NON usano le chiavi
# d'istanza (mai open-proxy sulla quota operatore) salvo
# MULTI_USER_ALLOW_ENV_FALLBACK=1.
- PICTORIUM_MULTI_USER=${PICTORIUM_MULTI_USER:-}
- PICTORIUM_MAX_MAPPINGS_PER_USER=${PICTORIUM_MAX_MAPPINGS_PER_USER:-}
- PICTORIUM_MAX_USERS=${PICTORIUM_MAX_USERS:-}
- PICTORIUM_MULTI_USER_ALLOW_ENV_FALLBACK=${PICTORIUM_MULTI_USER_ALLOW_ENV_FALLBACK:-}
- PICTORIUM_USER_RETENTION_DAYS=${PICTORIUM_USER_RETENTION_DAYS:-}
# ── Opzionali — Admin & Sicurezza ──
# PUBLIC_INSTANCE=1: route admin aperte senza token (LAN fidata/demo).
# Su istanze esposte lascia vuoto/0 + ADMIN_TOKEN, poi incolla il token
# in Impostazioni → Token admin (solo sessione) per usare la UI.
# Senza entrambi, l'editor resta chiuso (fail-closed); gli endpoint
# poster/cataloghi restano sempre aperti.
- PICTORIUM_PUBLIC_INSTANCE=${PICTORIUM_PUBLIC_INSTANCE:-}
- PICTORIUM_ADMIN_TOKEN=${PICTORIUM_ADMIN_TOKEN:-${POSTERIUM_ADMIN_TOKEN:-}}
- POSTERIUM_ADMIN_TOKEN=${POSTERIUM_ADMIN_TOKEN:-}
# Token warmup: l'app/entrypoint leggono PICTORIUM_/POSTERIUM_WARMUP_TOKEN
# (il vecchio WARMUP_TOKEN senza prefisso non è mai letto).
- PICTORIUM_WARMUP_TOKEN=${PICTORIUM_WARMUP_TOKEN:-${POSTERIUM_WARMUP_TOKEN:-}}
- POSTERIUM_WARMUP_TOKEN=${POSTERIUM_WARMUP_TOKEN:-}
# Firma dei config token URL (CONFIG_HMAC_SECRET). Senza, i token non sono firmati.
- CONFIG_HMAC_SECRET=${CONFIG_HMAC_SECRET:-}
# Cifratura AES-256-GCM delle apiKeys dei profili cloud (openssl rand -hex 32).
# Senza, le chiavi dei profili restano in chiaro a riposo (warning in prod).
- PROFILE_ENCRYPTION_KEY=${PROFILE_ENCRYPTION_KEY:-}
# Proxy fidato (dietro Cloudflare/Caddy/Nginx) e allowlist host pubblici
- PICTORIUM_TRUST_PROXY=${PICTORIUM_TRUST_PROXY:-${POSTERIUM_TRUST_PROXY:-}}
- PICTORIUM_ALLOWED_HOSTS=${PICTORIUM_ALLOWED_HOSTS:-${POSTERIUM_ALLOWED_HOSTS:-}}
# Banner sponsor hosting pubblico (es. "elfhosted"; vuoto = nessun banner).
- PICTORIUM_HOSTED_BY=${PICTORIUM_HOSTED_BY:-}
# ── Opzionali — Persistenza distribuita ──
# Redis nativo (TCP) per HA multi-replica senza /data: PICTORIUM_REDIS_URL
# vince su KV_REST_* (log warn, nessuna migrazione automatica). Su ElfHosted
# basta REDIS_URL (fallback nudo supportato). Senza nessuno dei due resta il
# volume /data sotto.
- PICTORIUM_REDIS_URL=${PICTORIUM_REDIS_URL:-${REDIS_URL:-}}
- KV_REST_API_URL=${KV_REST_API_URL:-}
- KV_REST_API_TOKEN=${KV_REST_API_TOKEN:-}
# ── Opzionali — Cache ──
- PICTORIUM_CACHE_MAX=${PICTORIUM_CACHE_MAX:-${POSTERIUM_CACHE_MAX:-2000}}
- POSTERIUM_CACHE_MAX=${POSTERIUM_CACHE_MAX:-2000}
- PICTORIUM_CACHE_MAX_MB=${PICTORIUM_CACHE_MAX_MB:-${POSTERIUM_CACHE_MAX_MB:-150}}
- POSTERIUM_CACHE_MAX_MB=${POSTERIUM_CACHE_MAX_MB:-150}
- PICTORIUM_CACHE_REFRESH_HOUR=${PICTORIUM_CACHE_REFRESH_HOUR:-${POSTERIUM_CACHE_REFRESH_HOUR:-3}}
- POSTERIUM_CACHE_REFRESH_HOUR=${POSTERIUM_CACHE_REFRESH_HOUR:-3}
# Byte-cache immagini TMDB e attesa rating: vuoti = default del codice
# (32MB / 1500ms). Su VPS con RAM alzare IMG a 128.
- PICTORIUM_IMG_CACHE_MB=${PICTORIUM_IMG_CACHE_MB:-}
- PICTORIUM_RATING_WAIT_MS=${PICTORIUM_RATING_WAIT_MS:-}
# Candidati clean del best-fit: vuoto = 16 (default del codice).
- PICTORIUM_AUTO_FIT_CANDIDATE_COUNT=${PICTORIUM_AUTO_FIT_CANDIDATE_COUNT:-}
# ── Opzionali — Render pipeline (tuning performance) ──
# Default tarati per il limite 512MB sotto. Su istanze con più RAM alza
# PICTORIUM_MAX_CONCURRENT_RENDERS (es. 8) e la cache per più poster/s
# sulle griglie fredde — vedi README "Tuning performance".
- PICTORIUM_MAX_CONCURRENT_RENDERS=${PICTORIUM_MAX_CONCURRENT_RENDERS:-${POSTERIUM_MAX_CONCURRENT_RENDERS:-4}}
- POSTERIUM_MAX_CONCURRENT_RENDERS=${POSTERIUM_MAX_CONCURRENT_RENDERS:-4}
- PICTORIUM_RENDER_SLOT_WAIT_MS=${PICTORIUM_RENDER_SLOT_WAIT_MS:-${POSTERIUM_RENDER_SLOT_WAIT_MS:-15000}}
- POSTERIUM_RENDER_SLOT_WAIT_MS=${POSTERIUM_RENDER_SLOT_WAIT_MS:-15000}
- PICTORIUM_RENDER_TIMEOUT_MS=${PICTORIUM_RENDER_TIMEOUT_MS:-${POSTERIUM_RENDER_TIMEOUT_MS:-30000}}
- POSTERIUM_RENDER_TIMEOUT_MS=${POSTERIUM_RENDER_TIMEOUT_MS:-30000}
# ── Opzionali — Sharp (ottimizzazione CPU/RAM) ──
- SHARP_CONCURRENCY=${SHARP_CONCURRENCY:-2}
- SHARP_CACHE_MEMORY_MB=${SHARP_CACHE_MEMORY_MB:-64}
# ── Opzionali — Logging ──
- PICTORIUM_LOG_LEVEL=${PICTORIUM_LOG_LEVEL:-${POSTERIUM_LOG_LEVEL:-info}}
- POSTERIUM_LOG_LEVEL=${POSTERIUM_LOG_LEVEL:-info}
- PICTORIUM_LOG_FORMAT=${PICTORIUM_LOG_FORMAT:-${POSTERIUM_LOG_FORMAT:-}}
- POSTERIUM_LOG_FORMAT=${POSTERIUM_LOG_FORMAT:-}
# ── Opzionali — CDN ──
- POSTER_CDN_URL=${POSTER_CDN_URL:-}
- NEXT_PUBLIC_POSTER_CDN_URL=${NEXT_PUBLIC_POSTER_CDN_URL:-}
# ── Runtime ──
- NODE_ENV=production
# Heap JS: default 384 (tarato per il limite 512MB sotto). Su VPS con
# più RAM alzarlo via PICTORIUM_NODE_OLD_SPACE (es. 2048 con limite 3g).
- NODE_OPTIONS=--max-old-space-size=${PICTORIUM_NODE_OLD_SPACE:-384}
- PORT=8080
- HOSTNAME=0.0.0.0
# Self-warmup post-boot (default 1): 0 per saltarlo.
- PICTORIUM_SELF_WARMUP=${PICTORIUM_SELF_WARMUP:-${POSTERIUM_SELF_WARMUP:-}}
# Hardening: il container gira come utente non-root (uid 1000) e senza
# capability aggiuntive; niente escalation di privilegi.
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
volumes:
# Nome volume legacy (posterium-*) tenuto per non orfanare i /data esistenti.
# Non rinominarlo tra un recreate e l'altro: nomi diversi = volumi diversi
# (lo storage sembrerebbe vuoto/"0 poster"). Deve restare scrivibile da uid 1000.
- posterium-data:/data
healthcheck:
test: ["CMD", "node", "-e", "fetch('http://localhost:8080/api/health?probe=1').then(r => r.ok ? process.exit(0) : process.exit(1)).catch(() => process.exit(1))"]
interval: 30s
timeout: 5s
start_period: 15s
retries: 3
# Rotation dei log json-file: senza limiti crescono senza bound su
# istanze long-running (livello info logga ogni render best-fit).
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"
deploy:
resources:
limits:
memory: ${PICTORIUM_MEM_LIMIT:-512M}
reservations:
memory: ${PICTORIUM_MEM_RESERVATION:-256M}
volumes:
posterium-data:
driver: local