Applications Azure

Meilisearch on Ubuntu 24.04 on Azure User Guide

| Product: Meilisearch on Ubuntu 24.04 LTS on Azure

Overview

Meilisearch is a fast, open source search engine that returns relevant, typo tolerant results in milliseconds, with built in AI and vector search for hybrid semantic queries. It exposes a clean REST API with official client libraries for most languages, and adds filtering, faceting, custom ranking, synonyms and multi language tokenization out of the box.

The cloudimg image installs the official Meilisearch single binary at /usr/local/bin/meilisearch, running as the meilisearch service bound to loopback 127.0.0.1:7700, behind nginx on port 80. nginx is ready for your TLS certificate.

Secure by default, no default login: Meilisearch runs an insecure no authentication development mode when no master key is set. This image never ships that. The service runs in production mode, which refuses to start without a master key, so every API endpoint requires authentication. A meilisearch-firstboot.service oneshot generates a unique master key on each VM's first boot, writes it to a root only file, resolves the instance URL and writes a root only info note, then disables itself. No two VMs share a key and none is baked into the image.

Always current: on first boot the appliance downloads the newest Meilisearch release binary (falling back to the baked version if the network is unavailable), so every launch runs current software rather than the version frozen at build time.

Note on the interface: Meilisearch is an API first service. Version 1.49 ships no bundled web interface (a browser request to / returns a JSON status), so you drive it through its REST API, the official client libraries, or your own application. This guide uses curl against the API.

What is included:

  • Meilisearch (verified at 1.49.0) as the official single static binary
  • meilisearch.service in production mode, bound to 127.0.0.1:7700
  • nginx reverse proxy on port 80, ready for TLS
  • meilisearch-firstboot.service for the first boot master key, binary refresh and info note
  • A unique per VM master key generated on first boot, in a root only 0600 file
  • Ubuntu 24.04 LTS base, fully patched
  • 24/7 cloudimg support, 24h response SLA

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet with a subnet. Meilisearch is lightweight, but search performance and index capacity scale with memory. Recommended VM size: Standard_B2s (2 vCPU, 4 GB RAM) for evaluation and small indexes, or a Standard_D2s_v5 or larger for production workloads with bigger datasets. Meilisearch keeps its index on the OS disk, so expand the disk before loading large collections.

Step 1: Deploy from the Azure Portal

Search the Marketplace for Meilisearch on Ubuntu 24.04, choose your VM size, and attach an NSG that allows TCP 22 (SSH) from your management network and TCP 80 / 443 (the API) from the networks and applications that need to query it. Front port 80 with TLS in production (see the HTTPS section below).

Step 2: Deploy from the Azure CLI

RG="meilisearch-prod"; LOCATION="eastus"; VM_NAME="meilisearch-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/meilisearch-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name meili-vnet --address-prefix 10.90.0.0/16 --subnet-name meili-subnet --subnet-prefix 10.90.1.0/24
az network nsg create -g "$RG" --name meili-nsg
az network nsg rule create -g "$RG" --nsg-name meili-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name meili-nsg --name allow-web --priority 110 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 80 443 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name meili-vnet --subnet meili-subnet --nsg meili-nsg --public-ip-sku Standard

Step 3: Connect via SSH

ssh azureuser@<vm-ip>

Step 4: Verify the services are running

Meilisearch listens on loopback 127.0.0.1:7700 and nginx fronts the API on port 80. The health endpoint is public; everything else requires your master key.

sudo systemctl start meilisearch nginx 2>/dev/null || true
sudo systemctl is-active meilisearch nginx
ss -tln | grep -E ':80 |127.0.0.1:7700'
curl -s http://127.0.0.1/health

You should see both services active, the two listening sockets, and {"status":"available"} from the health endpoint.

Terminal showing the meilisearch and nginx services active, Meilisearch bound to loopback 7700 with nginx fronting port 80, and the health endpoint returning available

Step 5: Read your per VM master key

The master key was generated on this VM's first boot and stored in a root only file. Read it and keep it secret: it authenticates every API request. Confirm that unauthenticated requests are rejected.

sudo cat /root/meilisearch-info.txt
echo "unauthenticated /keys -> HTTP $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/keys)"

The info note holds MEILI_MASTER_KEY and the instance URL, is owned root:root with mode 0600, and an unauthenticated call to /keys returns 401 because production mode enforces authentication.

Terminal showing production mode rejecting an unauthenticated API call with HTTP 401 and accepting the per VM key with HTTP 200, and the root only master key note

Step 6: Create an index and run your first search

Load the master key into a shell variable, create a movies index, configure its attributes, add a few documents, then run a typo tolerant search. Indexing is asynchronous, so wait for the documents to be processed before searching.

export MEILI_KEY=$(sudo grep '^MEILI_MASTER_KEY=' /root/meilisearch-info.txt | cut -d= -f2-)
H="Authorization: Bearer $MEILI_KEY"
curl -s -X PATCH http://127.0.0.1/indexes/movies/settings -H "$H" -H 'Content-Type: application/json' \
  --data '{"filterableAttributes":["genres","release_year"],"sortableAttributes":["release_year"]}' >/dev/null
curl -s -X POST 'http://127.0.0.1/indexes/movies/documents?primaryKey=id' -H "$H" -H 'Content-Type: application/json' \
  --data '[
    {"id":1,"title":"Interstellar","genres":["Science Fiction","Drama"],"release_year":2014},
    {"id":2,"title":"Inception","genres":["Action","Science Fiction"],"release_year":2010},
    {"id":3,"title":"The Matrix","genres":["Action","Science Fiction"],"release_year":1999},
    {"id":4,"title":"Dune","genres":["Science Fiction","Adventure"],"release_year":2021},
    {"id":5,"title":"Arrival","genres":["Science Fiction","Drama"],"release_year":2016}
  ]' >/dev/null
for i in $(seq 1 20); do
  N=$(curl -s -H "$H" http://127.0.0.1/indexes/movies/stats | jq -r '.numberOfDocuments // 0')
  [ "$N" -ge 5 ] && break; sleep 1
done
echo "indexed documents: $N"
curl -s -X POST http://127.0.0.1/indexes/movies/search -H "$H" -H 'Content-Type: application/json' \
  --data '{"q":"scince fiction","limit":3}' | jq -r '.hits[].title'

Note the deliberate typo in the query (scince fiction): Meilisearch still returns the science fiction titles, ranked by relevance, in a fraction of a millisecond.

Terminal showing the movies index with its documents and a typo tolerant search for scince fiction returning ten matching science fiction films in one millisecond

Step 7: Filter, sort and facet

Because you marked genres and release_year filterable and release_year sortable in Step 6, you can now filter and sort results. This returns science fiction films released after 2013, newest first.

export MEILI_KEY=$(sudo grep '^MEILI_MASTER_KEY=' /root/meilisearch-info.txt | cut -d= -f2-)
H="Authorization: Bearer $MEILI_KEY"
curl -s -X POST http://127.0.0.1/indexes/movies/search -H "$H" -H 'Content-Type: application/json' \
  --data '{"q":"","filter":"genres = \"Science Fiction\" AND release_year > 2013","sort":["release_year:desc"],"limit":5,"attributesToRetrieve":["title","release_year"]}' \
  | jq -r '.hits[] | .title + " (" + (.release_year|tostring) + ")"'

Step 8: AI powered hybrid search

Meilisearch combines classic keyword search with vector search so a query can match on meaning as well as words. Configure an embedder on the index (for example an OpenAI compatible provider, or supply your own vectors), then pass a hybrid object on the search request. The embedder configuration looks like this:

{
  "embedders": {
    "default": {
      "source": "openAi",
      "apiKey": "YOUR_PROVIDER_API_KEY",
      "model": "text-embedding-3-small"
    }
  }
}

With an embedder set, add "hybrid": {"embedder": "default", "semanticRatio": 0.5} to any search body to blend keyword and semantic relevance. See the Meilisearch documentation for embedder options and self hosted models.

Step 9: Enable HTTPS

nginx fronts the API on port 80 and is ready for TLS. Point a DNS record at the VM, then obtain a certificate with certbot and let it configure nginx for port 443.

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com

After issuance, restrict the NSG so only 443 (and 22 from your management network) is reachable, and query the API over https://your-domain.example.com/.

Persistence, first boot and updates

The search index lives on the OS disk under /var/lib/meilisearch/data.ms and is captured into the image, so a VM launched from this image is ready immediately. The first boot service generates the per VM master key, refreshes the Meilisearch binary to the latest release, then disables itself so subsequent reboots are unaffected. The OS ships fully patched with unattended security upgrades enabled.

Terminal showing the Meilisearch binary version, the first boot service, the search index on the OS disk and a clean OS security baseline with no held packages

Support

Every cloudimg deployment includes 24/7 support with a 24 hour response SLA. Contact support@cloudimg.co.uk for help with deployment, configuration or scaling.

This is a repackaged open source software product with additional charges for cloudimg support services. Meilisearch is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.