SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor · Atualizado 2026-08-28

Immich com 6 GB de RAM: upgrades seguros

Saiba quanta RAM o Immich realmente usa, como publicar a porta 2283 com HTTPS, corrigir o erro exit 137 e migrar pgvecto.rs antes do Immich v3.

O que você vai criar

O Immich é um serviço de cópia de segurança de fotografias e vídeos alojado por si, uma verdadeira alternativa ao Google Photos. Tem uma aplicação para telemóvel que carrega o rolo da câmara em segundo plano, uma linha cronológica, álbuns, reconhecimento facial e pesquisa com aprendizagem automática que encontra “praia” ou uma pessoa sem que tenha de adicionar etiquetas. O serviço é executado numa VPS sua, os ficheiros originais permanecem no seu disco e ninguém os analisa para lhe vender produtos. Se ainda estiver a comparar o Immich com a outra opção óbvia, a nossa comparação entre o PhotoPrism e o Immich coloca lado a lado os requisitos mínimos de RAM, as aplicações para telemóvel e os comandos de cópia de segurança.

A instalação usa quatro contentores do ficheiro Docker Compose do próprio projeto. Essa parte demora dez minutos. O restante deste guia é onde surgem as dificuldades: o contentor de aprendizagem automática consome muita memória numa máquina pequena, os ficheiros originais ocupam rapidamente o disco, a aplicação móvel recusa um servidor HTTP simples e o Immich lança alterações incompatíveis com frequência suficiente para que um docker compose pull descuidado possa deixar a base de dados sem conseguir iniciar. Trate estes quatro pontos com seriedade e o Immich será muito fiável. Ignore-os e perderá um fim de semana.

Pré-requisitos e limitações importantes

  • RAM: a documentação oficial indica 6 GB como mínimo e 8 GB como recomendado; considere 4 GB mais swap como o mínimo absoluto. Os contentores immich-server e Postgres usam poucos recursos. O contentor immich-machine-learning consome mais memória: carrega os modelos CLIP e de reconhecimento facial na RAM para criar índices de pesquisa e, numa máquina com 2 GB, o kernel termina o processo. Adicione swap mesmo que tenha 4 GB.
  • Disco: dimensione-o para toda a sua biblioteca e deixe alguma margem. Os ficheiros originais são copiados integralmente. Além disso, o Immich gera miniaturas e imagens de pré-visualização, que ocupam aproximadamente mais 10–20%. Uma coleção de fotografias com 200 GB precisa de um volume de 300 GB. O Postgres ocupa pouco espaço em comparação.
  • CPU: qualquer VPS KVM moderno é adequado, mas o ML em CPU é lento. A indexação da pesquisa inteligente de uma importação grande pode ser executada durante horas em segundo plano. Isso é normal; não precisa de uma GPU.
  • Um nome de domínio apontado para o VPS. A aplicação móvel prefere claramente um endpoint HTTPS, e deve colocar um reverse proxy à frente. A estrutura é semelhante à de uma instância self-hosted do Nextcloud com Docker, TLS e backups; o Immich é a alternativa para fotografias desse servidor de ficheiros.
  • Docker e o plugin Compose instalados: Docker Engine e o plugin Compose v2 provenientes do repositório apt oficial do Docker, exatamente como explicado no nosso guia básico do Docker Compose.

Etapa 1: Adicione swap antes de qualquer outra coisa

A falha mais comum do Immich num VPS pequeno é o contentor de ML ser terminado pelo OOM killer. Dê primeiro ao kernel algum espaço para aliviar a pressão de memória.

sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -h

free -h deve agora mostrar uma linha Swap: de 4.0Gi. Isto não tornará o ML rápido, mas impede que o contentor termine a meio da indexação numa máquina com 4 GB.

Passo 2: Obtenha o compose e o env oficiais e use-os, sem criar uma cópia

O Immich fixa as versões dos serviços e, sobretudo, a imagem da base de dados nos ficheiros que distribui. Não cole um ficheiro compose de um blogue, incluindo este, como fonte de referência. Transfira os artefactos da release:

sudo mkdir -p /opt/immich && cd /opt/immich
sudo wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
sudo wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

Estes ficheiros vêm da release identificada por uma tag, por isso as referências das imagens correspondem às versões corretas. O ficheiro compose define quatro serviços. É útil saber a função de cada um antes de alterar qualquer coisa:

  • immich-server (ghcr.io/immich-app/immich-server, contentor immich_server), a API e a interface Web, à escuta na porta 2283. Monta os seus uploads em /data.
  • immich-machine-learning (ghcr.io/immich-app/immich-machine-learning, contentor immich_machine_learning), utilizado para pesquisas com CLIP e reconhecimento facial. Coloca em cache os modelos transferidos num volume model-cache. É o serviço que mais memória consome.
  • database (contentor immich_postgres), o Postgres com a extensão vetorial VectorChord, que fornece a pesquisa por similaridade. A tag da imagem é fixada por digest diretamente no ficheiro compose, por exemplo ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:.... As instalações mais antigas usavam pgvecto.rs; o suporte para essa extensão foi removido no Immich v3.0, por isso qualquer instalação atual usa VectorChord. Nunca edite esta tag manualmente.
  • redis (contentor immich_redis), uma instância Valkey/Redis para as filas de tarefas.

Passo 3: Configure .env, onde ficam as suas fotografias e a base de dados

Abra .env e defina quatro valores. Tudo o que aparece abaixo da linha marcada permanece como está.

# Where original uploads are stored on the host
UPLOAD_LOCATION=/opt/immich/library

# Where the Postgres data lives. NEVER put this on an NFS/network share.
DB_DATA_LOCATION=/opt/immich/postgres

# "v3" is a floating tag that tracks the latest v3.x. Pin a full tag like
# v3.0.2 instead — then you upgrade on purpose, not by surprise.
IMMICH_VERSION=v3.0.2

# Change this to a long random string. Letters and digits only.
DB_PASSWORD=REPLACE_WITH_A_LONG_RANDOM_STRING

# Set your timezone so timestamps and "on this day" line up
TZ=Europe/London

###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immich

Duas regras evitam problemas. UPLOAD_LOCATION deve apontar para o seu disco de maior capacidade. Se adicionar um volume de dados mais tarde, defina este valor desde o início como o caminho de montagem do volume. Alterá-lo depois implica mover as miniaturas e atualizar os caminhos dos recursos. DB_DATA_LOCATION tem de estar num disco local: o Postgres fica corrompido quando usa um compartilhamento NFS ou SMB, e a documentação afirma isso explicitamente. Se usar apenas letras e dígitos em DB_PASSWORD, evita uma classe de problemas de escape nas strings de conexão.

Passo 4: Primeira execução e criação do utilizador admin

cd /opt/immich
sudo docker compose up -d
sudo docker compose ps

O resultado correto são quatro contentores, todos running e, por fim, healthy:

NAME                      STATUS
immich_machine_learning   Up (healthy)
immich_postgres           Up (healthy)
immich_redis              Up (healthy)
immich_server             Up (healthy)

A primeira execução de up transfere vários gigabytes de imagens, por isso aguarde. Monitorize o progresso com sudo docker compose logs -f immich-server; quando estiver pronto, o servidor regista nos logs que está a escutar na porta 2283. Agora abra http://YOUR_SERVER_IP:2283 num browser. Na primeira visita, é apresentado um assistente Getting Started. A primeira conta criada é a conta admin. Defina uma palavra-passe forte. Esta conta controla as definições do servidor, a gestão de utilizadores e a configuração de ML necessária mais tarde.

Passo 5: a aplicação móvel e a cópia de segurança em segundo plano

Instale o "Immich" a partir da App Store ou da Play Store. No ecrã de início de sessão, é pedido um Server Endpoint URL. Introduza o URL completo, incluindo o esquema, por exemplo https://photos.example.com (a aplicação acrescenta /api automaticamente). Inicie sessão com a conta que acabou de criar, abra o ecrã Backup da aplicação, selecione os álbuns que pretende proteger (normalmente Camera e Screenshots) e ative Background backup. A cópia de segurança em segundo plano no iOS é limitada pelo sistema operativo. Os carregamentos em primeiro plano são sempre executados. Os carregamentos em segundo plano ocorrem quando o sistema operativo o permite.

É precisamente nesta etapa que muitas pessoas ficam bloqueadas. Leia o Passo 6 antes de tentar resolver problemas na aplicação.

Passo 6: HTTPS através de um reverse proxy e a regra do URL completo

A aplicação móvel exige HTTPS. Coloque um reverse proxy à frente da porta 2283 e faça a terminação TLS nesse ponto. Se já executa vários contentores, Traefik com TLS automático para várias aplicações Docker é a opção mais organizada: um bloco de labels encaminha photos.example.com para o contentor immich-server e obtém o certificado automaticamente. Se preferir nginx, o guia Let's Encrypt com Certbot e nginx obtém um certificado e um bloco proxy_pass http://127.0.0.1:2283;. Depois de criar esse proxy, adicionar o serviço seguinte resume-se, na maioria dos casos, a criar um novo subdomínio. É assim que uma interface multimédia como Halcyon, a interface de videoclube dos anos 90 para Jellyfin pode ficar ao lado do Immich no mesmo servidor. O mesmo se aplica a um HarnessRouter alojado localmente que coloca Codex e Claude Code atrás de uma única API. Este serviço fica ligado ao loopback de propósito e só se torna acessível quando o proxy faz a terminação TLS à sua frente. Por isso, altere o login predefinido antes de apontar um subdomínio para ele. No entanto, nem todos os contentores devem ter um nome de host público. Uma ferramenta apenas para administração, como um analisador de segurança open-kritt alojado localmente, deve ficar totalmente fora do proxy e ser acedida através de um túnel SSH nas raras ocasiões em que abrir a interface. Outros serviços dispensam o proxy porque não usam HTTP. Um servidor relay RustDesk alojado localmente é o exemplo mais claro: escuta em várias portas TCP e UDP diretas e requer regras de firewall, não um subdomínio. Há uma definição do proxy importante para o Immich: aumente o limite do tamanho dos uploads, porque os vídeos dos telemóveis são grandes. No nginx, essa definição é client_max_body_size 50000M; dentro do bloco server. O valor predefinido de 1 MB rejeita os uploads de vídeo com 413 Request Entity Too Large.

A regra imposta pela aplicação é a seguinte: o endpoint tem de estar acessível e, na prática, tem de usar HTTPS. Endpoints http:// ou um IP direto sem a porta indicada originam o erro "a aplicação não consegue aceder ao servidor", descrito abaixo como uma falha identificada.

Etapa 7: bibliotecas externas versus carregamentos, importando uma árvore de fotos existente

Há duas formas de as fotos entrarem no Immich, e não são equivalentes.

  • Carregamentos são ativos pertencentes ao Immich. O aplicativo ou o carregador web copia o ficheiro para UPLOAD_LOCATION. O Immich pode renomeá-los, movê-los e eliminá-los.
  • Bibliotecas externas são importações somente de leitura de ficheiros que já estão numa pasta do servidor, numa árvore Pictures antiga ou numa exportação de NAS. O Immich indexa-os no local e mostra-os na linha temporal, mas nunca modifica nem elimina os originais.

Para importar uma árvore existente, monte-a como somente de leitura no contentor do servidor. Edite docker-compose.yml em immich-server: e adicione um volume:

  immich-server:
    volumes:
      - ${UPLOAD_LOCATION}:/data
      - /etc/localtime:/etc/localtime:ro
      - /srv/photos:/mnt/media/photos:ro

O :ro garante que o Immich nunca pode tocar nos originais. Recrie o contentor com sudo docker compose up -d. Depois, na interface web, aceda ao seu avatar → Administração → Bibliotecas externas → Criar biblioteca, selecione o utilizador proprietário, clique em Adicionar em Pastas e introduza o caminho do contentor, /mnt/media/photos, e não o caminho do host, /srv/photos. Clique em Digitalizar. Usar o caminho do host em vez do caminho do contentor é o erro mais comum nas bibliotecas externas; a digitalização não encontra nada e comunica zero ativos.

A disciplina de atualização exigida pelo Immich

Esta é a parte que separa uma instalação do Immich estável de uma instalação danificada. O Immich lança versões rapidamente e não faz backport de correções nem oferece suporte para downgrades. Seguir cegamente a tag flutuante v3 acabará por danificar a base de dados. Aplicar o mesmo princípio de fixar a versão e ler as notas a todos os contentores de execução prolongada no servidor também é recomendável. Por isso, um agente KiroCrew self-hosted fica fixado numa tag conhecida e estável, em vez de poder mudar na próxima reinicialização. A disciplina é a seguinte:

  1. Fixe uma versão. Mantenha IMMICH_VERSION definida com uma tag concreta, como v3.0.2, e não com a tag flutuante v3, que obtém sempre a versão v3.x mais recente.
  2. Leia sempre as notas de lançamento antes de atualizar. As alterações incompatíveis, especialmente as relacionadas com a base de dados ou com extensões vetoriais, são indicadas nessas notas. A versão v3.0 é o exemplo mais evidente: removeu totalmente o pgvecto.rs. Assim, quem ainda usava a extensão antiga tinha de concluir a migração para VectorChord, introduzida na v1.133, antes de poder atualizar.
  3. Faça primeiro uma cópia de segurança da base de dados (Passo 9). Faça-o sempre, mas tenha ainda mais cuidado quando as notas mencionarem a base de dados.
  4. Obtenha também o novo ficheiro compose. IMMICH_VERSION fixa apenas as imagens do servidor e de ML. A imagem do Postgres é fixada por digest dentro de docker-compose.yml. Por isso, uma versão que necessite de uma extensão de base de dados mais recente inclui um novo ficheiro compose. Transfira novamente os dois artefactos da versão, reaplique os seus valores de .env e, em seguida, atualize.
  5. Atualize os clientes móveis aproximadamente na mesma altura. O servidor comunica apenas com a versão principal correspondente, e a aplicação suporta a versão principal atual e a anterior. Se o servidor avançar em relação à aplicação, o telefone apresenta Your app major version is not compatible with the server! até que a aplicação seja atualizada. Por isso, é mais seguro atualizar primeiro a aplicação.

Os comandos concretos, depois de colocar os novos ficheiros no lugar, são:

cd /opt/immich
sudo docker compose pull
sudo docker compose up -d
sudo docker image prune

Etapa 9: Backups, um dump do banco de dados MAIS os originais, e teste

Um backup do Immich consiste em duas coisas, e uma sem a outra é inútil. O banco de dados contém a estrutura dos álbuns, os rostos, os índices de pesquisa e o mapeamento entre cada recurso e o respetivo ficheiro. O diretório de originais contém as fotografias reais. Restaure um sem o outro e terá fotografias sem organização ou uma estrutura vazia que aponta para ficheiros inexistentes. Essa estrutura em duas partes não é uma particularidade do Immich: um service desk Chatwoot autoalojado precisa da mesma combinação de um dump do Postgres e do respetivo diretório de uploads, caso contrário a caixa de entrada restaurada volta sem nenhum anexo. Copiar o diretório de dados do Postgres como uma árvore de ficheiros parece um atalho para evitar o dump, mas não constitui um backup utilizável, uma armadilha que o guia completo de backup e restauro do Immich explica juntamente com o erro de restauro que deixa a linha do tempo vazia.

Faça o dump do banco de dados com pg_dump a partir de dentro do contentor Postgres, especificamente da base de dados immich, e não de todo o cluster:

sudo docker exec -t immich_postgres pg_dump --clean --if-exists \
  --dbname=immich --username=postgres | gzip > /opt/immich/immich-db-$(date +%F).sql.gz

Depois faça backup de UPLOAD_LOCATION, de toda a árvore /opt/immich/library e, em particular, das subpastas library/, upload/ e profile/, usando restic, rsync ou borg para outra máquina ou para armazenamento de objetos. Seja qual for o mecanismo que agenda essa tarefa, uma entrada cron ou um temporizador systemd, ele precisa de um local para alertar quando falhar. Uma unidade systemd OnFailure= apontada para o seu próprio servidor push ntfy envia uma mensagem para o telemóvel na noite em que um dump falha, em vez de o deixar descobrir o problema durante um restauro. Faça primeiro o backup do banco de dados e depois o dos ficheiros, para que o dump nunca faça referência a uma fotografia que o backup de ficheiros ainda não copiou. Faça o backup das bibliotecas externas separadamente, na origem real. O Immich não é responsável por elas.

Agora vem a parte que todos ignoram: teste o restauro. O restauro tem de ser executado numa stack nova, cujo servidor nunca tenha sido iniciado, e numa imagem Postgres cuja extensão de vetores seja compatível com o dump. É exatamente por isso que nunca deve escolher o tag da imagem DB sem confirmar. Numa máquina de teste com o mesmo compose e .env, apague qualquer estado antigo, inicie apenas o banco de dados e carregue o dump:

cd /opt/immich
sudo docker compose down -v
sudo docker compose pull
sudo docker compose create
sudo docker start immich_postgres
sleep 10
gunzip --stdout immich-db-2026-07-15.sql.gz |
  sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" |
  sudo docker exec -i immich_postgres psql --dbname=immich --username=postgres --single-transaction --set ON_ERROR_STOP=on
sudo docker compose up -d

A reescrita de search_path com sed não é opcional numa base de dados VectorChord. Se a omitir, o restauro é interrompido a meio. Quando a stack voltar a iniciar com os seus originais no lugar, abra a interface web. Se as fotografias e os álbuns estiverem lá, o backup funciona. Se nunca executou este procedimento, não tem um backup. Tem apenas esperança.

Modos de falha e as mensagens apresentadas

O contentor ML é terminado por falta de memória (OOM). sudo docker compose logs immich-machine-learning termina abruptamente, docker compose ps mostra Restarting e o código de saída é 137. sudo dmesg | grep -i oom confirma o motivo: Out of memory: Killed process ... (python3). Os trabalhos de pesquisa e reconhecimento facial ficam bloqueados. A causa é haver pouca RAM para os modelos. Correções, por ordem: adicionar swap (Passo 1); atribuir mais RAM à VPS; ou, se isso não for possível, desativar o ML em Administration → Settings → Machine Learning Settings, desativando Smart Search e Facial Recognition. Mantém as cópias de segurança e os álbuns, mas perde a pesquisa por conteúdo. Remover o serviço immich-machine-learning do ficheiro compose tem o mesmo efeito.

O Postgres recusa iniciar depois de uma atualização. O log do servidor repete uma linha semelhante a The database currently has VectorChord 0.5.3 activated, but the Postgres instance only has 0.4.2 available. This most likely means the extension was downgraded. ou, em stacks mais antigas, The pgvecto.rs extension is not available in this Postgres instance.. A causa é uma imagem da base de dados cuja versão da extensão é mais antiga do que a versão para a qual os dados foram atualizados. Isto acontece quase sempre por editar manualmente a tag da imagem ou por restaurar um dump mais recente numa imagem mais antiga. A correção é usar a imagem Postgres compatível, obter o ficheiro compose da release que corresponde à sua base de dados, não fazer downgrade e restaurar apenas numa imagem compatível.

A aplicação móvel não consegue alcançar o servidor. O ecrã de início de sessão apresenta um erro de ligação / Server is not reachable depois de introduzir o URL. Há três causas possíveis: introduziu http://, mas o proxy só disponibiliza https://; ligou-se diretamente ao backend, mas omitiu a porta, por isso foi tentada example.com (porta 443) em vez de example.com:2283; ou o reverse proxy não está a encaminhar /api. Corrija o problema introduzindo o URL https://photos.example.com completo e confirme primeiro que este abre no browser do telemóvel. Se funcionar no browser mas não na aplicação, o proxy está a remover o caminho ou o certificado é autoassinado. A aplicação rejeita certificados não confiáveis.

O disco fica cheio durante a importação. Os uploads começam a falhar, as miniaturas ficam vazias e os logs mostram ENOSPC: no space left on device ou, no Postgres, could not extend file ... No space left on device. df -h mostra que o volume UPLOAD_LOCATION está a 100%. Por isso, dimensione o disco antes de importar uma biblioteca grande. Para recuperar, anexe um volume maior, pare a stack, mova UPLOAD_LOCATION para esse volume, atualize .env e inicie novamente. Também pode expandir o disco existente, se o fornecedor permitir. O Postgres pode ficar bloqueado quando o disco enche. Liberte espaço e reinicie o contentor da base de dados antes de concluir que existe corrupção.

FAQ

De quanta RAM e espaço em disco o Immich precisa?

Os requisitos oficiais do Immich são 6 GB de RAM no mínimo e 8 GB recomendados. Para uma biblioteca pequena, 4 GB com swap é o mínimo prático. Configure swap de qualquer forma, porque o contentor de machine learning é o componente que provoca os picos de utilização. Para o disco, reserve o tamanho total da biblioteca mais cerca de 10–20% para miniaturas e pré-visualizações geradas, em armazenamento local. Nunca coloque o diretório de dados do Postgres numa partilha de rede. Se ainda está a decidir o que executar, o guia sobre o que alojar autonomamente em 2026 compara o espaço ocupado pelo Immich com o de outros serviços.

Posso executar o Immich sem uma GPU?

Sim. O contentor de machine learning funciona normalmente com CPU. Uma GPU apenas acelera a indexação da pesquisa inteligente e, com a variante de imagem correta, a transcodificação de vídeo. Com CPU, a indexação inicial de uma biblioteca grande pode demorar horas em segundo plano, mas não bloqueia as cópias de segurança nem a navegação. Se a sua máquina for demasiado pequena para executar o ML, pode desativar a Pesquisa inteligente e o Reconhecimento facial nas definições de administração e manter todas as outras funcionalidades.

Como atualizo o Immich com segurança?

Fixe IMMICH_VERSION numa tag concreta, como v3.0.2, leia as notas da versão antes de cada atualização e faça primeiro uma cópia de segurança da base de dados. Como a imagem do Postgres está fixada dentro de docker-compose.yml, e não através de IMMICH_VERSION, descarregue novamente tanto o ficheiro compose como example.env a partir da versão de destino, reaplique os seus valores e execute docker compose pull && docker compose up -d. Nunca deixe a versão variar sem supervisão. O Immich lança alterações incompatíveis e não suporta downgrades.

O que devo incluir exatamente na cópia de segurança?

Duas coisas, em conjunto: um pg_dump da base de dados immich e todo o diretório de originais UPLOAD_LOCATION. A base de dados contém os álbuns, os rostos e o mapeamento entre ativos e ficheiros. O diretório contém as fotografias propriamente ditas. Uma restauração precisa dos dois elementos e de uma imagem da base de dados com uma extensão vetorial compatível. Faça primeiro o dump da base de dados e copie os ficheiros depois. Teste a restauração pelo menos uma vez numa máquina de teste. Uma cópia de segurança não testada não é uma cópia de segurança.

Como importo a minha pasta de fotografias existente?

Monte a pasta como somente leitura no contentor immich-server, como um volume adicional, por exemplo - /srv/photos:/mnt/media/photos:ro, recrie o contentor e, em Administração → Bibliotecas externas, crie uma biblioteca e adicione o caminho do contentor /mnt/media/photos. O Immich indexa os ficheiros no local e nunca os modifica nem elimina. O erro mais comum é introduzir o caminho do host em vez do caminho do contentor, fazendo com que a pesquisa não encontre nada.