Files
SnapOtter/apps/docs/pt-BR/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.9 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 ee71505c5fbe 2

Ambientes com Poucos Recursos

O SnapOtter roda bem em hardware modesto: um Raspberry Pi 4 ou 5, um notebook antigo ou um VPS de 2 GB. Esta página é o guia prático para essas máquinas: o que esperar, uma configuração pronta para copiar e colar com limites sensatos e quais features pular. Os dados completos de benchmark por trás desses números estão em Requisitos de Hardware.

Antes de tudo, duas restrições rígidas:

  • Apenas 64 bits. A imagem é construída para linux/amd64 e linux/arm64. ARM de 32 bits (armv7/armhf) não é suportado, então os Pis de primeira geração e a família Pi Zero ficam de fora.
  • Piso de memória de 2 GB. Com 512 MB a stack nem inicia, e 1 GB falha em lotes com vários arquivos. 2 GB com 2 núcleos é a menor configuração que funciona com folga.

O que roda bem em hardware modesto

Toda ferramenta sem IA funciona em uma máquina de 2 GB / 2 núcleos: as seções de Imagem e Arquivos inteiras, as ferramentas de PDF e as operações de vídeo e áudio por stream-copy (cortar, silenciar, remux de contêiner). A maioria termina em menos de um segundo.

Duas cargas de trabalho são as exceções:

  • Recodificação de vídeo (converter entre codecs) é limitada pela CPU. Um clipe 1080p que leva ~40 s em uma CPU de desktop rápida pode levar vários minutos em uma CPU da classe do Pi. As operações de stream-copy continuam instantâneas.
  • Ferramentas de IA precisam de RAM (4 GB recomendados) e disco (os bundles maiores têm 4-5 GB cada), e as pesadas (upscale, restauração de fotos, remoção de fundo) não são práticas em CPUs da classe do Pi. IA leve, como detecção de rosto e OCR, é utilizável se você tiver memória para isso.

Nenhuma das duas é instalada ou fica rodando a menos que você a use: sem bundles de IA instalados, o aplicativo fica ocioso em torno de 360 MB, e os bundles de IA só são baixados quando um admin os habilita.

Passo a passo para Raspberry Pi / notebook antigo

Esta é a instalação padrão com Compose de Primeiros Passos, mais limites de recursos e tetos conservadores. Ela pressupõe um sistema operacional de 64 bits (em um Pi: Raspberry Pi OS 64-bit ou 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     # Altere isso para implantações não locais
      - 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

Observações para máquinas da classe do Pi:

  • Prefira um SSD USB a um cartão SD para o volume de dados e o Postgres. As áreas de trabalho dos jobs fazem IO de disco de verdade, e cartões SD são lentos e se desgastam rápido.
  • O contêiner único tudo-em-um também funciona aqui (Postgres e Redis embutidos quando DATABASE_URL/REDIS_URL não estão definidos), e em um host com pouca memória você deve reduzir o teto do Redis embutido com REDIS_MAXMEMORY (veja Configuração). O Compose dá um controle mais fino por serviço, e é por isso que este passo a passo o utiliza.
  • Adicione swap em dispositivos de 2 GB. Isso evita que um pico ocasional (um PDF grande, um lote que você esqueceu de limitar) termine em um kill por falta de memória. zram é a opção amigável ao cartão SD.
  • A imagem arm64 é apenas CPU; não há CUDA em placas ARM.

Os ajustes disponíveis

Todos os limites são variáveis de ambiente, documentadas por completo em Configuração. 0 significa ilimitado ou automático. Os que importam em hardware modesto:

Variável Sugestão para máquinas pequenas O que protege
CONCURRENT_JOBS 1 Quantos jobs rodam em paralelo. A detecção automática usa o número de núcleos de CPU menos um, o que funciona bem em máquinas grandes e é agressivo demais em uma máquina de 2 núcleos sob pressão de memória.
MAX_WORKER_THREADS 2 Pool de threads de processamento de imagem.
MAX_BATCH_SIZE 5 É nos lotes que máquinas de 1-2 GB ficam sem memória primeiro.
MAX_UPLOAD_SIZE_MB 100 Impede que um único arquivo enorme ocupe toda a área de trabalho.
MAX_MEGAPIXELS 50 Decodificar uma imagem de 100+ MP custa RAM independentemente do tamanho do arquivo.
MAX_VIDEO_DURATION_S 300 Transcodificações longas monopolizam uma CPU pequena por minutos ou horas.
PROCESSING_TIMEOUT_S 600 Teto rígido para que um job descontrolado acabe liberando a máquina.

Esses limites se aplicam ao que o servidor aceita, então defina-os de acordo com o que você realmente usa, e não com o menor valor possível. Se você nunca mexe com vídeo, um limite em MAX_VIDEO_DURATION_S não custa nada; se você digitaliza documentos todos os dias, não limite MAX_PDF_PAGES.

O que pular

  • Bundles de IA pesados. Upscale, restauração de fotos e remoção de fundo pedem uma GPU ou uma CPU rápida com muitos núcleos, e cada bundle custa 4-5 GB de disco. Em uma máquina pequena, simplesmente não os instale; ferramentas cujo bundle está ausente mostram um aviso de instalação em vez de rodar.
  • Recodificação de vídeo como carga de trabalho rotineira. Transcodificações ocasionais são aceitáveis (só são lentas); uma fila constante de transcodificação pede núcleos de CPU, não um Pi.
  • Ferramentas não usadas em geral. Um admin pode desligar ferramentas individuais em Configurações, o que as remove da interface e deixa de registrar suas rotas de API. Isso por si só não economiza memória, mas evita que uma instância pequena compartilhada seja usada justamente para a carga de trabalho que o hardware não aguenta.

Se mais tarde você mover a instância para um hardware maior, remova os limites (defina-os de volta para 0) e o mesmo volume de dados vai junto.