Voltar ao blog

Como instalar Ollama e Open WebUI em uma VPS Linux sem expor sua IA

Rode seus próprios modelos de IA em uma VPS Linux com Ollama e Open WebUI sem deixar a API aberta na internet: escuta local, Nginx com HTTPS, firewall e dimensionamento de RAM e CPU.

Admin
Baie de serveurs câblés dans un datacenter, illustrant l'hébergement d'Ollama et Open WebUI sur un VPS Linux

Hospedar sua própria IA em uma VPS Linux com Ollama e Open WebUI significa manter as conversas no seu servidor e parar de pagar por requisição. O problema: a API do Ollama não tem nenhuma autenticação, então uma porta 11434 aberta na internet é IA de graça para quem a encontrar. Este guia mostra uma instalação em que só o Nginx, com HTTPS, fica acessível de fora.

Por que uma instância Ollama exposta é um problema

O Ollama oferece uma API REST muito prática, mas sem senha e sem chave. Qualquer pessoa que alcance a porta pode listar seus modelos, baixar novos até encher o disco, apagá-los ou disparar gerações que deixam a CPU da sua VPS no talo. Os mantenedores consideram que a autenticação é papel de um proxy reverso, então cabe a você configurá-la.

O risco é real. Em fevereiro de 2026, o buscador de vazamentos LeakIX contava mais de 12 mil instâncias Ollama acessíveis sem autenticação. No mesmo ano, uma falha de gravidade alta (CVE-2026-7482, apelidada de “Bleeding Llama”) permitia ler a memória de um servidor Ollama acessível, sem nenhuma credencial. Uma instância que só escuta localmente fica simplesmente fora do alcance desse tipo de ataque.

A arquitetura que vamos montar

  • Ollama escuta apenas em 127.0.0.1:11434.
  • Open WebUI roda no Docker e escuta apenas em 127.0.0.1:3000.
  • Nginx é o único serviço público: recebe o tráfego HTTPS na porta 443 e repassa para o Open WebUI.
  • O firewall só libera SSH, HTTP (para o certificado) e HTTPS.
  • Open WebUI cuida das contas: um administrador e cadastros fechados.

O guia parte de uma VPS Linux com Ubuntu 24.04 ou Debian 12, acesso sudo, Docker já instalado e um subdomínio, por exemplo ia.seu-dominio.com.br, apontando para o IP do servidor.

Qual VPS escolher: tabela de RAM e CPU sem GPU

Em uma VPS sem placa de vídeo, tudo depende da RAM e do número de núcleos. O modelo precisa caber inteiro na memória, com folga para o contexto da conversa, para o Open WebUI (reserve cerca de 1 GB) e para o sistema. Os tamanhos abaixo são os das versões padrão (quantizadas em 4 bits) publicadas na biblioteca do Ollama.

VPSModelos realistasExemplos (tamanho do download)Uso
4 GB de RAM, 2 vCPUDe 1 a 3 bilhões de parâmetrosgemma3:1b (806 MB), qwen3:1.7b (1,4 GB), llama3.2:3b (2,0 GB)Testes, resumos curtos, assistente simples
8 GB de RAM, 3 vCPUAté 4B com folga, 8B possível mas no limiteqwen3:4b (2,5 GB), gemma3:4b (3,4 GB), qwen3:8b (5,2 GB)Uso pessoal no dia a dia
12 GB de RAM, 4 vCPU8B com folga, 12-14B possível mas no limiteqwen3:8b (5,2 GB), gemma3:12b (8,2 GB), qwen3:14b (9,3 GB)Redação, código, equipe pequena
32 GB de RAM ou mais (servidor dedicado)De 27 a 32Bgemma3:27b (17 GB), qwen3:32b (20 GB)Qualidade maior, respostas lentas sem GPU

Na SoLinux, isso corresponde à VPS Linux 04G (4 GB, 2 núcleos, 45 GB NVMe), à VPS Linux 08G (8 GB, 3 núcleos, 50 GB NVMe) e à VPS Linux 12G (12 GB, 4 núcleos, 70 GB NVMe), sem fidelidade, a partir de 7 € por mês para a 04G, disponíveis na França, na Alemanha e em Nova York. Para uso frequente, a 08G é o melhor ponto de partida; a 12G vale a pena quando você quer um modelo 8B com folga ou vários usuários.

Seja realista quanto à velocidade: sem GPU, um modelo 7-8B escreve a resposta palavra por palavra, a poucas palavras por segundo, e a CPU fica em 100 % durante a geração. Modelos de 3-4B costumam ser o melhor equilíbrio. O armazenamento NVMe pesa sobretudo no carregamento inicial do modelo na memória.

Passo 1: preparar o servidor e o firewall

Comece atualizando o sistema e depois feche tudo o que não for indispensável. Com UFW:

sudo apt update && sudo apt upgrade -y
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Se preferir usar o nftables diretamente (e não junto com o UFW), este é o equivalente mínimo para a chain de entrada, em /etc/nftables.conf:

table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iif "lo" accept
    ip protocol icmp accept
    ip6 nexthdr icmpv6 accept
    tcp dport { 22, 80, 443 } accept
  }
}
sudo nft -c -f /etc/nftables.conf   # confere a sintaxe
sudo systemctl enable --now nftables

Armadilha clássica: uma porta publicada pelo Docker com -p 3000:8080 fica aberta em todas as interfaces e passa por cima das regras do UFW, porque o Docker escreve as próprias regras de firewall. Por isso este guia não publica nenhuma porta do Docker.

Passo 2: instalar o Ollama e mantê-lo local

O Ollama é instalado no Linux com o script oficial, que cria um usuário ollama e um serviço systemd:

curl -fsSL https://ollama.com/install.sh | sh

Depois, confira se o serviço está rodando:

ollama --version
sudo systemctl enable --now ollama
sudo systemctl status ollama

Por padrão, o Ollama escuta em 127.0.0.1:11434. Muitos tutoriais mandam colocar OLLAMA_HOST em 0.0.0.0 para o Docker conseguir acessá-lo: é exatamente isso que expõe a API. Em vez disso, fixe o endereço local de forma explícita, com um override do systemd que sobrevive às atualizações:

sudo systemctl edit ollama

Adicione estas linhas na área indicada:

[Service]
Environment="OLLAMA_HOST=127.0.0.1:11434"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Environment="OLLAMA_NUM_PARALLEL=1"

As duas últimas variáveis limitam o Ollama a um modelo carregado e uma requisição por vez, o que evita estourar a RAM de uma VPS sem GPU. Recarregue e confira a escuta:

sudo systemctl daemon-reload
sudo systemctl restart ollama
sudo ss -tlnp | grep 11434
# esperado: 127.0.0.1:11434, nunca 0.0.0.0:11434 nem [::]:11434
curl http://127.0.0.1:11434
# esperado: Ollama is running

Em seguida, baixe um modelo adequado à sua VPS e teste pela linha de comando:

ollama pull qwen3:4b
ollama run qwen3:4b "Explique em uma frase o que é um proxy reverso."
ollama list

Passo 3: subir o Open WebUI com Docker, sem porta pública

O comando de início rápido do Open WebUI publica a porta 3000 e acessa o Ollama via host.docker.internal, o que obriga o Ollama a escutar em todas as interfaces. Aqui fazemos diferente: o contêiner compartilha a pilha de rede do host (--network=host), acessa o Ollama em 127.0.0.1 e só escuta em 127.0.0.1:3000, graças às variáveis HOST e PORT.

# chave secreta fixa: sem ela, as sessões caem a cada reinício
sudo mkdir -p /etc/open-webui
openssl rand -hex 32 | sudo tee /etc/open-webui/secret > /dev/null
sudo chmod 600 /etc/open-webui/secret

DOMINIO=ia.seu-dominio.com.br   # seu subdomínio

sudo docker run -d --name open-webui \
  --network=host \
  -e HOST=127.0.0.1 \
  -e PORT=3000 \
  -e OLLAMA_BASE_URL=http://127.0.0.1:11434 \
  -e WEBUI_SECRET_KEY="$(sudo cat /etc/open-webui/secret)" \
  -e CORS_ALLOW_ORIGIN="https://$DOMINIO" \
  -v open-webui:/app/backend/data \
  --restart always \
  ghcr.io/open-webui/open-webui:main

O volume open-webui guarda contas, conversas e configurações. Em produção, você pode trocar a tag main por um número de versão específico e decidir quando atualizar. Confira a escuta depois de um minuto (a primeira inicialização demora um pouco):

sudo ss -tlnp | grep 3000
# esperado: 127.0.0.1:3000
curl -I http://127.0.0.1:3000

Passo 4: criar a conta de administrador antes de expor qualquer coisa

A primeira conta criada no Open WebUI vira administradora. Não deixe esse lugar para um desconhecido que encontre seu subdomínio antes de você: crie a conta antes de configurar o Nginx, por um túnel SSH. No seu computador:

ssh -L 3000:127.0.0.1:3000 usuario@IP_DA_VPS

Depois abra http://localhost:3000 no navegador do seu computador e crie a conta de administrador com uma senha longa e exclusiva. Em seguida, nas configurações de administração (seção de usuários ou de cadastros, conforme a versão):

  • desative os novos cadastros;
  • se precisar deixá-los abertos por um tempo, mantenha o papel padrão dos novos usuários como pendente (pending), para aprovar cada conta você mesmo;
  • crie você mesmo as contas dos seus colegas pela gestão de usuários.

Nunca desative a autenticação (WEBUI_AUTH=False) em uma instância acessível pela internet.

Passo 5: Nginx com HTTPS na frente do Open WebUI

Instale o Nginx e o Certbot:

sudo apt install -y nginx certbot python3-certbot-nginx

Adicione um limite de tentativas de login em /etc/nginx/conf.d/limites.conf:

limit_req_zone $binary_remote_addr zone=owui_login:10m rate=5r/m;

Depois crie /etc/nginx/sites-available/open-webui. O Open WebUI usa WebSockets e transmite as respostas em streaming: é preciso usar HTTP/1.1, repassar os cabeçalhos Upgrade e desligar o buffering, senão as respostas chegam de uma vez só ou são cortadas.

server {
    listen 80;
    server_name ia.seu-dominio.com.br;

    client_max_body_size 50M;

    # limita as tentativas de senha
    location = /api/v1/auths/signin {
        limit_req zone=owui_login burst=5 nodelay;
        proxy_pass http://127.0.0.1:3000;
        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;
    }

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_buffering off;
        proxy_cache off;
        proxy_read_timeout 1800s;
        proxy_send_timeout 1800s;
    }
}

Ative o site, teste a configuração e peça o certificado. O Certbot adiciona sozinho o bloco HTTPS na porta 443 e o redirecionamento a partir do HTTP:

sudo ln -s /etc/nginx/sites-available/open-webui /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d ia.seu-dominio.com.br --redirect
sudo certbot renew --dry-run

Para uma equipe pequena, você pode acrescentar uma segunda barreira com auth_basic no bloco location /, ou restringir o acesso a poucos IPs com allow e deny. Essas proteções se somam à conta do Open WebUI, não a substituem.

Conferir que nada está exposto

No servidor, liste as portas em escuta: só 22, 80 e 443 podem aparecer em um endereço público.

sudo ss -tlnp

No seu computador, teste o IP da VPS: as portas 11434 e 3000 devem recusar a conexão ou não responder. Só o seu subdomínio em HTTPS, aberto no navegador, deve mostrar a tela de login.

nc -zv -w 3 IP_DA_VPS 11434   # deve falhar
nc -zv -w 3 IP_DA_VPS 3000    # deve falhar

Manter a instalação atualizada

  • Ollama: rode de novo o script de instalação oficial. O override do systemd é mantido; mesmo assim, confira a escuta com ss -tlnp depois de cada atualização. A falha CVE-2026-7482 está corrigida desde a versão 0.17.1: confira a sua com ollama --version e não deixe uma versão antiga rodando.
  • Open WebUI: docker pull da imagem, depois docker stop, docker rm e o mesmo comando docker run. O volume preserva seus dados.
  • Backups: faça backup regular do volume open-webui (contas e conversas); os modelos podem ser baixados de novo.
  • Logs: journalctl -u ollama, docker logs open-webui e /var/log/nginx/ para identificar tentativas de login repetidas.

Perguntas frequentes

Preciso de GPU para rodar o Ollama em uma VPS?

Não. O Ollama funciona só com a CPU. As respostas são mais lentas do que com placa de vídeo, mas um modelo de 3 a 8 bilhões de parâmetros é perfeitamente usável em uma VPS com 8 a 12 GB de RAM.

Como usar a API do Ollama de outra máquina sem expô-la?

Use um túnel SSH: ssh -L 11434:127.0.0.1:11434 usuario@IP_DA_VPS e depois consulte http://localhost:11434 no seu computador. Para um aplicativo de terceiros, o Open WebUI também pode gerar chaves de API por usuário, atrás do seu Nginx com HTTPS.

O Open WebUI não mostra nenhum modelo. O que fazer?

Confira se ollama list retorna modelos, se curl http://127.0.0.1:11434 responde e se o contêiner foi iniciado com --network=host e OLLAMA_BASE_URL=http://127.0.0.1:11434. A conexão também pode ser verificada nas configurações de administração, na seção de conexões.

Quantas pessoas podem usar ao mesmo tempo?

Sem GPU, conte com uma geração por vez; as outras requisições aguardam na fila. Para dois ou três usuários ocasionais, uma VPS 12G com um modelo 4B ou 8B dá conta; acima disso, um servidor dedicado com mais núcleos e RAM passa a ser necessário.