--- title: "Cómo instalar Meilisearch en Ubuntu 24.04 con Nginx y HTTPS" description: "Instala Meilisearch en Ubuntu 24.04 como servicio systemd, protégelo con una clave maestra y claves de API, indexa documentos y publícalo con Nginx y HTTPS." category: "Base de Datos Avanzada" language: es source: https://cubepath.com/es/docs/base-de-datos-avanzada/instalacion-de-meilisearch-motor-de-busqueda-rapido updated: 2026-09-25 --- # Cómo instalar Meilisearch en Ubuntu 24.04 con Nginx y HTTPS Meilisearch es un motor de búsqueda de código abierto escrito en Rust que devuelve resultados en milisegundos, tolera errores tipográficos y permite filtrar y ordenar sin apenas configuración. Se maneja entero a través de una API REST, lo que lo hace muy práctico para buscadores de tiendas online, documentación o catálogos. En este tutorial instalarás Meilisearch en Ubuntu 24.04 como servicio systemd en modo producción, crearás un índice con documentos de ejemplo, configurarás filtros y claves de API con permisos limitados, y lo publicarás detrás de Nginx con un certificado de Let's Encrypt. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 1 GB de RAM (Meilisearch usa memoria mapeada, así que más RAM significa índices más rápidos). - Un usuario no root con privilegios `sudo`. - Un dominio o subdominio (en esta guía `search.your_domain`) con un registro DNS A apuntando a la IP de tu servidor. - Nginx instalado y UFW activo con los puertos 22, 80 y 443 abiertos. ## Paso 1: Descargar el binario de Meilisearch Meilisearch se distribuye como un único binario estático. Descarga la última versión estable desde las releases oficiales de GitHub. Para servidores x86_64 usa `meilisearch-linux-amd64`; en arm64 el archivo se llama `meilisearch-linux-aarch64`: ```bash curl -fsSL -o meilisearch https://github.com/meilisearch/meilisearch/releases/latest/download/meilisearch-linux-amd64 ``` Instálalo en `/usr/local/bin` con permisos de ejecución: ```bash sudo install -m 0755 meilisearch /usr/local/bin/meilisearch rm meilisearch ``` Comprueba que funciona: ```bash meilisearch --version ``` ```output meilisearch 1.x.y ``` ## Paso 2: Crear el usuario y los directorios de datos Meilisearch no debe ejecutarse como root. Crea un usuario de sistema sin shell con su directorio de trabajo en `/var/lib/meilisearch`: ```bash sudo useradd --system --home-dir /var/lib/meilisearch --create-home --shell /usr/sbin/nologin meilisearch ``` Crea los directorios para la base de datos, los volcados (dumps) y las instantáneas (snapshots): ```bash sudo install -d -o meilisearch -g meilisearch -m 0750 /var/lib/meilisearch/data /var/lib/meilisearch/dumps /var/lib/meilisearch/snapshots ``` ## Paso 3: Configurar la clave maestra y el modo producción En modo producción Meilisearch exige una clave maestra (master key) de al menos 16 bytes y desactiva el panel web de pruebas. Genera una clave aleatoria: ```bash openssl rand -base64 32 ``` ```output k3Vq8fN0y2Qe7Zr1bLx9Hm4Tw6Pc5Ds0Aa2Ug8Jn1Ro= ``` Guarda ese valor en un gestor de contraseñas y crea el archivo de configuración: ```bash sudo nano /etc/meilisearch.toml ``` Añade el siguiente contenido, sustituyendo `your_master_key` por la clave generada: ```toml env = "production" master_key = "your_master_key" db_path = "/var/lib/meilisearch/data" dump_dir = "/var/lib/meilisearch/dumps" snapshot_dir = "/var/lib/meilisearch/snapshots" http_addr = "127.0.0.1:7700" ``` Con `http_addr = "127.0.0.1:7700"` Meilisearch solo escucha en localhost; el acceso desde fuera pasará por Nginx. Como el archivo contiene la clave maestra, restringe sus permisos: ```bash sudo chown root:meilisearch /etc/meilisearch.toml sudo chmod 0640 /etc/meilisearch.toml ``` ## Paso 4: Ejecutar Meilisearch como servicio systemd Crea la unidad de systemd: ```bash sudo nano /etc/systemd/system/meilisearch.service ``` ```ini [Unit] Description=Meilisearch After=network-online.target Wants=network-online.target [Service] Type=simple User=meilisearch Group=meilisearch WorkingDirectory=/var/lib/meilisearch ExecStart=/usr/local/bin/meilisearch --config-file-path /etc/meilisearch.toml Restart=on-failure [Install] WantedBy=multi-user.target ``` Recarga systemd y arranca el servicio: ```bash sudo systemctl daemon-reload sudo systemctl enable --now meilisearch ``` Comprueba el estado y el endpoint de salud, que no requiere autenticación: ```bash systemctl status meilisearch --no-pager curl -s http://127.0.0.1:7700/health ``` ```output {"status":"available"} ``` Si el servicio no arranca, revisa el log con `sudo journalctl -u meilisearch -n 50`. El error más habitual es una clave maestra demasiado corta. ## Paso 5: Obtener las claves de API La clave maestra solo debe usarse para administrar claves, no desde las aplicaciones. Al arrancar, Meilisearch crea dos claves por defecto: una de búsqueda y otra de administración. Guarda la clave maestra en una variable de la sesión y lístalas: ```bash export MEILI_MASTER_KEY='your_master_key' curl -s http://127.0.0.1:7700/keys -H "Authorization: Bearer $MEILI_MASTER_KEY" ``` La respuesta incluye, entre otros campos, el nombre y el valor de cada clave: ```output {"results":[{"name":"Default Search API Key","description":"Use it to search from the frontend","key":"8dbb...","actions":["search"],"indexes":["*"],...},{"name":"Default Admin API Key","description":"Use it for anything that is not a search operation. Caution! Do not expose it on a public frontend","key":"f6f3...",...}],...} ``` Guarda la clave de administración en otra variable para los siguientes pasos: ```bash export MEILI_ADMIN_KEY='your_admin_api_key' ``` ## Paso 6: Crear un índice y añadir documentos Un índice es una colección de documentos JSON con un identificador único (clave primaria). Crea un archivo con algunos documentos de ejemplo: ```bash nano movies.json ``` ```json [ { "id": 1, "title": "Blade Runner", "genre": "ciencia ficción", "year": 1982 }, { "id": 2, "title": "El laberinto del fauno", "genre": "fantasía", "year": 2006 }, { "id": 3, "title": "Interstellar", "genre": "ciencia ficción", "year": 2014 }, { "id": 4, "title": "Amélie", "genre": "comedia", "year": 2001 } ] ``` Envíalos al índice `movies`. Si el índice no existe, Meilisearch lo crea y detecta `id` como clave primaria: ```bash curl -s -X POST 'http://127.0.0.1:7700/indexes/movies/documents' \ -H "Authorization: Bearer $MEILI_ADMIN_KEY" \ -H 'Content-Type: application/json' \ --data-binary @movies.json ``` ```output {"taskUid":0,"indexUid":"movies","status":"enqueued","type":"documentAdditionOrUpdate","enqueuedAt":"2026-09-25T10:00:00.000000Z"} ``` Las escrituras en Meilisearch son asíncronas: la API encola una tarea y responde al momento. Consulta su estado con el `taskUid` devuelto: ```bash curl -s 'http://127.0.0.1:7700/tasks/0' -H "Authorization: Bearer $MEILI_ADMIN_KEY" ``` Cuando el campo `status` valga `succeeded`, los documentos ya se pueden buscar. Prueba una búsqueda con una errata intencionada: ```bash curl -s -X POST 'http://127.0.0.1:7700/indexes/movies/search' \ -H "Authorization: Bearer $MEILI_ADMIN_KEY" \ -H 'Content-Type: application/json' \ --data '{ "q": "intrestelar" }' ``` ```output {"hits":[{"id":3,"title":"Interstellar","genre":"ciencia ficción","year":2014}],"query":"intrestelar","processingTimeMs":1,"limit":20,"offset":0,"estimatedTotalHits":1} ``` La tolerancia a errores tipográficos está activada por defecto, por eso encuentra "Interstellar". ## Paso 7: Configurar filtros, ordenación y campos de búsqueda Para filtrar u ordenar por un campo hay que declararlo antes en la configuración del índice. También conviene indicar qué campos se buscan y en qué orden de importancia: ```bash curl -s -X PATCH 'http://127.0.0.1:7700/indexes/movies/settings' \ -H "Authorization: Bearer $MEILI_ADMIN_KEY" \ -H 'Content-Type: application/json' \ --data '{ "searchableAttributes": ["title", "genre"], "filterableAttributes": ["genre", "year"], "sortableAttributes": ["year"] }' ``` Este cambio también genera una tarea y reindexa los documentos. Cuando termine, combina búsqueda, filtro y ordenación: ```bash curl -s -X POST 'http://127.0.0.1:7700/indexes/movies/search' \ -H "Authorization: Bearer $MEILI_ADMIN_KEY" \ -H 'Content-Type: application/json' \ --data '{ "q": "", "filter": "genre = \"ciencia ficción\" AND year > 2000", "sort": ["year:desc"] }' ``` ```output {"hits":[{"id":3,"title":"Interstellar","genre":"ciencia ficción","year":2014}],"query":"","processingTimeMs":0,"limit":20,"offset":0,"estimatedTotalHits":1} ``` ## Paso 8: Crear una clave de búsqueda limitada a un índice La clave que uses en el navegador del usuario solo debe permitir buscar, y a ser posible solo en los índices necesarios. Crea una con la clave maestra: ```bash curl -s -X POST 'http://127.0.0.1:7700/keys' \ -H "Authorization: Bearer $MEILI_MASTER_KEY" \ -H 'Content-Type: application/json' \ --data '{ "name": "frontend-movies", "description": "Búsqueda pública en movies", "actions": ["search"], "indexes": ["movies"], "expiresAt": null }' ``` El campo `key` de la respuesta es la clave que puedes incluir en tu frontend. Compruébalo: una búsqueda en `movies` funciona, pero intentar añadir documentos devuelve un error `invalid_api_key`: ```bash curl -s -X POST 'http://127.0.0.1:7700/indexes/movies/documents' \ -H 'Authorization: Bearer your_search_key' \ -H 'Content-Type: application/json' \ --data '[{"id": 5, "title": "Prueba"}]' ``` ```output {"message":"The provided API key is invalid.","code":"invalid_api_key","type":"auth","link":"https://docs.meilisearch.com/errors#invalid_api_key"} ``` ## Paso 9: Publicar Meilisearch con Nginx y HTTPS Crea un bloque de servidor para el subdominio: ```bash sudo nano /etc/nginx/sites-available/meilisearch ``` ```nginx server { listen 80; listen [::]:80; server_name search.your_domain; client_max_body_size 100M; location / { proxy_pass http://127.0.0.1:7700; 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; } } ``` `client_max_body_size 100M` coincide con el tamaño máximo de carga que acepta Meilisearch por defecto, para que Nginx no corte las importaciones grandes. Activa el sitio y recarga Nginx: ```bash sudo ln -s /etc/nginx/sites-available/meilisearch /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` Obtén el certificado con Certbot, que modificará el bloque para servir HTTPS y redirigir HTTP: ```bash sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d search.your_domain ``` Verifica el acceso externo desde tu equipo: ```bash curl -s https://search.your_domain/health ``` ```output {"status":"available"} ``` ## Paso 10: Crear copias de seguridad con snapshots Una snapshot es una copia exacta de la base de datos que se restaura rápidamente en la misma versión de Meilisearch. Lánzala con la clave de administración: ```bash curl -s -X POST 'http://127.0.0.1:7700/snapshots' -H "Authorization: Bearer $MEILI_ADMIN_KEY" ``` Cuando la tarea termine, el archivo aparecerá en el directorio configurado: ```bash sudo ls -lh /var/lib/meilisearch/snapshots ``` Para migrar entre versiones de Meilisearch usa un dump (`POST /dumps`), que se guarda en `/var/lib/meilisearch/dumps` y es compatible entre versiones. Copia ambos tipos de archivo fuera del servidor. ## Solución de problemas - **`missing_authorization_header` o `invalid_api_key`**: falta la cabecera `Authorization: Bearer ...` o la clave no tiene permiso para esa acción o índice. - **El filtro devuelve `invalid_search_filter`**: el campo no está en `filterableAttributes`, o la tarea de configuración aún no ha terminado. Revísalo en `GET /tasks`. - **Nginx responde 413 al importar**: sube `client_max_body_size` o divide el JSON en lotes más pequeños. - **El servicio no arranca tras actualizar el binario**: la base de datos de una versión anterior puede no ser compatible. Crea un dump con la versión antigua e impórtalo en la nueva con la opción `--import-dump`. ## Conclusión Tienes Meilisearch funcionando en Ubuntu 24.04 en modo producción, con una clave maestra, claves de API con permisos mínimos y acceso público solo a través de Nginx con HTTPS. Como siguientes pasos, puedes conectar tu aplicación con uno de los SDK oficiales (JavaScript, Python, PHP, Go...), configurar sinónimos y palabras vacías en los ajustes del índice, y programar snapshots periódicas con un temporizador de systemd.