OpenObserve no Ubuntu: servidor dedicado, S3, GCS, OCI e MinIO

Mascote LinuxPro administrando o OpenObserve em um servidor Ubuntu com armazenamento de observabilidade

Depois de conhecer o OpenObserve e sua plataforma unificada de logs, métricas e traces, o próximo passo é operá-lo em um servidor Ubuntu dedicado sem Docker. Este guia instala o binário oficial como serviço systemd, mantém a porta do OpenObserve no loopback, publica a interface por nginx com TLS e mostra quando usar disco local ou S3, Google Cloud Storage, Oracle Cloud Object Storage e MinIO.

Escopo: é uma instalação de nó único. Ela é indicada quando uma janela de manutenção e uma restauração testada são aceitáveis. Alta disponibilidade é outra arquitetura: use o desenho HA oficial com os componentes exigidos e faça uma homologação antes de mover dados importantes.

Revisão técnica: 7 de outubro de 2026. Receita para instalação nova com sudo em Ubuntu e Bash. Escolha disco ou bucket antes da primeira ingestão. Os provedores são alternativas, não etapas cumulativas; não execute como migração sobre uma instância existente.

Arquitetura e dimensionamento

Cenário Metadados Dados de telemetria Quando usar
Servidor dedicado com disco SQLite local Disco local em Parquet Ambiente pequeno ou médio, operação simples e retenção limitada.
Servidor pequeno + object storage SQLite local S3, GCS, Oracle Object Storage ou MinIO Quando capacidade e durabilidade devem sair do disco da VM.
Alta disponibilidade PostgreSQL Object storage Serviço crítico, escala horizontal e tolerância a falhas.

O modo local é o padrão: usa SQLite para metadados e pode gravar dados de streams no disco ou em armazenamento compatível com S3. Para um bucket em nó único, defina ZO_LOCAL_MODE_STORAGE=s3. Não troque o backend de uma instância com dados sem plano de migração, backup e teste de restauração: apontar para um bucket não transporta automaticamente os Parquet existentes.

Clientes HTTPS chegam ao nginx e ao OpenObserve no loopback; metadados, WAL e cache locais, Parquet no bucket

Bucket não transforma nó único em HA. SQLite e dados de ingestão em andamento continuam locais. Perder esses componentes pode impedir a recuperação completa, mesmo que os objetos já enviados continuem no bucket. Na opção de disco, os Parquet também ficam locais. Veja a arquitetura oficial.

Dimensione com um piloto representativo: crescimento diário, retenção, pico de ingestão, concorrência de consultas, CPU, memória e I/O. Reserve espaço para WAL, cache e compactação e meça a recuperação após falhas. Não existe correspondência universal entre terabytes armazenados e vCPUs. Monitore bytes livres e inodes; RAID não substitui backup.

1. Preparar o Ubuntu e criar o usuário do serviço

Atualize o sistema e instale apenas os utilitários usados para baixar, validar e descompactar o arquivo. O processo do OpenObserve roda com uma conta de sistema sem login; o binário permanece sob controle do root e os dados ficam em /var/lib/openobserve.

sudo apt update
sudo apt install -y ca-certificates curl openssl tar

sudo adduser --system --group --home /var/lib/openobserve \
  --shell /usr/sbin/nologin openobserve
sudo install -d -o root -g root -m 0755 /usr/local/lib/openobserve
sudo install -d -o openobserve -g openobserve -m 0750 /var/lib/openobserve
sudo install -d -o root -g openobserve -m 0750 /etc/openobserve

Não use uma conta com shell administrativo para o serviço. A separação permite limitar quem lê as credenciais e quem escreve nos dados locais.

2. Baixar e instalar o binário oficial

Consulte primeiro a página oficial de downloads e troque OO_VERSION por uma release estável que você decidiu homologar. O exemplo usa v1.0.4, release estável conferida em 7 de outubro de 2026, sem prometer que será a mais recente no futuro. Ele detecta amd64 ou arm64; para máquinas com glibc antiga, a documentação orienta usar o pacote linux-amd64-musl, com possível custo de desempenho.

Selecione a edição Open Source nos downloads; artefatos Enterprise têm outros nomes. Execute o bloco em Bash. Na página Downloads, selecione Open Source, a versão e a arquitetura; use o botão Show SHA256 do pacote correspondente. O hash deve ser o publicado pelo fornecedor para esse artefato.

(
set -euo pipefail
export OO_VERSION=v1.0.4
case "$(dpkg --print-architecture)" in
  amd64|arm64) OO_ARCH="$(dpkg --print-architecture)" ;;
  *) echo "Arquitetura não suportada"; exit 1 ;;
esac

OO_TARBALL="openobserve-${OO_VERSION}-linux-${OO_ARCH}.tar.gz"
OO_URL="https://downloads.openobserve.ai/releases/openobserve/${OO_VERSION}/${OO_TARBALL}"

WORK=$(mktemp -d)
trap 'rm -rf -- "$WORK"' EXIT
cd "$WORK"
curl -fL -o "$OO_TARBALL" "$OO_URL"
read -r -p "SHA-256 oficial desse arquivo: " EXPECTED
[[ "$EXPECTED" =~ ^[[:xdigit:]]{64}$ ]] || { echo "Hash inválido"; exit 1; }
printf '%s  %s\n' "$EXPECTED" "$OO_TARBALL" | sha256sum --check -

mkdir "$WORK/unpack"
tar -xzf "$OO_TARBALL" -C "$WORK/unpack"
sudo install -o root -g root -m 0755 \
  "$WORK/unpack"/openobserve \
  "/usr/local/lib/openobserve/openobserve-${OO_VERSION}"
sudo ln -sfn "/usr/local/lib/openobserve/openobserve-${OO_VERSION}" \
  /usr/local/bin/openobserve

/usr/local/bin/openobserve --version
)

O checksum é uma etapa obrigatória antes de executar um binário baixado. Guarde a versão instalada: atualizações devem baixar uma nova release, validar o hash, instalar outro arquivo e só então trocar o link simbólico durante uma janela de manutenção.

3. Criar o arquivo de ambiente

O OpenObserve é configurado por variáveis de ambiente. Crie um arquivo que só root e o grupo do serviço possam ler. A senha raiz é usada na primeira inicialização; gere uma senha longa, salve-a em um cofre e substitua os valores de exemplo antes de iniciar o serviço.

sudo install -o root -g openobserve -m 0640 /dev/null /etc/openobserve/openobserve.env
sudo tee /etc/openobserve/openobserve.env > /dev/null <<'EOF'
ZO_ROOT_USER_EMAIL=admin@example.com
ZO_ROOT_USER_PASSWORD=TROQUE_POR_UMA_SENHA_LONGA_E_ALEATORIA

# Nó único, dados no disco local
ZO_LOCAL_MODE=true
ZO_LOCAL_MODE_STORAGE=disk
ZO_DATA_DIR=/var/lib/openobserve

# O nginx será a única entrada pública
ZO_HTTP_ADDR=127.0.0.1
ZO_HTTP_PORT=5080
ZO_GRPC_ADDR=127.0.0.1
ZO_WEB_URL=https://o2.exemplo.com
ZO_CORS_ALLOWED_ORIGINS=https://o2.exemplo.com

# Ajuste a retenção ao piloto e ao espaço disponível
ZO_COMPACT_DATA_RETENTION_DAYS=30
EOF
sudo chown root:openobserve /etc/openobserve/openobserve.env
sudo chmod 0640 /etc/openobserve/openobserve.env

# Gere uma senha para copiar ao cofre; depois cole-a no arquivo acima.
openssl rand -hex 32
sudoedit /etc/openobserve/openobserve.env

ZO_HTTP_ADDR=127.0.0.1 evita publicar a porta 5080 diretamente. Definimos também ZO_GRPC_ADDR=127.0.0.1 para que a porta gRPC padrão não fique aberta na rede. Se o OpenObserve for servido em um subcaminho, como https://exemplo.com/logs/, use ZO_BASE_URI=/logs e ajuste o proxy.

Não inicie com a senha de exemplo. Substitua senha e domínio com sudoedit; para bucket, aplique agora o bloco da seção 6. O comando de criação do arquivo é para instalação nova: não o repita sobre a configuração existente.

4. Rodar como serviço systemd

Crie a unidade. O limite de descritores segue a recomendação do guia oficial; Restart=on-failure tenta recuperar falhas, mas não corrige configuração inválida; acompanhe logs e o limite de reinícios.

sudo tee /etc/systemd/system/openobserve.service > /dev/null <<'EOF'
[Unit]
Description=OpenObserve
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=openobserve
Group=openobserve
WorkingDirectory=/var/lib/openobserve
EnvironmentFile=/etc/openobserve/openobserve.env
ExecStart=/usr/local/bin/openobserve
ExecStop=/bin/kill -s QUIT $MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now openobserve
sudo systemctl status openobserve --no-pager
curl -fsS http://127.0.0.1:5080/healthz; echo
sudo journalctl -u openobserve -n 100 --no-pager

A resposta esperada do health check é {"status":"ok"}. Se o serviço não iniciar, confirme permissões em /var/lib/openobserve, a sintaxe do arquivo de ambiente e o log do journalctl. Não altere a senha raiz em uma instância já inicializada esperando recriar o usuário: essas variáveis são necessárias apenas no primeiro start.

5. Instalar nginx e publicar com TLS

Depois de validar o OpenObserve no loopback, publique-o com um nome DNS próprio, por exemplo o2.exemplo.com. Antes de pedir o certificado, crie os registros A (e AAAA, se usar IPv6) apontando para o servidor e confirme que as portas 80 e 443 chegam até ele. O OpenObserve continua em 127.0.0.1:5080; somente o nginx ficará exposto.

Instalar o proxy reverso

sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx
sudo systemctl enable --now nginx
sudo nginx -t
sudo systemctl status nginx --no-pager

Se o host usa UFW, preserve primeiro o acesso administrativo e libere somente HTTP/HTTPS. Em provedores de nuvem, faça a mesma liberação no firewall ou security group do provedor.

# Execute somente se UFW já faz parte da política deste host.
sudo ufw allow OpenSSH  # somente se o SSH usa o perfil/porta padrão
sudo ufw allow 'Nginx Full'
sudo ufw status verbose

Crie primeiro um virtual host HTTP. Ele retorna 404 deliberadamente e não entrega a aplicação em HTTP; o Certbot configurará o desafio HTTP-01 do Let’s Encrypt. Não publique a porta 5080 nem a 5081 no firewall.

sudo tee /etc/nginx/sites-available/openobserve >/dev/null <<'EOF'
server {
    listen 80;
    listen [::]:80;
    server_name o2.exemplo.com;

    location / {
        return 404;
    }
}
EOF

sudo ln -s /etc/nginx/sites-available/openobserve /etc/nginx/sites-enabled/openobserve
sudo nginx -t
sudo systemctl reload nginx
curl -sSI http://o2.exemplo.com/

Use um subdomínio, como no exemplo. Se optar por publicar sob um caminho, como https://exemplo.com/logs/, siga a documentação do OpenObserve e defina ZO_BASE_URI=/logs; apenas acrescentar location /logs/ no nginx não é suficiente.

Emitir e renovar o certificado

Com o DNS propagado e a porta 80 acessível publicamente, o plugin nginx do Certbot pode obter o certificado e instalar o bloco HTTPS. Faça cópia da configuração antes de permitir que o Certbot a altere.

sudo cp -a /etc/nginx /etc/nginx.backup.$(date +%F)
sudo certbot --nginx --redirect -d o2.exemplo.com
sudo nginx -t
sudo systemctl reload nginx
sudo certbot renew --dry-run
curl -sSI https://o2.exemplo.com/

Ativar o proxy somente no bloco HTTPS

Edite /etc/nginx/sites-available/openobserve. No bloco 443 criado pelo Certbot, substitua apenas o location / que retorna 404 pelo bloco abaixo. Preserve as diretivas TLS e mantenha a porta 80 com redirecionamento e renovação.

location / {
    client_max_body_size 20m;
    proxy_pass http://127.0.0.1:5080;
    proxy_http_version 1.1;
    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_set_header X-Envoy-External-Address "";
    proxy_buffering off;
    proxy_read_timeout 300s;
}

Os valores 20m e 300s são escolhas iniciais desta receita, não universais. Lotes acima do limite de corpo recebem 413: ajuste o coletor antes de aumentar o limite indiscriminadamente. Buffering desativado evita represar respostas em fluxo. O exemplo supõe clientes chegando diretamente ao nginx, sem outro proxy à frente.

sudo nginx -t && sudo systemctl reload nginx
curl --fail --silent --show-error https://o2.exemplo.com/healthz

Limite de corpo e diretivas de proxy na documentação nginx.

O --redirect redireciona HTTP para HTTPS. O teste renew --dry-run confirma a renovação antes da data de expiração. Para certificados corporativos ou validação DNS-01, não rode o comando acima: instale o certificado conforme a política da organização e mantenha o mesmo proxy para 127.0.0.1:5080.

ss -lntp | grep -E ':(80|443|5080|5081)\b'

O resultado deve mostrar nginx em 80/443 e as portas 5080 e 5081 do OpenObserve apenas em loopback, nunca em 0.0.0.0. Não exponha a interface, APIs de ingestão ou o endpoint MCP em HTTP simples.

Validar ingestão e consulta antes dos dados reais

Se escolheu bucket, conclua primeiro a seção 6; só depois envie o evento. Health check não comprova ingestão. Use o evento JSON e a consulta SQL do laboratório introdutório, trocando a URL por https://o2.exemplo.com e o usuário pela conta criada. Confirme o evento, reinicie o serviço e consulte novamente.

O proxy mostrado atende HTTP, não publica OTLP/gRPC em 5081. Configure o exporter para o protocolo e endpoint corretos; não abra 5081 só porque ele usa gRPC por padrão.

6. Usar S3, GCS, Oracle Cloud ou MinIO

Configure o backend antes da primeira ingestão. Em instância existente, trocar variáveis não migra os dados. Com object storage, SQLite e WAL continuam no disco local. Edite o mesmo arquivo /etc/openobserve/openobserve.env, mude ZO_LOCAL_MODE_STORAGE para s3, acrescente um bloco do provedor e reinicie o serviço. Crie o bucket antes, use um prefixo exclusivo por ambiente e teste escrita, leitura e retenção em ambiente de homologação.

AWS S3

Em EC2, prefira uma IAM Role com acesso mínimo ao bucket e ao prefixo em vez de credenciais estáticas. Para S3 padrão, não defina ZO_S3_SERVER_URL; o SDK busca a identidade da instância. Fora da AWS, injete as chaves por um gerenciador de segredos ou pelo arquivo de ambiente com permissão 0640; nunca as inclua em Git.

# Em EC2 com IAM Role: não defina AWS_ACCESS_KEY_ID nem AWS_SECRET_ACCESS_KEY
ZO_LOCAL_MODE_STORAGE=s3
ZO_S3_PROVIDER=s3
ZO_S3_REGION_NAME=us-east-1
ZO_S3_BUCKET_NAME=openobserve-producao
ZO_S3_BUCKET_PREFIX=openobserve/producao/
# Fora da AWS: entregue estes valores por cofre de segredos
AWS_ACCESS_KEY_ID=CHAVE_DE_ACESSO
AWS_SECRET_ACCESS_KEY=SEGREDO_DE_ACESSO
ZO_LOCAL_MODE_STORAGE=s3
ZO_S3_PROVIDER=s3
ZO_S3_REGION_NAME=us-east-1
ZO_S3_BUCKET_NAME=openobserve-producao
ZO_S3_BUCKET_PREFIX=openobserve/producao/

Google Cloud Storage

O GCS pode usar a API compatível com S3. Crie uma chave HMAC com acesso restrito ao bucket e use HTTP/1, exigido pela configuração documentada:

ZO_LOCAL_MODE_STORAGE=s3
ZO_S3_SERVER_URL=https://storage.googleapis.com
ZO_S3_REGION_NAME=auto
ZO_S3_ACCESS_KEY=CHAVE_HMAC_GCS
ZO_S3_SECRET_KEY=SEGREDO_HMAC_GCS
ZO_S3_BUCKET_NAME=openobserve-producao
ZO_S3_BUCKET_PREFIX=openobserve/producao/
ZO_S3_FEATURE_HTTP1_ONLY=true
ZO_S3_PROVIDER=s3

Também existe integração direta: use ZO_S3_PROVIDER=gcs e, quando não houver identidade da instância, forneça em ZO_S3_ACCESS_KEY o caminho para a chave JSON da conta de serviço, com permissão de leitura apenas para o usuário openobserve.

Oracle Cloud Object Storage

O Object Storage da Oracle oferece API S3-compatible. Use uma Customer Secret Key, mantenha a URL no formato da sua tenancy e região e valide a configuração em um bucket de teste antes de gravar dados de produção.

ZO_LOCAL_MODE_STORAGE=s3
ZO_S3_SERVER_URL=https://SEU_NAMESPACE.compat.objectstorage.SUA_REGIAO.oci.customer-oci.com
ZO_S3_REGION_NAME=SUA_REGIAO
ZO_S3_ACCESS_KEY=OCI_ACCESS_KEY
ZO_S3_SECRET_KEY=OCI_CUSTOMER_SECRET_KEY
ZO_S3_BUCKET_NAME=openobserve-producao
ZO_S3_BUCKET_PREFIX=openobserve/producao/
ZO_S3_PROVIDER=s3
ZO_S3_FEATURE_FORCE_HOSTED_STYLE=false

MinIO

MinIO é uma opção S3-compatible para datacenter, outra VM ou Kubernetes. Crie o bucket antes do start e use TLS entre o OpenObserve e o endpoint. Um MinIO no mesmo host não cria redundância: uma falha da máquina pode derrubar aplicação e dados ao mesmo tempo.

ZO_LOCAL_MODE_STORAGE=s3
ZO_S3_SERVER_URL=https://minio.exemplo.com
ZO_S3_REGION_NAME=us-east-1
ZO_S3_ACCESS_KEY=MINIO_ACCESS_KEY
ZO_S3_SECRET_KEY=MINIO_SECRET_KEY
ZO_S3_BUCKET_NAME=openobserve-producao
ZO_S3_BUCKET_PREFIX=openobserve/producao/
ZO_S3_PROVIDER=minio
sudoedit /etc/openobserve/openobserve.env
sudo systemctl restart openobserve
sudo journalctl -u openobserve -f

RustFS como destino S3-compatible

A documentação atual também descreve RustFS como destino. Use o endpoint HTTPS da API S3, não o console; crie bucket e credencial da aplicação antes:

ZO_LOCAL_MODE_STORAGE=s3
ZO_S3_PROVIDER=s3
ZO_S3_SERVER_URL=https://s3.exemplo.com
ZO_S3_REGION_NAME=us-east-1
ZO_S3_ACCESS_KEY=CHAVE_DA_APLICACAO
ZO_S3_SECRET_KEY=SEGREDO_DA_APLICACAO
ZO_S3_BUCKET_NAME=openobserve-producao
ZO_S3_BUCKET_PREFIX=openobserve/producao/
ZO_S3_FEATURE_FORCE_HOSTED_STYLE=false

Homologue escrita, leitura, reinício e retenção; esta revisão não executou integração contra esse backend. Autorize o bucket/prefixo necessário, incluindo operações de exclusão usadas pela retenção. Referência oficial dos backends.

7. Integrar agentes de IA e aplicações LLM

Sim: o OpenObserve pode participar de um fluxo com LLM de duas formas. A primeira é observar a aplicação de IA via OpenTelemetry — tokens, latência, modelo, erros e chamadas de ferramentas viram traces e métricas. A segunda é conectar um cliente MCP para consultar logs, métricas e traces em linguagem natural.

O endpoint MCP segue o formato https://o2.exemplo.com/api/ID_DA_ORGANIZACAO/mcp. A documentação informa suporte em Open Source, Enterprise e Cloud. Use somente HTTPS e uma conta separada; não registre tokens em repositórios, chat ou arquivos compartilhados.

Configure o cliente conforme a documentação de MCP. Basic Auth usa Base64, não criptografia. Não coloque tokens em argumentos de processos compartilhados; proteja o arquivo de configuração do cliente e os backups. unset não apaga uma credencial que o cliente já gravou em disco.

Segurança no MCP: na edição Open Source, chamadas MCP usam os privilégios completos da conta conectada; RBAC granular está disponível na Enterprise e no Cloud. No OSS, use uma conta exclusiva para rastreabilidade e rotação, mas não a trate como privilégio mínimo. Restrinja o endpoint por rede/IP, peça confirmação para operações de escrita e considere qualquer texto vindo de logs como dado não confiável — inclusive contra prompt injection.

Telemetria de IA pode conter prompts, respostas, identificadores e documentos recuperados. Defina antes quais atributos podem sair da aplicação, faça redaction quando necessário e alinhe retenção, LGPD e acesso. Não envie segredos ou chaves de API em logs ou spans.

Operação, backup e atualização

  • Monitore o próprio serviço: CPU, RAM, I/O, espaço livre, erros de ingestão, tempo de consulta e crescimento do bucket.
  • Proteja os metadados: em nó único, o SQLite local contém configurações, usuários, dashboards e alertas; faça backup consistente de /var/lib/openobserve e do arquivo de ambiente, mantendo segredos protegidos.
  • Teste restauração: recuperar apenas Parquet no bucket não recria automaticamente usuários, dashboards ou regras.
  • Atualização e retorno: faça backup consistente, homologue a release e instale o binário lado a lado. Pare o serviço antes de trocar o link. Guardar o binário anterior não garante downgrade: migrações de metadados podem exigir restaurar também o backup pré-atualização.
  • Revise retenção: ZO_COMPACT_DATA_RETENTION_DAYS tem padrão de 3650 dias; defina uma política explícita e compatível com as regras de lifecycle do bucket.

Backup consistente e restauração

Neste nó único, agende uma janela, interrompa o envio ou garanta filas suficientes nos coletores, pare o serviço e copie o diretório de dados inteiro e a configuração para armazenamento protegido. Preserve proprietário e permissões. Não copie apenas o SQLite enquanto ele está sendo alterado.

No modo bucket, alinhe o ponto de recuperação dos metadados com os objetos e a política de backup. Uma cópia local não congela o bucket. Restaure primeiro em rede isolada, com a mesma versão; valide usuários, streams, dashboards e consultas antes de liberar ingestão. Registre tempo de recuperação e perda máxima aceitável.

Falhas comuns

  • 502: confira serviço e resposta no loopback antes de alterar nginx.
  • 413: compare tamanho do lote com os limites do proxy e do backend.
  • 401/403: confira credencial, organização e permissões; não desative autenticação.
  • Erro no bucket: verifique endpoint, região, relógio, validade das chaves e certificados. Não desabilite TLS.
  • Disco cheio: examine WAL, cache e logs; não apague arquivos internos manualmente.

Veja também os comandos essenciais do systemd.

Checklist final

  • Binário oficial instalado e SHA-256 conferido antes da execução.
  • Serviço openobserve ativo, com dados graváveis apenas pela conta dedicada.
  • Portas 5080 e 5081 ligadas ao loopback; interface disponível somente em HTTPS pelo nginx.
  • Senha raiz e credenciais de bucket armazenadas fora de Git, chat e backups sem criptografia.
  • Retenção calculada com a ingestão real, não com uma taxa de compressão presumida.
  • Teste de escrita/leitura no bucket e restauração de metadados concluídos antes da produção.

Quer avaliar outro backend de objetos com API S3? Veja RustFS no Linux: instalação por binário e Docker. Compatibilidade S3 não garante integração sem ajustes: valide endpoint, região, autenticação e as operações usadas pelo OpenObserve em um laboratório antes de migrar dados.

Fontes oficiais