--- title: "Cómo instalar ZincSearch en Ubuntu 24.04 como servicio" description: "Instala ZincSearch en Ubuntu 24.04 con systemd, crea un índice con mapping, carga datos con la API _bulk de Elasticsearch y busca con agregaciones." category: "Motores de Búsqueda" language: es source: https://cubepath.com/es/docs/motores-de-búsqueda/zincsearch-alternativa-ligera-a-elasticsearch updated: 2026-09-25 --- # Cómo instalar ZincSearch en Ubuntu 24.04 como servicio ZincSearch es un motor de búsqueda de texto completo escrito en Go que se distribuye como un único binario. Implementa parte de la API de Elasticsearch (ingesta `_bulk` y búsquedas con la sintaxis Query DSL), por lo que muchos scripts y clientes existentes funcionan sin cambios, con un consumo de memoria muy inferior. En este tutorial instalarás ZincSearch en Ubuntu 24.04 como servicio systemd, crearás un índice para logs de acceso con un mapping explícito, cargarás datos y harás búsquedas con filtros y agregaciones. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS de 64 bits (x86_64), por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - Al menos 1 GB de RAM y espacio en disco acorde al volumen de datos que vayas a indexar. ZincSearch escuchará solo en `127.0.0.1:4080`. Accederás a su interfaz web mediante un túnel SSH, así que no hace falta abrir puertos. > Nota: esta guía usa ZincSearch 0.4.10, la última versión estable con binarios publicados. El proyecto ha empezado a publicar versiones 1.0.0 en fase beta; revisa la [página de versiones](https://github.com/zincsearch/zincsearch/releases) antes de instalar en producción. ## Paso 1: Descargar e instalar el binario Descarga el paquete para Linux x86_64 y la lista de sumas de comprobación: ```bash ZINC_VERSION=0.4.10 cd /tmp wget "https://github.com/zincsearch/zincsearch/releases/download/v${ZINC_VERSION}/zincsearch_${ZINC_VERSION}_linux_x86_64.tar.gz" wget "https://github.com/zincsearch/zincsearch/releases/download/v${ZINC_VERSION}/checksums.txt" ``` Verifica el archivo. La opción `--ignore-missing` omite las entradas de otras plataformas que no has descargado: ```bash sha256sum -c --ignore-missing checksums.txt ``` ```output zincsearch_0.4.10_linux_x86_64.tar.gz: OK ``` Extrae el binario e instálalo en `/usr/local/bin`: ```bash tar xzf "zincsearch_${ZINC_VERSION}_linux_x86_64.tar.gz" zincsearch sudo install -m 0755 zincsearch /usr/local/bin/zincsearch ``` ## Paso 2: Crear el usuario y el directorio de datos Ejecutarás ZincSearch con un usuario de sistema sin privilegios que solo puede escribir en su directorio de datos: ```bash sudo useradd --system --no-create-home --shell /usr/sbin/nologin zincsearch sudo install -d -o zincsearch -g zincsearch -m 0750 /var/lib/zincsearch sudo install -d -m 0755 /etc/zincsearch ``` ## Paso 3: Configurar ZincSearch ZincSearch se configura con variables de entorno. Las guardarás en un archivo que solo pueda leer root y el usuario del servicio, porque contiene la contraseña del administrador: ```bash sudo nano /etc/zincsearch/zincsearch.env ``` Añade el siguiente contenido. Sustituye `your_strong_password` por una contraseña robusta, por ejemplo una generada con `openssl rand -base64 24`: ```ini ZINC_DATA_PATH=/var/lib/zincsearch ZINC_SERVER_ADDRESS=127.0.0.1 ZINC_SERVER_PORT=4080 ZINC_FIRST_ADMIN_USER=admin ZINC_FIRST_ADMIN_PASSWORD=your_strong_password ZINC_TELEMETRY=false ZINC_SENTRY=false GIN_MODE=release ``` Qué hace cada variable: | Variable | Función | |----------|---------| | `ZINC_DATA_PATH` | Directorio donde se guardan índices y metadatos | | `ZINC_SERVER_ADDRESS` / `ZINC_SERVER_PORT` | Dirección y puerto de escucha | | `ZINC_FIRST_ADMIN_USER` / `ZINC_FIRST_ADMIN_PASSWORD` | Usuario administrador que se crea en el primer arranque. Son obligatorias la primera vez | | `ZINC_TELEMETRY`, `ZINC_SENTRY` | Desactivan el envío de telemetría y de errores a los servidores del proyecto, activos por defecto | | `GIN_MODE=release` | Quita los mensajes de depuración del framework HTTP | Restringe los permisos del archivo: ```bash sudo chown root:zincsearch /etc/zincsearch/zincsearch.env sudo chmod 0640 /etc/zincsearch/zincsearch.env ``` ## Paso 4: Crear el servicio systemd Crea la unidad del servicio: ```bash sudo nano /etc/systemd/system/zincsearch.service ``` Añade este contenido: ```ini [Unit] Description=ZincSearch After=network.target [Service] Type=simple User=zincsearch Group=zincsearch EnvironmentFile=/etc/zincsearch/zincsearch.env WorkingDirectory=/var/lib/zincsearch ExecStart=/usr/local/bin/zincsearch Restart=on-failure RestartSec=5 LimitNOFILE=65536 NoNewPrivileges=true ProtectSystem=strict ReadWritePaths=/var/lib/zincsearch ProtectHome=true PrivateTmp=true [Install] WantedBy=multi-user.target ``` Recarga systemd e inicia el servicio: ```bash sudo systemctl daemon-reload sudo systemctl enable --now zincsearch ``` Comprueba que el servicio está activo y que responde. El endpoint `/healthz` no requiere autenticación: ```bash sudo systemctl status zincsearch curl -s http://127.0.0.1:4080/healthz ``` ```output {"status":"ok"} ``` Guarda las credenciales en variables de la sesión para no repetirlas en cada comando. Usa la contraseña que pusiste en el archivo de entorno: ```bash export ZINC_URL="http://127.0.0.1:4080" export ZINC_AUTH="admin:your_strong_password" ``` Comprueba que la autenticación funciona consultando la lista de índices, que de momento estará vacía: ```bash curl -s -u "$ZINC_AUTH" "$ZINC_URL/api/index" ``` > Importante: una vez creado el administrador, cambia su contraseña desde la interfaz web y borra la línea `ZINC_FIRST_ADMIN_PASSWORD` del archivo de entorno. Solo se usa en el primer arranque. Para abrir la interfaz web desde tu equipo, crea un túnel SSH sustituyendo `your_user` y `your_server_ip`, y visita `http://localhost:4080`: ```bash ssh -L 4080:127.0.0.1:4080 your_user@your_server_ip ``` ## Paso 5: Crear un índice con mapping ZincSearch crea los índices de forma automática al recibir el primer documento, pero entonces adivina el tipo de cada campo. Para datos como logs de acceso es mejor definir el mapping. Los tipos disponibles son `text` (texto analizado para búsqueda), `keyword` (valor exacto), `numeric`, `boolean`, `date` y `geo_point`. `aggregatable` y `sortable` permiten usar el campo en agregaciones y ordenaciones: ```bash curl -s -u "$ZINC_AUTH" -X POST "$ZINC_URL/api/index" \ -H 'Content-Type: application/json' \ -d '{ "name": "logs-nginx", "storage_type": "disk", "mappings": { "properties": { "ip_cliente": {"type": "keyword", "index": true, "store": true, "aggregatable": true}, "metodo": {"type": "keyword", "index": true, "store": true, "aggregatable": true}, "ruta": {"type": "text", "index": true, "store": true, "highlightable": true}, "status": {"type": "numeric", "index": true, "store": true, "sortable": true, "aggregatable": true}, "bytes": {"type": "numeric", "index": true, "store": true, "sortable": true, "aggregatable": true}, "user_agent": {"type": "text", "index": true, "store": true} } } }' ``` ```output {"message":"ok","index":"logs-nginx","storage_type":"disk"} ``` ## Paso 6: Cargar documentos con la API _bulk La ruta `/es/_bulk` acepta el mismo formato NDJSON que Elasticsearch: una línea de acción seguida de una línea con el documento. El campo `@timestamp` es especial en ZincSearch: si lo envías en formato RFC 3339 se usa como fecha del documento, y si lo omites se usa la hora de ingesta. Crea un archivo de ejemplo: ```bash nano /tmp/logs.ndjson ``` ```json {"index": {"_index": "logs-nginx"}} {"@timestamp": "2026-09-20T10:31:00Z", "ip_cliente": "203.0.113.10", "metodo": "POST", "ruta": "/api/pedidos", "status": 201, "bytes": 456, "user_agent": "curl/8.5.0"} {"index": {"_index": "logs-nginx"}} {"@timestamp": "2026-09-20T10:31:05Z", "ip_cliente": "203.0.113.11", "metodo": "GET", "ruta": "/api/usuarios", "status": 401, "bytes": 78, "user_agent": "Mozilla/5.0"} {"index": {"_index": "logs-nginx"}} {"@timestamp": "2026-09-20T10:32:00Z", "ip_cliente": "203.0.113.10", "metodo": "GET", "ruta": "/api/productos", "status": 200, "bytes": 2310, "user_agent": "Mozilla/5.0"} {"index": {"_index": "logs-nginx"}} {"@timestamp": "2026-09-20T10:33:12Z", "ip_cliente": "203.0.113.12", "metodo": "GET", "ruta": "/api/productos/42", "status": 404, "bytes": 120, "user_agent": "Mozilla/5.0"} ``` El archivo debe terminar con un salto de línea. Envíalo con `--data-binary`, que respeta los saltos de línea (`-d` los eliminaría): ```bash curl -s -u "$ZINC_AUTH" -X POST "$ZINC_URL/es/_bulk" \ -H 'Content-Type: application/x-ndjson' \ --data-binary @/tmp/logs.ndjson ``` La respuesta sigue el formato de Elasticsearch. Comprueba que el campo `errors` es `false`: ```output {"took":3,"errors":false,"items":[{"index":{"_index":"logs-nginx","_id":"...","_version":1,"result":"created",... ``` Para añadir un único documento también puedes usar `POST /api/logs-nginx/_doc` con el JSON en el cuerpo. ## Paso 7: Buscar con la sintaxis de Elasticsearch Los documentos pueden tardar un segundo en ser visibles para la búsqueda. Busca las peticiones a rutas que contengan "productos" con código de estado menor que 400, ordenadas de la más reciente a la más antigua: ```bash curl -s -u "$ZINC_AUTH" -X POST "$ZINC_URL/es/logs-nginx/_search" \ -H 'Content-Type: application/json' \ -d '{ "query": { "bool": { "must": [{"match": {"ruta": "productos"}}], "filter": [{"range": {"status": {"lt": 400}}}] } }, "sort": [{"@timestamp": "desc"}], "size": 10 }' ``` ```output {"took":1,"timed_out":false,"hits":{"total":{"value":1},"max_score":0.98,"hits":[{"_index":"logs-nginx","_id":"...","_score":0.98,"@timestamp":"2026-09-20T10:32:00Z","_source":{"ip_cliente":"203.0.113.10","metodo":"GET","ruta":"/api/productos","status":200,... ``` Las agregaciones permiten resumir los datos, por ejemplo para un panel de errores. Esta consulta cuenta las peticiones por método y por código de estado, sin devolver documentos (`"size": 0`): ```bash curl -s -u "$ZINC_AUTH" -X POST "$ZINC_URL/es/logs-nginx/_search" \ -H 'Content-Type: application/json' \ -d '{ "query": {"match_all": {}}, "aggs": { "por_metodo": {"terms": {"field": "metodo", "size": 10}}, "por_status": {"terms": {"field": "status", "size": 10}} }, "size": 0 }' ``` ```output ..."aggregations":{"por_metodo":{"buckets":[{"key":"GET","doc_count":3},{"key":"POST","doc_count":1}]},"por_status":{"buckets":[...]}}} ``` Solo los campos marcados como `aggregatable` en el mapping pueden usarse en agregaciones. ## Paso 8: Borrar datos antiguos ZincSearch no tiene políticas de ciclo de vida como el ILM de Elasticsearch. La forma habitual de gestionar la retención de logs es crear un índice por mes (por ejemplo `logs-nginx-2026-09`) y borrar los antiguos: ```bash curl -s -u "$ZINC_AUTH" -X DELETE "$ZINC_URL/api/index/logs-nginx-2026-06" ``` Para ver cuánto ocupa cada índice en disco: ```bash sudo du -sh /var/lib/zincsearch/* ``` ## Solución de problemas **El servicio no arranca.** Revisa el log: ```bash sudo journalctl -u zincsearch -n 50 --no-pager ``` El mensaje `ZINC_FIRST_ADMIN_USER and ZINC_FIRST_ADMIN_PASSWORD must be set on first start` indica que falta alguna de esas variables en el primer arranque. Un error de permisos sobre el directorio de datos se corrige con `sudo chown -R zincsearch:zincsearch /var/lib/zincsearch`. **Respuesta 401 en la API.** Las credenciales no son correctas. Recuerda que la contraseña del archivo de entorno solo se aplica en el primer arranque; si la cambiaste desde la interfaz web, usa la nueva. **Una petición que funciona en Elasticsearch falla en ZincSearch.** ZincSearch implementa solo una parte de la API: no incluye ILM, snapshots, rollover ni pipelines de ingesta. Si necesitas esas funciones, valora OpenSearch o Elasticsearch. ## Conclusión Tienes ZincSearch funcionando como servicio en Ubuntu 24.04, con un índice definido por ti, datos cargados mediante la API `_bulk` compatible con Elasticsearch y consultas con filtros y agregaciones. Como siguientes pasos, puedes enviar los logs de Nginx con un agente como Fluent Bit o Vector usando su salida para Elasticsearch apuntando a `/es/`, crear usuarios con permisos limitados para cada aplicación desde la interfaz web, o publicar ZincSearch detrás de un proxy inverso con HTTPS si otras máquinas necesitan acceder a él.