Como hospedar o Ollama com segurança em um VPS
Um modelo 7B precisa de 8 GB de RAM e entrega 4 a 10 tokens por segundo na CPU. Use 127.0.0.1:11434/v1 e mantenha a porta 11434 fechada.
O que você vai criar
Um único modelo de linguagem de pesos abertos, executado num servidor sob o seu controlo, respondendo através de uma API HTTP e, se quiser, com uma página de chat no navegador. O Ollama é o componente que descarrega o modelo, o carrega na memória e atende pedidos em http://127.0.0.1:11434. A instalação requer um único comando. A parte difícil está noutros pontos: escolher um modelo que o seu VPS consiga manter na RAM e não publicar acidentalmente um servidor de inferência sem autenticação em toda a Internet.
Primeiro, dois avisos importantes. Um VPS apenas com CPU executa modelos pequenos lentamente e a API não tem autenticação incorporada. Ambos os pontos são abordados em detalhe abaixo, porque são as situações que mais frequentemente causam problemas.
A verificação de dimensionamento, em números simples
O consumo de memória de um modelo corresponde aproximadamente ao tamanho do ficheiro, mais cerca de 1 GB de sobrecarga de execução, mais algum espaço para a janela de contexto. As tags predefinidas da maioria dos modelos populares do Ollama, incluindo llama3.2:3b, llama3.1:8b e mistral:7b, usam quantização de 4 bits (identificada como Q4_K_M), que consome cerca de meio gigabyte de RAM por cada mil milhões de parâmetros. Nem todas as predefinições usam Q4: modelos pequenos, como smollm2:135m, são distribuídos em 16 bits. Consulte a linha de quantização na página da biblioteca do modelo antes de fazer as contas. A aritmética é simples e determina tudo. O último termo é definido por si: aumentar num_ctx acima do valor predefinido reduzido do Ollama permite usar prompts mais longos, mas aumenta a cache KV na RAM. Por isso, defina o tamanho do contexto antes de avaliar se um modelo cabe.
Um modelo 3B, como llama3.2:3b, requer um download de cerca de 2 GB e precisa de aproximadamente 4 GB de RAM livre para ser executado. Um modelo 7B ou 8B, como mistral:7b ou llama3.1:8b, ocupa cerca de 5 GB em disco e precisa de aproximadamente 8 GB de RAM; 16 GB oferecem uma margem confortável. Um modelo 13B ou 14B precisa de cerca de 16 GB. Qualquer modelo entre 30B e 70B requer uma máquina com muita RAM ou, realisticamente, uma GPU. Numa VPS com CPU, ou não caberá ou responderá tão lentamente que será inútil.
Agora, a velocidade, porque este é o aspeto que costuma ser subestimado. A inferência na CPU é limitada pela largura de banda da memória, não pela velocidade do clock, e uma vCPU partilhada numa VPS tem uma largura de banda moderada. Espere entre unidades e poucas dezenas de tokens por segundo: um modelo Q4 de 7-8B pode atingir 4 a 10 tokens por segundo, e um modelo 3B, 10 a 25. Uma GPU é aproximadamente uma ordem de grandeza mais rápida. Estes valores são deliberadamente aproximados. A abordagem correta é medir a sua própria máquina, como mostra o passo de execução abaixo. Confie no seu eval rate, não num número apresentado num artigo, incluindo este.
A conclusão prática é a seguinte: modelos pequenos quantizados executados na CPU são realmente úteis para redigir, resumir e classificar, se aceitar a velocidade de processamento. Para modelos maiores ou mais rápidos, reserve orçamento para uma instância com GPU. Se preferir ver estas contas aplicadas do princípio ao fim a um modelo específico, executar o Nemotron 3.5 Lightning numa VPS explica qual tag obter, quanta RAM o modelo realmente precisa e se a execução apenas na CPU acompanha o ritmo.
Para comparar um modelo específico com uma máquina específica, estime aqui o consumo de memória:
Instalar o Ollama
Existem duas formas simples. O script oficial é a opção mais fácil numa VPS sem outros componentes:
curl -fsSL https://ollama.com/install.sh | shIsto cria um utilizador de sistema chamado ollama, instala o binário em /usr/local/bin/ollama e regista um serviço systemd chamado ollama.service, que inicia no boot e escuta em 127.0.0.1:11434. Confirme que está ativo:
systemctl status ollama
ollama --versionSe já utiliza Docker, use o contentor:
docker run -d --name ollama \
-p 127.0.0.1:11434:11434 \
-v ollama:/root/.ollama \
--restart always \
ollama/ollamaTenha em atenção o prefixo 127.0.0.1: no mapeamento da porta. Isto liga a porta apenas a localhost. Se escrever -p 11434:11434, a porta fica publicada em todas as interfaces. Esse é o erro alertado na secção de segurança. Escolha um método de instalação. Não execute o script e o contentor ao mesmo tempo, porque os dois processos entram em conflito pela mesma porta.
Obtenha e execute o seu primeiro modelo
ollama pull llama3.2:3b
ollama run llama3.2:3bpull transfere as camadas do modelo para o disco (cerca de 2 GB neste caso). run carrega-as para a memória e apresenta um prompt >>>. Introduza uma pergunta. O primeiro token pode demorar vários segundos enquanto os pesos são carregados do disco para a RAM. Depois, a resposta é transmitida. Introduza /bye para sair do chat. O Ollama continua a executar-se em segundo plano.
Veja o que está carregado e como é utilizado:
ollama psA coluna PROCESSOR mostra a situação real. 100% CPU significa que não existe uma GPU envolvida. Essa é a causa da lentidão. Meça a velocidade real com a flag verbose:
ollama run --verbose llama3.2:3b "Write two sentences about Linux."A linha eval rate apresentada no fim mostra o número de tokens por segundo neste hardware. Esse é o valor que deve usar no planeamento.
Onde os modelos ficam e quanto espaço em disco reservar
Instalados pelo script e executados como um serviço, os modelos ficam no diretório pessoal do utilizador ollama:
sudo du -sh /usr/share/ollama/.ollama/modelsQuando são executados interativamente pelo seu próprio utilizador, ficam em ~/.ollama/models. No contentor, ficam no volume nomeado ollama. Isto é importante porque os pesos quantizados ocupam espaço rapidamente: um modelo 3B ocupa cerca de 2 GB, um modelo 7-8B ocupa cerca de 5 GB e um modelo 14B ocupa cerca de 9 GB. Transfira quatro modelos para os comparar e terá ocupado 20 GB sem se aperceber. Dimensione o disco para os modelos que pretende manter e elimine os restantes com ollama rm <model>. Se o mesmo VPS já executar algo com um consumo elevado de espaço, como PhotoPrism ou Immich com uma biblioteca de fotografias, subtraia primeiro esse espaço ao espaço livre e considere o restante como o orçamento real para os modelos.
Execute-o como um serviço sob o seu controlo
O script de instalação já registou ollama.service, por isso o serviço é reiniciado no boot sem trabalho adicional. A configuração que vale a pena alterar é o tempo durante o qual um modelo permanece residente e, em algumas configurações, o endereço de bind. Ambas devem ficar num drop-in do systemd, para que uma atualização do Ollama não as substitua:
sudo systemctl edit ollama.serviceAdicione isto sob o cabeçalho [Service] apresentado pelo editor:
[Service]
Environment="OLLAMA_KEEP_ALIVE=30m"OLLAMA_KEEP_ALIVE define durante quanto tempo um modelo permanece na memória depois do último pedido (o valor predefinido é 5 minutos). Aumente-o num servidor ao qual faz pedidos durante todo o dia, para evitar recarregar os pesos a cada pedido. Defina-o como 0 num servidor com pouca memória, para libertar a RAM assim que o pedido terminar. Se quiser manter um modelo residente indefinidamente, em vez de o manter durante uma janela fixa, manter um modelo Ollama carregado permanentemente explica o campo keep_alive por pedido e como voltar a aquecer os pesos depois de um reboot, em vez de o fazer no primeiro pedido lento. systemctl edit recarrega os ficheiros das unidades automaticamente, por isso reinicie para aplicar a alteração:
sudo systemctl restart ollamaO ponto de segurança mais importante
Por predefinição, o Ollama fica associado a 127.0.0.1:11434, por isso apenas os processos no próprio VPS conseguem aceder-lhe. Essa predefinição está correta. Mantenha-a.
A API não tem autenticação. Nenhuma. Não existe chave de API, início de sessão nem limite de pedidos. A única lista de permissões disponível, OLLAMA_ORIGINS, apenas controla quais origens de navegador podem chamá-la (CORS); não impede chamadas feitas com curl nem por um script noutro computador. Qualquer pessoa que consiga aceder à porta 11434 pode executar qualquer modelo que tenha descarregado, descarregar modelos novos, apagá-los e manter a CPU ou GPU a 100% de utilização indefinidamente. Scanners como o Shodan indexam milhares de instâncias do Ollama abertas, e uma instância exposta é encontrada e abusada no espaço de algumas horas.
Por isso, há um único erro que nunca deve cometer: não defina OLLAMA_HOST=0.0.0.0 nem abra a porta 11434 na firewall. Isso publica um servidor de inferência sem autenticação em toda a Internet. Nenhuma configuração torna seguro o acesso direto a 11434 em 0.0.0.0, porque nenhuma das definições documentadas do Ollama adiciona autenticação à API local, e uma lista de permissões de origens não é um início de sessão. Esta regra aplica-se a este serviço específico, não proíbe abrir uma porta em qualquer situação: um relay RustDesk autoalojado para acesso remoto ao ambiente de trabalho tem de aceitar tráfego público para funcionar, e isso é possível porque inclui a sua própria autenticação baseada em chaves e uma lista curta e documentada de portas, precisamente o que o Ollama não tem.
Existem três formas seguras de aceder ao modelo a partir de outro local:
- Mantenha-o local. Se o único cliente for outro programa no mesmo VPS, um script cron, um bot ou um servidor MCP que liga as suas ferramentas ao modelo, mantenha a associação em
127.0.0.1e faça esse programa chamarhttp://127.0.0.1:11434. Nada fica exposto e não é necessário mais nada. - Aceda através de um túnel privado. Coloque o VPS numa VPN WireGuard que aloja e gere, defina
OLLAMA_HOSTcomo o endereço do túnel (por exemplo,10.8.0.1, e não0.0.0.0), e permita ligações apenas dos peers da VPN. A Internet pública continua sem ver nada na porta 11434. - Coloque um reverse proxy com autenticação à frente. Termine o TLS e exija uma palavra-passe ou um token no nginx, Traefik ou Caddy; depois encaminhe os pedidos para
127.0.0.1:11434. O Ollama mantém a associação a localhost; apenas o proxy fica à escuta na porta pública. A estrutura é a mesma de colocar um certificado Let's Encrypt no nginx à frente de qualquer serviço local.
A opção do reverse proxy é exatamente a que a interface de chat lhe apresenta a seguir, já com um início de sessão real associado.
Adicionar uma interface de chat com Open WebUI, protegida por TLS
O Open WebUI é uma interface de chat auto-hospedada. Execute-o no Docker e aponte-o para o Ollama local:
docker run -d \
--name open-webui \
--network=host \
-e OLLAMA_BASE_URL=http://127.0.0.1:11434 \
-v open-webui:/app/backend/data \
--restart always \
ghcr.io/open-webui/open-webui:mainA opção --network=host é o detalhe importante numa VPS Linux. Ela coloca o contentor no namespace de rede do host. Assim, 127.0.0.1 dentro do contentor corresponde ao loopback do próprio host, e o contentor alcança o Ollama através de 127.0.0.1:11434 sem que o Ollama escute noutra interface. A configuração de rede bridge apresentada noutro local, --add-host=host.docker.internal:host-gateway com OLLAMA_BASE_URL=http://host.docker.internal:11434, não funciona aqui. Esse nome resolve para o gateway da bridge do Docker. Um serviço ligado a 127.0.0.1 no host não fica acessível através da bridge. Por isso, o Open WebUI fica a indicar que não consegue ligar-se ao Ollama.
A desvantagem da rede do host é que o Open WebUI passa a escutar na porta 8080 do host em todas as interfaces. Qualquer mapeamento -p é ignorado, e o Docker apresenta um aviso a indicar isso. Por isso, feche 8080 tanto no host como na firewall do fornecedor. Deixe o reverse proxy TLS ser o único ponto de acesso público. Na primeira visita, o Open WebUI pede-lhe para criar uma conta de administrador. Essa conta é a sua camada de autenticação. Escolha uma palavra-passe forte.
Para abrir o chat no portátil através de HTTPS, coloque um reverse proxy TLS à frente de 127.0.0.1:8080. Se já encaminha várias aplicações Docker no servidor, Traefik com TLS automático para várias aplicações é a opção mais adequada. Um único bloco de labels emite o certificado e encaminha chat.example.com para o Open WebUI. Esse mesmo encaminhamento baseado numa label por aplicação será usado por todas as outras interfaces Web no servidor, seja um dashboard de estado ou algo mais descontraído, como Halcyon, que apresenta uma biblioteca Jellyfin como uma loja de aluguer dos anos 90, cada uma no seu próprio hostname e protegida pelo seu próprio login. A regra da secção de segurança continua válida: o proxy controla a porta pública e o login, enquanto o Ollama permanece em localhost e a própria porta 8080 do Open WebUI continua protegida pela firewall.
Use o endpoint compatível com OpenAI a partir do seu código
O Ollama disponibiliza um subconjunto da API de chat da OpenAI em /v1. A maioria das bibliotecas cliente da OpenAI funciona depois de alterar duas coisas: a URL base e uma chave descartável.
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:11434/v1", api_key="ollama")
resp = client.chat.completions.create(
model="llama3.2:3b",
messages=[{"role": "user", "content": "Name three Linux distributions."}],
)
print(resp.choices[0].message.content)api_key é obrigatório para a biblioteca cliente, mas é ignorado pelo Ollama. Por isso, qualquer texto serve. model tem de ser o nome de um modelo que já tenha transferido. Um nome desconhecido devolve 404 com model 'x' not found. Uma chamada simples com curl segue o mesmo princípio:
curl http://127.0.0.1:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"llama3.2:3b","messages":[{"role":"user","content":"Hello"}]}'É também assim que integra o modelo em ferramentas de agentes e editores. Se já desenvolve neste servidor, um modelo local pode suportar scripts e plugins juntamente com o Claude Code em execução na VPS dentro do tmux, mantendo o trabalho de rascunho barato e privado fora de uma API paga, enquanto o raciocínio mais exigente continua num modelo alojado.
Modos de falha, com as strings exatas que verá
O processo é "Killed" durante a geração. Inicia um modelo grande e o terminal apresenta Killed, ou o log do servidor (journalctl -u ollama) mostra uma linha que começa por llama-server process has terminated. Esta é a mensagem usada no Ollama 0.40.7, verificada em 21 October 2026; as versões anteriores apresentavam llama runner process has terminated: signal: killed. O OOM killer do Linux interrompeu o processo porque o modelo precisava de mais RAM do que o servidor tem. Confirme a causa com sudo dmesg | grep -i oom. Verá uma linha semelhante a Out of memory: Killed process .... A solução é usar um modelo menor ou com maior quantização, llama3.2:3b em vez de um 13B, ou adicionar swap para que uma carga que excede por pouco a RAM física continue lentamente em vez de terminar. A swap transforma uma falha imediata numa resposta lenta; não torna um modelo 70B viável em 4 GB. A interrupção é silenciosa, exceto se estiver a observar o terminal. Num servidor que consulta remotamente, associar uma unidade OnFailure= a ollama.service, que publica numa instância ntfy que aloja para receber alertas push, permite saber no momento em que o processo termina, em vez de descobrir o problema apenas no pedido seguinte.
Ollama recusa-se a carregar o modelo. O pedido falha imediatamente com um erro, sem terminar o processo, e o log do servidor regista model is too large for system memory (Ollama 0.40.7, verificado em 21 October 2026). As versões anteriores apresentavam Error: model requires more system memory (X GiB) than is available (Y GiB) diretamente na linha de comandos. Esta é a versão controlada da falha anterior: o Ollama calculou os requisitos e parou, em vez de deixar o OOM killer fazê-lo. Escolha um modelo cujo requisito seja inferior à RAM livre (verifique com free -h), reduza o comprimento do contexto ou mude para um VPS maior. Nenhuma flag faz o modelo caber; a memória necessária é real.
O primeiro token demora muito, mas depois tudo funciona. Um modelo frio não apresenta nada durante cinco a trinta segundos e depois começa a transmitir normalmente. Essa pausa ocorre porque os pesos estão a ser carregados do disco para a RAM pela primeira vez. Um armazenamento lento piora o problema. Depois de carregado, o modelo permanece residente durante o período definido por OLLAMA_KEEP_ALIVE. Por isso, o segundo pedido responde imediatamente. Se esse primeiro carregamento exceder um timeout em alguma etapa do caminho do pedido, receberá um erro em vez de uma resposta lenta. Determinar qual camada comunicou context deadline exceeded permite saber se o cliente, o proxy ou o próprio carregamento esgotou o tempo de espera. Aumente esse valor se as pausas forem incómodas e use ollama ps para verificar se há atualmente um modelo carregado.
Tudo está simplesmente lento. Dez tokens por segundo ou menos, sem qualquer erro. Isso é a inferência por CPU a funcionar como esperado. ollama ps mostra 100% CPU, o que significa que não existe GPU. Isto não é um erro, e nenhuma configuração transforma uma CPU numa GPU, porque o principal limite é a largura de banda da memória. Ainda assim, vale a pena testar uma configuração numa VM: o Ollama escolhe o número de threads com base nos cores físicos detetados, e um hypervisor pode comunicá-los incorretamente. Numa sessão ollama run --verbose, experimente /set parameter num_thread 4 (ou o número de vCPUs), execute novamente o mesmo pedido e mantenha o valor que produzir o melhor eval rate. Além disso, use um modelo menor, aceite a velocidade ou mude para uma instância com GPU. Meça a taxa real com --verbose antes de concluir que algo está avariado. Quando a espera resulta do comprimento da resposta e não da velocidade, limitar a resposta com num_predict impede que um modelo propenso a divagar passe minutos a gerar tokens que nunca iria ler.
Ligação recusada a partir de outra máquina. No portátil, o curl atual (8.23.0, verificado em 21 October 2026) apresenta curl: (7) Failed to connect to <ip>:11434 after <n> ms: Could not connect to server, enquanto o curl 8.5.0 incluído no Ubuntu 24.04 apresenta curl: (7) Failed to connect to <ip> port 11434 after <n> ms: Couldn't connect to server. As palavras "Connection refused" só aparecem se adicionar -v, numa linha com connect to <ip> port 11434 from ... failed: Connection refused. Isto funciona como previsto: o Ollama associa-se apenas a localhost. Não "corrija" o problema associando-o a 0.0.0.0, que é precisamente o erro de exposição referido acima. Aceda ao modelo através da VPN ou de um proxy com autenticação.
Expôs a porta 11434 à internet. Se definiu OLLAMA_HOST=0.0.0.0, abriu a firewall e agora vê downloads de modelos que não iniciou ou a CPU fixa em 100% por clientes desconhecidos, o servidor foi encontrado e utilizado. Este é o erro principal, não um caso excecional. Volte a associar o serviço a 127.0.0.1 ou ao endereço da VPN, feche a porta 11434 na firewall e coloque autenticação à frente do serviço. Parta do princípio de que qualquer serviço acessível nesse endereço enquanto a porta esteve aberta foi consultado por terceiros.
Backups e upgrades
Há pouco estado a perder. Os modelos podem ser descarregados novamente, por isso só vale a pena fazer cópias de segurança do volume de dados do Open WebUI, das contas, do histórico de conversas, das definições e de qualquer drop-in do systemd que tenha criado. Faça uma cópia do volume com um contentor descartável:
docker run --rm -v open-webui:/data -v "$PWD":/backup alpine \
tar czf /backup/open-webui.tgz -C /data .Atualize o Ollama executando novamente o script de instalação; atualize o Open WebUI com docker pull ghcr.io/open-webui/open-webui:main e recrie o contentor. Uma nota sobre o disco na linha 0.40: o Ollama 0.40.2 começou a atualizar em segundo plano os modelos obtidos com versões anteriores e mantém as cópias originais como backups. Por isso, esses modelos ocupam espaço adicional em disco até serem removidos. A versão 0.40.3 (11 October 2026) colocou essa atualização em segundo plano em pausa. Verifique df -h depois de uma atualização e consulte as notas da versão para saber qual comando elimina esses backups. Não fixe versões a longo prazo: tanto a qualidade dos modelos como o runtime evoluem rapidamente. Consulte as notas da versão e volte a medir o desempenho no seu próprio servidor, em vez de confiar nos números do último trimestre.
FAQ
Posso mesmo executar um LLM numa VPS apenas com CPU?
Sim, dentro de certos limites. Modelos quantizados pequenos, entre 3B e 8B, executam em CPU e são realmente úteis para elaborar rascunhos, resumir e classificar, embora lentamente, a uma velocidade de um dígito baixo a dois dígitos baixos de tokens por segundo numa vCPU partilhada. Qualquer modelo de 13B ou superior é muito lento ou nem sequer cabe na RAM. Para obter velocidade real ou executar modelos maiores, precisa de uma instância com GPU.
De quanta RAM precisa cada modelo?
Uma regra aproximada para as etiquetas de 4 bits (Q4) que os modelos mais populares usam por predefinição: cerca de 0.5 GB de RAM por mil milhões de parâmetros para os pesos, mais aproximadamente 1 GB de overhead e um pouco mais para o contexto. Assim, um modelo de 3B precisa de cerca de 4 GB livres, um modelo de 7-8B precisa de cerca de 8 GB e um modelo de 14B precisa de cerca de 16 GB. Verifique a margem disponível com free -h e deixe espaço para o sistema operativo e para os restantes serviços do servidor.
A API do Ollama tem autenticação?
Não. O Ollama não tem autenticação integrada, chave de API nem limite de taxa. Qualquer pessoa que consiga aceder à porta 11434 tem controlo total sobre o serviço. A definição OLLAMA_ORIGINS limita apenas as origens de navegador que podem fazer chamadas, não quem pode estabelecer ligação. É precisamente por isso que o serviço fica associado a 127.0.0.1 por predefinição e por que nunca deve expor a porta 11434 em 0.0.0.0 à Internet. Aceda localmente, através de uma VPN privada ou por meio de um reverse proxy que acrescente um início de sessão.
Como adiciono uma interface de chat Web?
Execute o Open WebUI no Docker com --network=host para partilhar o loopback do host e aceder ao Ollama nativo em http://127.0.0.1:11434. Depois, coloque um reverse proxy TLS à frente da porta 8080 para permitir o acesso a partir do seu portátil. Mantenha 8080 fechada na firewall para que o proxy seja a única porta de entrada pública. A própria conta de administrador do Open WebUI fornece o início de sessão. Defina a palavra-passe na primeira execução.
Como lhe faço chamadas a partir da minha própria aplicação?
Use o endpoint compatível com OpenAI em http://127.0.0.1:11434/v1. Aponte qualquer SDK da OpenAI para esse URL base, passe qualquer cadeia como chave de API, porque ela é ignorada, e defina model com o nome de um modelo que tenha obtido. O código existente da OpenAI costuma funcionar sem alterações, exceto pelo URL base e pela chave.