Skip to main content

Overview

Meilisearch is an open-source (MIT) search engine for instant, typo-tolerant, faceted search — a self-hosted alternative to Algolia, driven entirely by a REST API. This template deploys a single Meilisearch 1.52 server with persistent index storage, mandatory master-key authentication, an indexing memory budget derived from the container’s own memory limit, optional scheduled snapshots, and scheduled platform volume backups. The image is the Community build, compiled without any Enterprise code. Everything it contains is available here; replication and sharding are not part of it (see Important Notes).

Architecture

  • Meilisearch server — A single-replica stateful workload ({release}-meilisearch) serving the REST API on port 7700. There is no second port: the API, /metrics, and the search preview all live behind 7700.
  • Persistent data — One volume set mounted at /meili_data holding the LMDB index (data.ms), Meilisearch’s own .snapshot files, and dumps. All three paths are set explicitly to absolute locations on the volume, so nothing durable ever lands on the container’s ephemeral layer.
  • Authentication — Always on. The master key comes from an opaque secret you create yourself and reference by name; Meilisearch derives its four built-in API keys from it.

What Gets Created

  • Stateful Meilisearch Workload — A single replica serving the REST API on 7700, with /health used for both probes.
  • Volume Set — Persistent ext4 storage at /meili_data with scheduled snapshots and a final snapshot on delete.
  • Identity — An identity bound to the workload, used to read the master-key secret.
  • Policyreveal on exactly that one secret and nothing else.
The template creates no secrets of its own, and needs no database, cache, or object store.
This template does not create a GVC. You must deploy it into an existing GVC.

Prerequisites

Create the master-key secret before installing. This is required — Meilisearch refuses every route except GET /health without a master key, and a workload referencing a secret that does not exist waits indefinitely with no obvious error. It is an opaque secret with encoding: plain whose entire payload is the key:
Then set auth.secretName to the name you used. Installing with an empty auth.secretName fails at render time.
The key must be at least 16 bytes while server.env is production. A shorter one makes the server refuse to launch with The master key must be at least 16 bytes in a production environment. Rotating the key later regenerates every API key derived from it, breaking every deployed client — treat it as write-once, or plan to redistribute all keys.
Nothing else is required: no cloud account, no bucket, no external database. Backups use platform volume snapshots. Install the template using your preferred method:

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

The default values.yaml for this template:

Image and resources

  • image — The Meilisearch server image. Pin a concrete tag; changing it on a populated volume requires the upgrade procedure below.
  • resources.minCpu / resources.maxCpu / resources.minMemory / resources.maxMemory — CPU reservation and limit, memory reservation and limit for the Meilisearch container.
  • tuning.indexingMemoryPercent — Percentage of resources.maxMemory given to the indexing arena. Accepted range is 20–80; anything else is rejected at render time.
Searches are served from a memory-mapped index, so steady-state RAM is modest — indexing is the hungry phase. Upstream’s rough guide is RAM ≈ ⅓ of the on-disk index size. The indexing budget is derived, not absolute: MEILI_MAX_INDEXING_MEMORY is set to indexingMemoryPercent of resources.maxMemory. At the defaults that is 1024MiB; with maxMemory: 8Gi it becomes 4096MiB. There is deliberately no absolute override, so the budget can never drift from the container’s own limit. Left to itself, Meilisearch budgets two thirds of the RAM it detects — in a container that is routinely the node’s, not your limit — and OOM-kills itself part-way through an indexing task. Raise maxMemory to index faster and to hold a larger index; raise indexingMemoryPercent only if the instance indexes far more often than it searches.
The API rejects a maxCpu-to-minCpu ratio greater than 4:1. The defaults sit exactly at 4:1, so raising maxCpu means raising minCpu too.

Storage

  • volumeset.capacity — Initial volume size in GiB. The platform minimum is 10, and the chart rejects anything smaller at render time.
The single ext4 volume at /meili_data holds data.ms (the LMDB index), snapshots/, and dumps/. Upstream advises against network-mounted storage for the memory-mapped index, so this is a block device rather than shared storage.

Master key

  • auth.secretName — Name of your prerequisite opaque secret. Its whole payload is the master key. The chart creates a policy granting the workload reveal on exactly that secret.

Server

  • server.envproduction (default) or development. Only development serves the browser search-preview UI at /; the master key protects every route either way.
  • server.logLevel — One of ERROR, WARN, INFO (default), DEBUG, TRACE.
  • server.maxPayloadSize — Largest accepted request body. A larger import is rejected with HTTP 413 and The provided payload reached the size limit.
  • server.telemetry — When false (default), no anonymous usage data is sent upstream.
  • server.upgradeDb — Set to true for exactly one deploy when moving to a newer image tag, then back to false. See Upgrading Meilisearch.
With server.env: production, GET / returns HTTP 200 with {"status":"Meilisearch is running"} and no HTML. That is a healthy instance, not a broken one — the search-preview UI is suppressed in production mode by design. Set server.env: development if you want the playground at /.

Metrics

  • metrics.enabled — When true, Meilisearch exposes Prometheus metrics at /metrics on port 7700. The route requires an API key with the metrics.get action; unauthenticated requests get 401.
These are index-level metrics (documents indexed, searches per index, database size) that the platform’s built-in workload metrics cannot see. With metrics.enabled: false (the default), GET /metrics returns HTTP 400 with {"code":"feature_not_enabled"} — not a 404.

Snapshots and backup

Two different things are called “snapshots” here, and they do different jobs:
  • backup.enabled — When true (default), the volume set takes snapshots on backup.schedule.
  • backup.schedule — Cron expression in UTC. Hourly is the platform maximum frequency.
  • backup.retention — How long each snapshot is kept (for example 7d, 720h, 30d).
  • snapshots.enabled — When true, Meilisearch writes a scheduled .snapshot file into /meili_data/snapshots, rewriting it each interval.
  • snapshots.intervalSeconds — Seconds between those snapshots.
The volume set also takes a final snapshot when it is deleted, retained for backup.retention. That final snapshot happens regardless of backup.enabled — setting it to false disables scheduled snapshots only. Changing any backup value updates the volume set without restarting the workload. You can also trigger a Meilisearch snapshot on demand with POST /snapshots, whether or not the scheduled ones are enabled.

Access

  • publicAccess.enabled — When true, the REST API is served over HTTPS on the automatically assigned *.cpln.app canonical endpoint. When false (default), no external inbound traffic is allowed.
  • internalAccess.type — Internal firewall scope of the workload:
  • internalAccess.workloads — Workload links (//gvc/GVC_NAME/workload/WORKLOAD_NAME), used only with workload-list.
Firewall changes take 45–150 seconds to propagate. After toggling publicAccess or internalAccess, requests may keep returning the old behavior (or 503) for more than a minute before settling — re-test rather than concluding the knob does not work.

Connecting

The canonical hostname appears under status.canonicalEndpoint:
Public traffic is HTTPS at the platform edge; same-GVC traffic is plain HTTP carried over the mesh’s own mTLS. A fresh install typically reaches ready: true in 45–60 seconds.

Use a scoped API key, not the master key

On first boot Meilisearch derives four keys from the master key. Fetch them once and hand the right one to each caller:
Indexing is asynchronous: writes return 202 Accepted with a taskUid you can poll on /tasks.
The misspelled query returns the Interstellar document. Use the Search API key, not the admin key, for anything running in a browser.

Upgrading Meilisearch

Meilisearch refuses to open a database written by an older version, so raising image on a populated volume fails by design until you ask for the migration:
1

Confirm a recent backup exists

The migration is not atomic. Check the volume set’s snapshots before starting.
2

Deploy the new image with the migration flag

Set image to the new tag and server.upgradeDb: true in the same deploy. The database is upgraded on startup.
3

Turn the flag back off

Once the workload is ready on the new tag, set server.upgradeDb: false and redeploy so a migration flag is not left permanently on.
If you raise the image tag without the flag, the new container exits with Your database version (X) is incompatible with your current engine version (Y). and restarts in a loop. The platform keeps the old, working version serving for roughly two minutes before the deployment flips to not-ready, so a forgotten flag looks fine at first and then goes down — check the deployment status, not just the first minute after the upgrade.

Important Notes

  • The master-key secret must exist before you install. If it does not, the deployment hangs waiting on a secret that will never resolve and looks broken. Verify with cpln secret get my-meilisearch-master-key first.
  • Rotating the master key changes every API key. All four built-in keys are derived from it, so a rotation silently breaks every deployed client. Treat it as write-once, or plan to redistribute all keys.
  • Single replica, by design and by edition. Replication and sharding are Meilisearch Enterprise features and are not compiled into the Community image this template ships, so there is no replicas knob and no failover. A restart or upgrade is a real outage of the search endpoint: measured at 87 seconds (68 consecutive failed requests out of 349, at 1 request per second across a helm upgrade). The failures begin about 51 seconds after the upgrade command returns, so the CLI looks finished well before the outage starts. An abrupt replica loss recovers faster — about 20 seconds, with data intact. Have your application fall back to a database query while search is unavailable.
  • server.env: production does not serve the search-preview UI, and GET / returns 200 with {"status":"Meilisearch is running"}. That is a healthy instance. Use server.env: development for the browser playground.
  • /metrics returns 400 feature_not_enabled, not 404, when metrics are disabled. Set metrics.enabled: true to serve it, and call it with a key that has the metrics.get action.
  • Size indexing with resources.maxMemory. The indexing budget is derived from it via tuning.indexingMemoryPercent (default 50%), and there is no absolute override, so the two cannot drift apart.
  • Over-size imports return HTTP 413. A body larger than server.maxPayloadSize is rejected outright and nothing is written — batch large imports or raise the limit.
  • Install into a single-location GVC. A workload runs in every location its GVC has, and each location gets its own volume — two locations means two independent indexes diverging silently behind one endpoint.
  • Uninstall deletes the volume set. A final snapshot is retained for backup.retention, and your own master-key secret is left untouched.

External References

Meilisearch Documentation

Official Meilisearch documentation

Configuration Reference

Every environment variable and command-line option

API Keys and Security

Master key, derived keys, and scoping access

Snapshots and Backups

Meilisearch’s own snapshot and dump formats

Updating Meilisearch

The database migration procedure between versions

Meilisearch Template

View the source files, default values, and chart definition