OpenObserve en Ubuntu: servidor dedicado, S3, GCS, OCI y MinIO

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

Después de conocer OpenObserve y su plataforma unificada de logs, métricas y traces, el siguiente paso es operarlo en un servidor Ubuntu dedicado sin Docker. Esta guía instala el binario oficial como servicio systemd, mantiene el puerto de OpenObserve en loopback, publica la interfaz con nginx y TLS y muestra cuándo usar disco local o S3, Google Cloud Storage, Oracle Cloud Object Storage y MinIO.

Alcance: es una instalación de un único nodo. Está indicada cuando una ventana de mantenimiento y una restauración probada son aceptables. La alta disponibilidad es otra arquitectura: use el diseño HA oficial con los componentes exigidos y haga una homologación antes de mover datos importantes.

Revisión técnica: 7 de octubre de 2026. Receta para instalación nueva con sudo en Ubuntu y Bash. Elija disco o bucket antes de la primera ingesta. Los proveedores son alternativas, no pasos acumulativos; no ejecute como migración sobre una instancia existente.

Arquitectura y dimensionamiento

Escenario Metadatos Datos de telemetría Cuándo usar
Servidor dedicado con disco SQLite local Disco local en Parquet Entorno pequeño o medio, operación sencilla y retención limitada.
Servidor pequeño + object storage SQLite local S3, GCS, Oracle Object Storage o MinIO Cuando la capacidad y la durabilidad deben salir del disco de la VM.
Alta disponibilidad PostgreSQL Object storage Servicio crítico, escala horizontal y tolerancia a fallos.

El modo local es el predeterminado: usa SQLite para los metadatos y puede escribir datos de streams en el disco o en almacenamiento compatible con S3. Para un bucket en un único nodo, defina ZO_LOCAL_MODE_STORAGE=s3. No cambie el backend de una instancia con datos sin un plan de migración, copia de seguridad y prueba de restauración: apuntar a un bucket no traslada automáticamente los Parquet existentes.

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

Bucket no convierte un nodo único en HA. SQLite y datos de ingesta en curso siguen siendo locales. Perder estos componentes puede impedir la recuperación completa, aunque los objetos ya enviados permanezcan en el bucket. En la opción de disco, los Parquet también quedan locales. Véase la arquitectura oficial.

Dimensione con un piloto representativo: crecimiento diario, retención, pico de ingesta, concurrencia de consultas, CPU, memoria e I/O. Reserve espacio para WAL, caché y compactación y mida la recuperación tras fallos. No existe una correspondencia universal entre terabytes almacenados y vCPUs. Monitorice bytes libres e inodes; RAID no sustituye al backup.

1. Preparar el Ubuntu y crear el usuario de servicio

Actualice el sistema e instale solo las utilidades utilizadas para descargar, validar y descomprimir el archivo. El proceso de OpenObserve se ejecuta con una cuenta de sistema sin inicio de sesión; el binario permanece bajo control de root y los datos se guardan en /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

No use una cuenta con shell administrativo para el servicio. La separación permite limitar quién lee las credenciales y quién escribe en los datos locales.

2. Descargar e instalar el binario oficial

Consulte primero la página oficial de descargas y cambie OO_VERSION por una release estable que haya decidido homologar. El ejemplo utiliza v1.0.4, release estable comprobada en 7 de octubre de 2026, sin prometer que será la más reciente en el futuro. Detecta amd64 o arm64; para máquinas con glibc antiguo, la documentación recomienda usar el paquete linux-amd64-musl, con posible coste de rendimiento.

Seleccione la edición Open Source en las descargas; los artefactos Enterprise tienen otros nombres. Ejecute el bloque en Bash. En la página de Descargas, seleccione Open Source, la versión y la arquitectura; use el botón Show SHA256 del paquete correspondiente. El hash debe ser el publicado por el proveedor para ese artefacto.

(
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
)

El checksum es un paso obligatorio antes de ejecutar un binario descargado. Guarde la versión instalada: las actualizaciones deben descargar una nueva release, validar el hash, instalar otro archivo y solo entonces intercambiar el enlace simbólico durante una ventana de mantenimiento.

3. Crear el archivo de entorno

OpenObserve se configura mediante variables de entorno. Cree un archivo que solo root y el grupo del servicio puedan leer. La contraseña raíz se utiliza en el primer arranque; genere una contraseña larga, guárdela en una caja fuerte y sustituya los valores de ejemplo antes de iniciar el servicio.

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 el puerto 5080 directamente. También definimos ZO_GRPC_ADDR=127.0.0.1 para que el puerto gRPC por defecto no quede abierto en la red. Si OpenObserve se sirve en una subruta, como https://exemplo.com/logs/, use ZO_BASE_URI=/logs y ajuste el proxy.

No empiece con la contraseña de ejemplo. Sustituya la contraseña y el dominio con sudoedit; para el bucket, aplique ahora el bloque de la sección 6. El comando de creación del archivo es para instalación nueva: no lo repita sobre la configuración existente.

4. Ejecutar como servicio systemd

Cree la unidad. El límite de descriptores sigue la recomendación de la guía oficial; Restart=on-failure intenta recuperar fallos, pero no corrige una configuración inválida; supervise los logs y el límite de reinicios.

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

La respuesta esperada del health check es {"status":"ok"}. Si el servicio no arranca, comprueba los permisos en /var/lib/openobserve, la sintaxis del archivo de entorno y el registro de journalctl. No cambies la contraseña de root en una instancia ya inicializada esperando recrear al usuario: esas variables solo son necesarias en el primer arranque.

5. Instalar nginx y publicar con TLS

Después de validar OpenObserve en loopback, publícalo con un nombre DNS propio, por ejemplo o2.exemplo.com. Antes de solicitar el certificado, crea los registros A (y AAAA, si usas IPv6) apuntando al servidor y confirma que los puertos 80 y 443 llegan hasta él. OpenObserve sigue en 127.0.0.1:5080; solo nginx quedará expuesto.

Instalar el proxy inverso

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

Si el host usa UFW, preserva primero el acceso administrativo y abre únicamente HTTP/HTTPS. En proveedores de nube, haz la misma apertura en el firewall o security group del proveedor.

# 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

Cree primero un host virtual HTTP. Devuelve 404 deliberadamente y no entrega la aplicación en HTTP; Certbot configurará el desafío HTTP-01 de Let's Encrypt. No publique el puerto 5080 ni el 5081 en el 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/

Usa un subdominio, como en el ejemplo. Si optas por publicar bajo una ruta, como https://exemplo.com/logs/, sigue la documentación de OpenObserve y define ZO_BASE_URI=/logs; simplemente añadir location /logs/ en nginx no es suficiente.

Emitir y renovar el certificado

Con el DNS propagado y el puerto 80 accesible públicamente, el plugin nginx de Certbot puede obtener el certificado e instalar el bloque HTTPS. Haz una copia de la configuración antes de permitir que Certbot la modifique.

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/

Activar el proxy solo en el bloque HTTPS

Edite /etc/nginx/sites-available/openobserve. En el bloque 443 creado por Certbot, sustituya únicamente el location / que devuelve 404 por el bloque de abajo. Preserve las directivas TLS y mantenga el puerto 80 con redirección y renovación.

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;
}

Los valores 20m e 300s son elecciones iniciales de esta receta, no universales. Los lotes por encima del límite del cuerpo reciben 413: ajuste el colector antes de aumentar el límite de forma indiscriminada. El buffering desactivado evita acumular respuestas en flujo. El ejemplo asume clientes que llegan directamente a nginx, sin otro proxy delante.

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

Límite de cuerpo e directivas de proxy en la documentación nginx.

O --redirect redirige HTTP a HTTPS. La prueba renew --dry-run confirma la renovación antes de la fecha de expiración. Para certificados corporativos o validación DNS-01, no ejecutes el comando anterior: instala el certificado conforme a la política de la organización y mantén el mismo proxy para 127.0.0.1:5080.

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

El resultado debe mostrar nginx en 80/443 y los puertos 5080 y 5081 de OpenObserve solo en loopback, nunca en 0.0.0.0. No expongas la interfaz, las APIs de ingestión ni el endpoint MCP en HTTP simple.

Validar ingesta y consulta antes de los datos reales

Si ha elegido bucket, complete primero la sección 6; solo después envíe el evento. El health check no comprueba la ingestión. Use el evento JSON y la consulta SQL del laboratorio introductorio, cambiando la URL por https://o2.exemplo.com y el usuario por la cuenta creada. Confirme el evento, reinicie el servicio y consulte de nuevo.

El proxy mostrado atiende HTTP, no publica OTLP/gRPC en 5081. Configure el exporter para el protocolo y endpoint correctos; no abra 5081 solo porque usa gRPC por defecto.

6. Usar S3, GCS, Oracle Cloud o MinIO

Configure el backend antes de la primera ingestión. En una instancia existente, cambiar variables no migra los datos. Con object storage, SQLite y WAL siguen en el disco local. Edite el mismo archivo /etc/openobserve/openobserve.env, cambia ZO_LOCAL_MODE_STORAGE para s3, añade un bloque del proveedor y reinicia el servicio. Crea el bucket antes, usa un prefijo exclusivo por entorno y prueba escritura, lectura y retención en un entorno de homologación.

AWS S3

En EC2, prefiere una IAM Role con acceso mínimo al bucket y al prefijo en lugar de credenciales estáticas. Para S3 estándar, no definas ZO_S3_SERVER_URL; el SDK busca la identidad de la instancia. Fuera de AWS, inyecte las claves mediante un gestor de secretos o mediante el archivo de entorno con permisos 0640; nunca las incluya en 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

GCS puede usar la API compatible con S3. Cree una clave HMAC con acceso restringido al bucket y use HTTP/1, exigido por la configuración 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

También existe integración directa: use ZO_S3_PROVIDER=gcs y, cuando no haya identidad de la instancia, proporcione en ZO_S3_ACCESS_KEY la ruta a la clave JSON de la cuenta de servicio, con permiso de lectura solo para el usuario openobserve.

Oracle Cloud Object Storage

Object Storage de Oracle ofrece API S3-compatible. Utilice una Customer Secret Key, mantenga la URL en el formato de su tenancy y región y valide la configuración en un bucket de prueba antes de escribir datos de producción.

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 es una opción S3-compatible para datacenter, otra VM o Kubernetes. Cree el bucket antes del start y use TLS entre OpenObserve y el endpoint. Un MinIO en el mismo host no crea redundancia: un fallo de la máquina puede derribar aplicación y datos al mismo tiempo.

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 compatible con S3

La documentación actual también describe RustFS como destino. Utilice el endpoint HTTPS de la API S3, no la consola; cree el bucket y la credencial de la aplicación 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 escritura, lectura, reinicio y retención; esta revisión no ejecutó integración contra ese backend. Autorice el bucket/prefijo necesario, incluidas las operaciones de borrado utilizadas por la retención. Referencia oficial de los backends.

7. Integrar agentes de IA y aplicaciones LLM

Sí: OpenObserve puede participar de un flujo con LLM de dos formas. La primera es observar la aplicación de IA mediante OpenTelemetry: tokens, latencia, modelo, errores y llamadas a herramientas se convierten en traces y métricas. La segunda es conectar un cliente MCP para consultar logs, métricas y traces en lenguaje natural.

El endpoint MCP sigue el formato https://o2.exemplo.com/api/ID_DA_ORGANIZACAO/mcp. La documentación indica soporte en Open Source, Enterprise y Cloud. Utilice solo HTTPS y una cuenta separada; no registre tokens en repositorios, chat ni archivos compartidos.

Configure el cliente según la documentación de MCP. Basic Auth usa Base64, no cifrado. No coloque tokens en argumentos de procesos compartidos; proteja el archivo de configuración del cliente y las copias de seguridad. unset no elimina una credencial que el cliente ya haya escrito en disco.

Seguridad en el MCP: en la edición Open Source, las llamadas MCP utilizan los privilegios completos de la cuenta conectada; RBAC granular está disponible en Enterprise y Cloud. En OSS, usa una cuenta exclusiva para trazabilidad y rotación, pero no la trates como mínimo privilegio. Restringe el endpoint por red/IP, pide confirmación para operaciones de escritura y considera cualquier texto proveniente de logs como dato no confiable, incluso frente a prompt injection.

La telemetría de IA puede contener prompts, respuestas, identificadores y documentos recuperados. Define de antemano qué atributos pueden salir de la aplicación, haz redacción cuando sea necesario y alinea retención, RGPD y acceso. No envíes secretos ni claves de API en logs ni en spans.

Operación, copia de seguridad y actualización

  • Monitoriza el propio servicio: CPU, RAM, I/O, espacio libre, errores de ingestión, tiempo de consulta y crecimiento del bucket.
  • Protege los metadatos: en nodo único, el SQLite local contiene configuraciones, usuarios, dashboards y alertas; haz backup consistente de /var/lib/openobserve y del archivo de entorno, manteniendo los secretos protegidos.
  • Prueba la restauración: recuperar únicamente Parquet en el bucket no recrea automáticamente usuarios, dashboards ni reglas.
  • Actualización y reversión: realice una copia de seguridad coherente, pruebe la release e instale el binario en paralelo. Detenga el servicio antes de cambiar el enlace. Conservar el binario anterior no garantiza un downgrade: las migraciones de metadatos pueden requerir restaurar también la copia de seguridad previa a la actualización.
  • Revise la retención: ZO_COMPACT_DATA_RETENTION_DAYS tiene un patrón de 3650 días; defina una política explícita y compatible con las reglas de lifecycle del bucket.

Backup consistente y restauración

En este nodo único, programe una ventana, detenga el envío o asegúrese de que haya colas suficientes en los colectores, detenga el servicio y copie el directorio de datos completo y la configuración a un almacenamiento protegido. Preserve el propietario y los permisos. No copie solo el SQLite mientras se está modificando.

En el modo bucket, alinee el punto de recuperación de los metadatos con los objetos y la política de copia de seguridad. Una copia local no congela el bucket. Restaure primero en una red aislada, con la misma versión; valide usuarios, streams, dashboards y consultas antes de habilitar la ingesta. Registre el tiempo de recuperación y la pérdida máxima aceptable.

Fallos comunes

  • 502: verifique el servicio y la respuesta en el loopback antes de modificar nginx.
  • 413: compare el tamaño del lote con los límites del proxy y del backend.
  • 401/403: verifique credencial, organización y permisos; no desactive la autenticación.
  • Error en el bucket: verifique endpoint, región, reloj, validez de las claves y certificados. No deshabilite TLS.
  • Disco lleno: examine WAL, caché y registros; no borre archivos internos manualmente.

Vea también los comandos esenciales de systemd.

Checklist final

  • Binario oficial instalado y SHA-256 comprobado antes de la ejecución.
  • Servicio openobserve activo, con datos grabables solo por la cuenta dedicada.
  • Puertos 5080 y 5081 enlazados al loopback; interfaz disponible solo en HTTPS mediante nginx.
  • Contraseña raíz y credenciales de bucket almacenadas fuera de Git, chat y copias de seguridad sin cifrado.
  • Retención calculada con la ingesta real, no con una tasa de compresión asumida.
  • Prueba de escritura/lectura en el bucket y restauración de metadatos completadas antes de pasar a producción.

¿Desea evaluar otro backend de objetos con API S3? Vea RustFS en Linux: instalación por binario y Docker. La compatibilidad con S3 no garantiza la integración sin ajustes: valide endpoint, región, autenticación y las operaciones que usa OpenObserve en un laboratorio antes de migrar datos.

Fuentes oficiales