Immich: Alternativa Self-Hosted ao Google Photos em 2026
O Google Photos deixou de ser gratuito em 2021 e desde então as quotas de armazenamento comprimidas ao Google One. Para quem tem uma NAS, um mini-PC ou um servidor antigo em casa, o Immich é a alternativa self-hosted mais madura e activa: oferece linha temporal, partilha, reconhecimento facial, pesquisa semântica e apps móveis (iOS/Android) com backup automático. Neste guia mostro como instalar via Docker Compose, configurar o reconhecimento facial e os modelos de machine learning, garantir conformidade com o RGPD e resolver os erros mais comuns.
ℹ Estado do projecto: O Immich manteve-se em beta activo durante 2024 e 2025, mas a versão v1.140.0 (Julho 2026) já é considerada production-ready pela comunidade. As APIs são estáveis, o external storage funciona, e o machine learning suporta GPU. A equipa recomenda ainda assim backups da base de dados antes de cada upgrade.
Introdução
O Immich é um servidor de gestão de fotos e vídeos que corre em Docker. Foi criado em 2022 por Alex Tran e cresceu até ser o projecto self-hosted mais popular na categoria, com mais de 60.000 estrelas no GitHub. O objectivo é claro: recriar a experiência do Google Photos mas com os ficheiros no teu próprio hardware.
As principais funcionalidades em 2026 incluem:
- Timeline idêntica ao Google Photos (organização por data, mês, ano)
- Backup automático das fotos do telemóvel (apps iOS e Android)
- Reconhecimento facial com agrupamento automático de pessoas
- Pesquisa semântica (“praia ao pôr-do-sol”, “cão a correr”)
- Detecção de objectos e classificação automática (cães, praias, comida, etc.)
- Partilha de álbuns com links públicos ou com utilizadores registados
- Leitura de metadados EXIF (GPS, câmara, lente, ISO)
- Mapa com geolocalização das fotos
- Suporte para vídeo (incluindo transcodificação para web)
- Storage externo (S3, Backblaze B2, MinIO) via library scanning
O Immich é composto por três serviços principais: o server (API em Node.js/NestJS), o machine learning (Python, usa ONNX runtime) e a base de dados (PostgreSQL com o pgvector para embeddings vectoriais). Tudo corre em containers Docker e comunica por rede interna.
✓ Vantagem sobre alternativas: O Nextcloud tem fotos mas o reconhecimento facial é fraco. O PhotoPrism é bom para arquivos estáticos mas não tem app móvel com backup. O Immich é o único que cobre todo o fluxo: captura, backup, organização, pesquisa e partilha.
Instalar via Docker Compose
A instalação oficial usa Docker Compose. Precisas de Docker 24+ e Docker Compose v2. O hardware mínimo é modesto: 2 vCPU, 4 GB RAM e 50 GB de disco para a biblioteca (o ML consome RAM extra). Para bibliotecas grandes (100k+ fotos) recomenda-se 8 GB de RAM e GPU para acelerar o reconhecimento facial.
1. Pré-requisitos
Verifica que tens Docker e Docker Compose instalados:
docker --version
# Docker version 26.0.0 ou superior
docker compose version
# Docker Compose version v2.27.0 ou superior
2. Obter os ficheiros oficiais
O Immich fornece um repositório GitHub com os ficheiros de configuração. Clona o repositório e entra na pasta docker:
git clone https://github.com/immich-app/immich.git
cd immich/docker
# Copiar o env de exemplo
cp .env.example .env
3. Configurar o ficheiro .env
Edita o ficheiro .env com as tuas definições. As variáveis essenciais são:
# Pasta onde ficam as fotos (caminho absoluto no host)
UPLOAD_LOCATION=/mnt/fotos/immich
# Password da base de dados PostgreSQL
DB_PASSWORD=UmaPasswordForteAqui123
# URL de acesso (usado pelas apps móveis)
EXTERNAL_DOMAIN=https://fotos.minha-casa.pt
O UPLOAD_LOCATION deve apontar para um disco com espaço suficiente. Se usas uma NAS ou um mount NFS, garante que o Docker tem permissões de leitura/escrita nesse caminho.
4. Iniciar os serviços
docker compose up -d
# Verificar se todos os containers estão a correr
docker compose ps
# Ver os logs do server
docker compose logs -f immich-server
Após o arranque, o Immich fica disponível em http://IP_DO_SERVIDOR:2283. No primeiro acesso, cria-se a conta de administrador. Depois podes configurar utilizadores adicionais, definir quotas de armazenamento por utilizador e ligar o reverse proxy.
5. Reverse proxy com Caddy
Para acesso externo com HTTPS, usa um reverse proxy. O Caddy é o mais simples porque gere certificados Let’s Encrypt automaticamente:
fotos.minha-casa.pt {
reverse_proxy localhost:2283
}
Com o Nginx, adiciona também os headers de WebSocket (necessários para o upload em tempo real das apps móveis):
location / {
proxy_pass http://localhost:2283;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_max_body_size 0; # sem limite de upload
}
⚠ Atenção ao client_max_body_size: Se não definires como 0 (sem limite), o Nginx rejeita uploads de vídeos grandes com erro 413 Request Entity Too Large. O Immich envia ficheiros em chunks, mas o Nginx pode barrar o chunk inicial se o limite for baixo.
Reconhecimento Facial e ML
O Immich usa dois modelos de machine learning: um para detecção facial (encontra caras nas fotos) e outro para reconhecimento facial (agrupa caras da mesma pessoa). Ambos correm no container immich-machine-learning e usam o ONNX Runtime, que suporta CPU e GPU (CUDA para NVIDIA, CoreML para Mac, OpenVINO para Intel).
Activar o reconhecimento facial
Por defeito, o reconhecimento facial vem activado. Para confirmar ou ajustar, vai a Administration → Settings → Machine Learning no painel de administração. As opções principais são:
- Face Detection Model:
buffalo_l(padrão, preciso) ouantelopev2(mais rápido, menos preciso) - Face Recognition Model:
buffalo_l(padrão) - CLIP Model:
all-MiniLM-L6-v2(pesquisa semântica, padrão) - Min Faces for Grouping: 3 (mínimo de caras detectadas para criar um grupo de pessoa)
Para forçar o reprocessamento de todas as fotos (útil após mudar de modelo):
# Administration -> Jobs -> Face Detection -> ALL
# Administration -> Jobs -> Face Recognition -> ALL
# Administration -> Jobs -> Smart Search -> ALL
Acelerar com GPU (NVIDIA)
Se tens uma GPU NVIDIA, podes acelerar o ML de 5x a 20x. Altera o docker-compose.yml do machine learning para usar a imagem com CUDA:
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:latest-cuda
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
Precisas também do NVIDIA Container Toolkit instalado no host. Após reiniciar, o Immich detecta a GPU automaticamente e usa-a para inferência. Podes confirmar em Administration → Settings → Machine Learning — aparece um indicador de GPU activa.
Pesquisa semântica (Smart Search)
A pesquisa semântica usa o modelo CLIP para converter cada imagem num vector de 384 dimensões que fica armazenado no PostgreSQL via pgvector. Quando escreves “praia” na barra de pesquisa, o Immich converte a palavra num vector e encontra as fotos cujo vector está mais próximo. Isto permite procurar por conceitos sem tags manuais — “cão”, “neve”, “festa de aniversário” funcionam mesmo que o EXIF não tenha essa informação.
A primeira vez que activas o Smart Search, o job processa toda a biblioteca. Para 10.000 fotos em CPU, demora entre 2 a 6 horas dependendo do processador. Com GPU, o tempo cai para 15-30 minutos.
Backup e RGPD
Por ser self-hosted, o Immich coloca a responsabilidade dos backups e da conformidade legal inteiramente em ti. Isto é uma vantagem (controlo total) mas exige disciplina. Há três componentes que precisam de backup: a pasta de uploads, a base de dados PostgreSQL e a configuração.
Backup da base de dados
A base de dados contém os metadados, as pessoas detectadas, os álbuns, os utilizadores e os embeddings vectoriais. Sem ela, perdes toda a organização — mesmo que as fotos continuem no disco. O backup faz-se com pg_dumpall dentro do container:
# Backup diário automatizado (crontab)
0 3 * * * docker exec immich-postgres pg_dumpall -U postgres | gzip > /backup/immich-db-$(date +\%F).sql.gz
# Rotação: manter 7 dias
find /backup -name "immich-db-*.sql.gz" -mtime +7 -delete
Backup das fotos
As fotos em si ficam na pasta UPLOAD_LOCATION. O Immich não faz deduplicação ao nível do sistema de ficheiros — cada foto tem um UUID e fica numa estrutura library/<user>/<year>/<month>/. Um rsync para um disco externo ou NAS remota é suficiente:
rsync -avz --delete /mnt/fotos/immich/ user@nas-remota:/backup/immich/
Conformidade com o RGPD
Se a tua instância do Immich vai ser usada por outras pessoas (família, amigos, clientes), tens de considerar o Regulamento Geral de Protecção de Dados (RGPD/GDPR). O Immich processa dados pessoais — fotos com caras identificadas, localização GPS, datas — e o responsável pelo tratamento és tu.
- Base legal: Para uso familiar, o consentimento é a base mais simples. Para uso profissional, pode ser contrato ou interesse legítimo. Documenta a base legal.
- Direito ao apagamento: O Immich permite eliminar uma conta de utilizador e todos os seus dados em Administration → Users → Delete. Isto remove fotos, metadados e caras detectadas. Confirma que o backup também é purgado (não basta apagar na cópia principal).
- Portabilidade: O utilizador pode exportar todas as suas fotos via Account → Export. O Immich gera um ficheiro ZIP com as fotos originais e um JSON com os metadados.
- Encriptação em trânsito: Usa sempre HTTPS (reverse proxy com Let’s Encrypt). As apps móveis só aceitam ligações HTTPS por defeito.
- Encriptação em repouso: O Immich não encripta os ficheiros no disco. Se precisas de encriptação, usa LUKS no nível do sistema de ficheiros ou uma pasta cifrada com
gocryptfs. - Registo de acessos: O Immich regista logins e alterações administrativas nos logs do container. Para auditoria formal, encaminha os logs para um sistema centralizado (Loki, ELK).
- Partilha pública: Links de partilha pública não exigem autenticação. Define uma data de expiração e evita partilhar álbuns com fotos de terceiros sem consentimento.
⚠ Violação de dados: Se a tua instância for comprometida e houver acesso não autorizado a fotos de pessoas identificadas, tens 72 horas para notificar a CNPD (Portugal) ou autoridade equivalente. Guarda os logs de acesso para conseguir determinar o âmbito da violação.
Erros Comuns
A tabela seguinte resume os erros mais frequentes reportados pela comunidade Immich em 2025-2026, com causa e solução:
| Erro | Causa | Solução |
|---|---|---|
Error: GPU not found |
NVIDIA Container Toolkit não instalado ou imagem errada (sem sufixo -cuda) |
Instalar nvidia-container-toolkit, usar imagem :latest-cuda, reiniciar Docker |
502 Bad Gateway no Nginx |
Immich server ainda a arrancar ou porta errada no proxy | Confirmar docker compose ps, proxy aponta para localhost:2283 |
413 Request Entity Too Large |
Nginx com client_max_body_size baixo |
Definir client_max_body_size 0; no bloco server |
| Faces não detectadas após upload | Job de Face Detection em pausa ou ML container parado | Verificar docker compose logs immich-machine-learning, forçar job ALL |
| Upload da app móvel falha | HTTPS mal configurado ou certificado auto-assinado não aceite | Usar Let’s Encrypt no reverse proxy; a app não aceita self-signed |
Out of memory no ML |
Biblioteca grande em CPU com < 4 GB RAM | Aumentar RAM para 8 GB, usar GPU, ou trocar para modelo antelopev2 (mais leve) |
| PostgreSQL não arranca | Permissões na pasta pgdata ou DB_PASSWORD alterada |
chown -R 1000:1000 ./pgdata, manter password consistente entre reinícios |
| Pesquisa semântica não devolve resultados | Job Smart Search não executado ou pgvector não instalado | Confirmar extensão pgvector activa, forçar job Smart Search ALL |
| Upgrade quebra a instância | Saltar versões intermédias (não seguir release notes) | Seguir release notes de cada versão, fazer backup DB antes, não saltar major versions |
⚠ Upgrades: O Immich não segue versionamento semântico. Cada release pode incluir migrations de base de dados irreversíveis. Lê sempre as release notes antes de fazer docker compose pull && docker compose up -d. Se saltas versões, podes corromper a base de dados.
Checklist Antes de Aplicar em Produção
Antes de aplicar qualquer comando deste artigo em ambiente produtivo, confirma:
- Versão do Docker (deve ser 24+):
docker --version - Docker Compose v2 (não v1, que está em deprecated):
docker compose version - Espaço em disco suficiente no
UPLOAD_LOCATION:df -h /mnt/fotos - RAM disponível (mínimo 4 GB, 8 GB com ML):
free -h - Reverse proxy configurado com HTTPS (Let’s Encrypt ou equivalente):
curl -I https://fotos.minha-casa.pt - Backup da base de dados antes de cada upgrade:
docker exec immich-postgres pg_dumpall -U postgres | gzip > immich-backup.sql.gz
⚠ Comandos que afectam a base de dados (e.g. docker compose pull && docker compose up -d durante um upgrade) devem ser testados em staging e aplicados em janela de manutenção — um upgrade mal feito pode causar perda irreversível de metadados, corrupção do pgvector ou indisponibilidade do serviço para todos os utilizadores.