Files
SnapOtter/apps/docs/it/guide/low-resource.md
T
SnapOtterandGitHub d10d0f544f fix: release QA hardening across processing, media, security, and CI gates (#649)
A release-readiness QA pass over the whole product. The commits split into
defects a user would hit and gates that were reporting green while measuring
nothing.

## Fixes that change behaviour

Rate limiting was bypassable on every install: TRUST_PROXY defaulted to true, so
request.ip came from a client-set header and a forged X-Forwarded-For got past
the login limiter. The default is now a private-network trust list.

A transient Postgres outage stranded in-flight jobs, leaving finished output on
disk with no row pointing at it. A reconciler now resolves those rows and adopts
the bytes rather than dropping the work.

A Redis connection that moved to a new address wedged every read-blocked
consumer, so completions stopped signalling while health still answered 200.
Socket timeouts plus subscriber pings recover it.

Installing more than one AI bundle left the shared venv multi-versioned and
silently broke three tools. The installer now reconciles distributions to one
version each.

Converting an image to JXL at quality 1 through 4 returned a 500, because
libjxl 0.7 rejects the distance those values compute. The quality is floored at
what the encoder honours. A missing ffmpeg was also reported to the user as a
corrupt upload; it now says the engine is unavailable.

RAW uploads reached an unpatched LibRaw on arm64, so it is built from source at
0.22.2, and the release scan was split so it can fail on an unfixed critical
instead of hiding it behind ignore-unfixed.

## Gates that could not fail

Two mutation lanes ran zero mutants because Stryker crawled the gitignored docs
build; coverage discarded its whole report on any failing test; the lint gate
skipped root tests, scripts, and two workspaces; and several generated matrices
counted a host missing ffmpeg as a passing tool. Each now measures what it
claims.

Full evidence and the outstanding release items are tracked locally and are not
part of this branch.
2026-07-27 15:37:30 +08:00

6.8 KiB

i18n_source_hash, i18n_provenance, i18n_output_hash, i18n_hash_version
i18n_source_hash i18n_provenance i18n_output_hash i18n_hash_version
521c03a6416c machine 09c689ff490a 2

Configurazioni a basse risorse

SnapOtter funziona bene su hardware modesto: un Raspberry Pi 4 o 5, un vecchio laptop o un VPS da 2 GB. Questa pagina è la guida pratica per quelle macchine: cosa aspettarsi, una configurazione copia-incolla con limiti ragionevoli e quali funzionalità saltare. I dati completi dei benchmark dietro questi numeri si trovano in Requisiti hardware.

Due vincoli rigidi da subito:

  • Solo a 64 bit. L'immagine viene creata per linux/amd64 e linux/arm64. ARM a 32 bit (armv7/armhf) non è supportato, quindi i Pi di prima generazione e la famiglia Pi Zero sono esclusi.
  • Soglia minima di memoria: 2 GB. Con 512 MB lo stack non si avvia nemmeno, e 1 GB fallisce sui batch multi-file. 2 GB con 2 core è la configurazione più piccola che funziona comodamente.

Cosa funziona bene su hardware modesto

Ogni strumento non AI funziona su una macchina da 2 GB / 2 core: le intere sezioni Immagine e File, gli strumenti PDF e le operazioni video e audio in stream-copy (taglio, silenziamento, remux del container). La maggior parte termina in meno di un secondo.

Due carichi di lavoro fanno eccezione:

  • La ricodifica video (conversione tra codec) è vincolata alla CPU. Una clip 1080p che richiede ~40 s su una CPU desktop veloce può richiedere diversi minuti su una CPU di classe Pi. Le operazioni in stream-copy restano istantanee.
  • Gli strumenti AI hanno bisogno di RAM (4 GB consigliati) e di disco (i bundle più grandi pesano 4-5 GB ciascuno), e quelli pesanti (upscaling, ripristino foto, rimozione dello sfondo) non sono praticabili su CPU di classe Pi. L'AI leggera come il rilevamento dei volti e l'OCR è utilizzabile se hai la memoria necessaria.

Nessuno dei due è installato o in esecuzione finché non lo usi: senza bundle AI installati l'app a riposo occupa circa 360 MB, e i bundle AI vengono scaricati solo quando un amministratore li abilita.

Guida passo passo per Raspberry Pi / vecchio laptop

Questa è l'installazione Compose standard di Per iniziare, più limiti di risorse e tetti prudenti. Presuppone un sistema operativo a 64 bit (su un Pi: Raspberry Pi OS 64-bit o Ubuntu Server arm64).

services:
  snapotter:
    image: snapotter/snapotter:latest
    ports:
      - "1349:1349"
    volumes:
      - ./snapotter-data:/data
    environment:
      - DATABASE_URL=postgres://snapotter:snapotter@db:5432/snapotter
      - REDIS_URL=redis://redis:6379
      # Small-box profile: see the table below for what each cap does.
      - CONCURRENT_JOBS=1
      - MAX_WORKER_THREADS=2
      - MAX_BATCH_SIZE=5
      - MAX_UPLOAD_SIZE_MB=100
      - MAX_MEGAPIXELS=50
      - MAX_VIDEO_DURATION_S=300
    deploy:
      resources:
        limits:
          cpus: "2"
          memory: 2G
    depends_on:
      - db
      - redis
    restart: unless-stopped

  db:
    image: postgres:17-alpine
    environment:
      - POSTGRES_USER=snapotter
      - POSTGRES_PASSWORD=snapotter     # Modificarlo per distribuzioni non locali
      - POSTGRES_DB=snapotter
    volumes:
      - ./postgres-data:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:8-alpine
    command: redis-server --maxmemory 256mb --maxmemory-policy noeviction
    restart: unless-stopped

Note per le macchine di classe Pi:

  • Preferisci un SSD USB a una scheda SD per il volume dei dati e Postgres. Gli spazi di lavoro dei job fanno vero IO su disco, e le schede SD sono lente e si usurano in fretta.
  • Anche il container unico all-in-one funziona qui (Postgres e Redis integrati quando DATABASE_URL/REDIS_URL non sono impostati), e su un host con poca memoria conviene abbassare il tetto del Redis integrato con REDIS_MAXMEMORY (vedi Configurazione). Compose offre un controllo più fine per singolo servizio, ed è per questo che questa guida lo usa.
  • Aggiungi swap sui dispositivi da 2 GB. Evita che il picco occasionale (un PDF enorme, un batch che hai dimenticato di limitare) finisca in un out-of-memory kill. zram è l'opzione più delicata con le schede SD.
  • L'immagine arm64 è solo CPU; non c'è CUDA sulle schede ARM.

I parametri di regolazione

Tutti i tetti sono variabili d'ambiente, documentate per esteso in Configurazione. 0 significa illimitato o automatico. Quelli che contano su hardware modesto:

Variabile Suggerimento per macchine piccole Cosa protegge
CONCURRENT_JOBS 1 Quanti job girano in parallelo. Il rilevamento automatico usa i core della CPU meno uno, che va bene sulle macchine grandi ed è troppo aggressivo su una macchina a 2 core sotto pressione di memoria.
MAX_WORKER_THREADS 2 Pool di thread per l'elaborazione delle immagini.
MAX_BATCH_SIZE 5 I batch sono il punto in cui le macchine da 1-2 GB esauriscono la memoria per prime.
MAX_UPLOAD_SIZE_MB 100 Impedisce che un singolo file enorme occupi l'intero spazio di lavoro.
MAX_MEGAPIXELS 50 Decodificare un'immagine da 100+ MP costa RAM a prescindere dalla dimensione del file.
MAX_VIDEO_DURATION_S 300 Le transcodifiche lunghe monopolizzano una CPU piccola per minuti o ore.
PROCESSING_TIMEOUT_S 600 Tetto rigido perché un job fuori controllo liberi comunque la macchina, prima o poi.

Questi tetti si applicano a ciò che il server accetta, quindi impostali in base a ciò che usi davvero, non al minimo possibile. Se non tocchi mai i video, un tetto su MAX_VIDEO_DURATION_S non costa nulla; se digitalizzi documenti ogni giorno, non mettere un tetto a MAX_PDF_PAGES.

Cosa saltare

  • I bundle AI pesanti. Upscaling, ripristino foto e rimozione dello sfondo vogliono una GPU o una CPU veloce con molti core, e ogni bundle costa 4-5 GB di disco. Su una macchina piccola, semplicemente non installarli; gli strumenti il cui bundle manca mostrano un invito all'installazione invece di essere eseguiti.
  • La ricodifica video come carico di lavoro abituale. Le transcodifiche occasionali vanno bene (sono solo lente); una coda di transcodifica costante vuole core CPU, non un Pi.
  • Gli strumenti inutilizzati in generale. Un amministratore può disattivare i singoli strumenti nelle Impostazioni, il che li rimuove dall'interfaccia e smette di registrare le loro rotte API. Di per sé non fa risparmiare memoria, ma evita che una piccola istanza condivisa venga usata proprio per l'unico carico di lavoro che l'hardware non può reggere.

Se in seguito sposti l'istanza su hardware più potente, rimuovi i tetti (riportali a 0) e lo stesso volume dei dati si trasferisce così com'è.