Search and analytics engines
When your app uses a search engine, an analytics database or a graph database, OpsCrew can run it as one node next to the app: OpenSearch, Elasticsearch, Meilisearch, Typesense, ClickHouse or Neo4j Community. Each gets a memory limit, its engine’s own memory settings below that limit, a generated key or password where the engine has a login, and no open port. These engines are heavy for a small server: each has a server size it is comfortable on. On Hetzner Cloud and DigitalOcean, design picks a server at least that big; on a smaller server you already have, it warns you. Like every component, an engine costs nothing beyond the server memory it takes, which design shows with its share of the server’s price (see Components).
What OpsCrew runs
Section titled “What OpsCrew runs”| Engine | Version | Memory limit (lowest) | Smallest server | Licence | Login |
|---|---|---|---|---|---|
| OpenSearch | 3.9 | 1024 MB (768 MB) | 4 GB | Apache 2.0 | none: only the app’s containers reach it |
| Elasticsearch | 9.5 | 1024 MB (768 MB) | 4 GB | Elastic License 2.0 | generated password |
| Meilisearch | 1.55 | 512 MB (256 MB) | 2 GB | MIT | generated master key |
| Typesense | 30.2 | 512 MB (256 MB) | 2 GB | GPL 3.0 | generated API key |
| ClickHouse | 26.3, a long-term release | 1024 MB (768 MB) | 2 GB | Apache 2.0 | user app, generated password |
| Neo4j Community | 2026.09 | 1536 MB (1024 MB) | 4 GB | GPL 3.0 | user neo4j, generated password |
OpsCrew adds an engine when it finds your app’s client library for it. Turn one off with
enabled: false on the service in opscrew/plan.yaml, and give the app a hosted engine’s address
instead. Cassandra is never run on the server: it is built for a ring of several nodes, so OpsCrew
keeps it where the app reaches it now (a hosted Cassandra such as DataStax Astra DB works with the
app’s driver).
Elasticsearch’s official image is under the Elastic License 2.0, and Typesense and Neo4j Community under the GPL 3.0: all allow running them for your own app; their conditions are about offering or sharing the engine itself.
What your app receives
Section titled “What your app receives”| Engine | Variables |
|---|---|
| OpenSearch | OPENSEARCH_URL (http://opensearch:9200) |
| Elasticsearch | ELASTICSEARCH_URL (http://elastic:<password>@elasticsearch:9200) |
| Meilisearch | MEILISEARCH_HOST (http://meilisearch:7700), MEILISEARCH_KEY |
| Typesense | TYPESENSE_HOST, TYPESENSE_PORT, TYPESENSE_PROTOCOL, TYPESENSE_API_KEY |
| ClickHouse | CLICKHOUSE_URL, CLICKHOUSE_USER, CLICKHOUSE_PASSWORD |
| Neo4j | NEO4J_URI (bolt://neo4j:7687), NEO4J_USERNAME, NEO4J_PASSWORD |
When your app reads its own variable for the address, that one gets the address too. Each key and
password is generated by OpsCrew and kept on the computer that ran npx opscrew provision, never in
your repository.
Each engine’s settings
Section titled “Each engine’s settings”- OpenSearch runs with its security plugin off: it has no login, and only the app’s own containers can reach it, on the app’s internal network. Its Java heap is half the memory limit.
- Elasticsearch runs only for apps that use an Elasticsearch client: since version 7.14,
Elasticsearch clients refuse OpenSearch, and OpenSearch clients refuse Elasticsearch. Security is
on, with the
elasticuser’s password, over plain HTTP on the app’s internal network. Machine learning is off (it needs 6 GB of memory on its own). Its Java heap is half the memory limit. - Meilisearch runs in production mode, which requires its master key. The app gets the master
key itself as
MEILISEARCH_KEY. To search from the browser, create a search-only key with it and give the browser that one, never the master key. Indexing uses at most half the memory limit, and Meilisearch sends no usage data. Before you merge an update of Meilisearch, read its release notes: some versions need the data dumped and imported again. - Typesense keeps its index in memory (about 165 MB for a million short documents), so give it a memory limit to match your data.
- ClickHouse gets a low-memory profile, since its own documentation is written for much larger
servers: it refuses more work once it uses three quarters of its memory limit, keeps small
caches, runs at most 20 queries at once and two threads per query, and leaves out the system log
tables that grow on their own. Only the user
appcan log in from the network. ClickHouse’s long-term releases are the ones numbered YY.3 and YY.8 (26.3, 26.8 …); Dependabot also proposes the releases between them, which are supported for a shorter time, so prefer merging the YY.3 and YY.8 updates. - Neo4j Community has one database, the
neo4juser and its password. Its heap and its page cache each get a third of the memory limit. Its versions are named after the year and month, so Dependabot also proposes the next year’s releases.
The kernel setting of OpenSearch and Elasticsearch
Section titled “The kernel setting of OpenSearch and Elasticsearch”OpenSearch and Elasticsearch map their indexes into memory, and the server’s kernel must allow that
many maps: vm.max_map_count must be at least 262144. That is a setting of the host, not of a
container:
- On Hetzner Cloud and DigitalOcean, the app’s Compose project has a small one-off container
that raises the setting before the engine starts on every deploy, and writes it to
/etc/sysctl.d/90-opscrew.confso a restart of the server keeps it. A value that is already higher stays. - On a server you already have, the host plan sets it in
/etc/sysctl.d/90-opscrew.conf, as a step you see and approve with the rest of the plan.npx opscrew driftreports it when it is lowered later. - In your Portainer, OpsCrew never changes the Docker host, so it does not run OpenSearch or
Elasticsearch there. Design keeps the engine the app uses now (for example Amazon OpenSearch
Service, Aiven for OpenSearch or Elastic Cloud). To run one next to your Portainer yourself, set
it on the Docker host as root (
sysctl -w vm.max_map_count=262144, and the linevm.max_map_count = 262144in a file in/etc/sysctl.d/so a restart keeps it), and give the app its address.
The two engines also get an open-file limit of 65536.
Where the data is
Section titled “Where the data is”On a server, Meilisearch, Typesense, ClickHouse and Neo4j keep their data in
/srv/data/<app>/<name>; OpenSearch and Elasticsearch, whose images run as their own users, in a
Docker volume of the app’s Compose project (<app>_opensearch_data, <app>_elasticsearch_data).
In your Portainer, the data is in the named volumes of the app’s stack. npx opscrew destroy keeps
the data unless you add --delete-data and type the app’s name.