Meilisearch 部署教程:给网站加上亚毫秒级全文搜索
搜索是大多数网站逃不掉的功能。MySQL 的 LIKE 在数据量过万之后就开始变慢,Elasticsearch 又重得让人望而却步,而 Meilisearch 正好填补了中间的空缺——用 Rust 写的轻量级搜索引擎,单容器就能跑,官方 demo 中搜索响应普遍在几十毫秒内。本教程按 GitHub 仓库 README 的事实为准,一步一步把 Meilisearch 用 Docker 部署起来,并把搜索接入到你的网站里。
Meilisearch 是什么
Meilisearch 是一个开源的搜索引擎,目标是「开箱即用 + 亚毫秒级响应」。它不是数据库,而是为了搜索而生的引擎:你把文档喂给它,它帮你建索引、提供 RESTful API 返回匹配结果。
从 README 的 Features 列表可以看到它的能力覆盖得相当全:混合搜索(语义 + 全文)、即时搜索(Search-as-you-type)、容错匹配(typo tolerance)、过滤与分面、排序、同义词、地理搜索、多语言(中文/日文/希伯来文/拉丁语系都有优化)、租户隔离、API Key 鉴权、文档关联、分片与复制等。
这意味着无论是电商商品搜索、博客全文检索、CRM 联系人查找,还是文档知识库,都能套上 Meilisearch。

前置准备
部署 Meilisearch 本身的要求不高,按 README 与社区实践,需要准备:
- Docker:用于拉取官方镜像
meilisearch/meilisearch,单容器即可运行 - 512M 内存起步:官方对最低内存的建议是小数据集 512M 起步,中等规模建议 1G 以上
- 一个可用的端口:默认监听 7700,建议内网或反代后访问,不要直接暴露公网
- 生产环境必须设置 Master Key:这是 Meilisearch 安全模型的硬性要求,没设 key 等同于公开可写
如果是云服务器,建议提前在安全组里把 7700 端口限制为只允许内部访问或反代服务器访问。
Docker 单容器部署
最简单的方式是用一行 docker run 跑起来。仓库 README 里推荐的命令形式如下:
docker run -d \
-p 7700:7700 \
-v meili:/meili_data \
meilisearch/meilisearch
这条命令做了三件事:
-d后台运行容器-p 7700:7700把宿主机 7700 映射到容器内的 7700-v meili:/meili_data把数据卷挂到容器内的/meili_data,保证重启容器后索引数据不丢
容器启动后,访问 http://:7700 应该能看到 Meilisearch 的内置预览 UI。这个 UI 不只是展示用,还能直接在里面调试索引和搜索请求,开发阶段非常方便。
必须设置的环境变量
单容器跑起来只是第一步。生产部署前必须设置 MEILI_MASTER_KEY,否则任何人只要能访问到 7700 端口,就能往你的索引里塞数据、删数据、改数据——这是 README 里反复强调的安全要求。
生成一个强随机密码作为 master key:
openssl rand -base64 32
把生成的字符串填入环境变量:
docker run -d \
-p 7700:7700 \
-v meili:/meili_data \
-e MEILI_MASTER_KEY=你的强随机密码 \
--name meilisearch \
meilisearch/meilisearch
除了 master key,还有一些常用的环境变量可以根据需要设置(具体参数请参考官方文档):
| 环境变量 | 作用 |
|---|---|
MEILI_MASTER_KEY |
管理 API key,访问管理接口时必须带 |
MEILI_ENV |
运行环境:development 或 production,生产建议设 production |
MEILI_NO_ANALYTICS |
是否关闭遥测,true 表示关闭 |
MEILI_HTTP_ADDR |
监听地址,默认 0.0.0.0:7700 |
MEILI_DB_PATH |
索引数据目录,默认 /meili_data |
索引文档:把数据喂给 Meilisearch
Meilisearch 用「Index(索引)」来组织文档,类似数据库的表。一个 index 里放的是同一类文档,比如 books、products、articles。
下面演示怎么建一个 books 索引并往里塞两条数据。先用 curl 加文档:
curl -X POST 'http://localhost:7700/indexes/books/documents?primaryKey=id' \
-H 'Content-Type: application/json' \
--data-binary '[
{ "id": 1, "title": "老人与海", "author": "海明威" },
{ "id": 2, "title": "百年孤独", "author": "马尔克斯" }
]'
/indexes/books/documents:往 books 索引写文档primaryKey=id:告诉引擎用id字段做主键- 请求体是一个 JSON 数组,每条记录就是一篇文档
文档提交后,Meilisearch 会异步建索引,几百到几千条几乎瞬间完成,几万条以上会稍等几秒。可以查询任务状态确认是否完成:
curl 'http://localhost:7700/tasks?indexUids=books&limit=1' \
-H "Authorization: Bearer 你的强随机密码"
搜索 API:把搜索结果拿回来
索引建好之后,搜索就一行请求的事。Meilisearch 的搜索端点是 /indexes//search:
curl -X POST 'http://localhost:7700/indexes/books/search' \
-H 'Content-Type: application/json' \
-d '{ "q": "海" }'
返回结果大概长这样:
{
"hits": [
{ "id": 1, "title": "老人与海", "author": "海明威" }
],
"query": "海",
"processingTimeMs": 1
}
hits 是命中的文档列表,processingTimeMs 是处理耗时——README 里宣传的「亚毫秒级响应」在这个字段里就能直接看到。
前端集成时只需要发个 POST 请求,把 q 参数换成用户输入的关键词即可。后端 SDK 方面,Meilisearch 官方提供了 JavaScript、Python、Go、Rust、PHP、Ruby、Java 等多种语言版本。

反向代理 + HTTPS:不要把 7700 直接暴露公网
直接把 7700 端口暴露在公网是非常危险的做法,哪怕设了 master key,也容易成为攻击目标。生产环境强烈建议用 Nginx 做反向代理,终止 HTTPS,再把请求转发给 7700。
一个最小可用的 Nginx 配置示例:
server {
listen 443 ssl;
server_name search.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/search.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/search.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:7700;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
这样公网只能访问 443,由 Nginx 加密;7700 仍然只监听在 127.0.0.1,外部网络根本摸不到。
如果想让搜索端点对外开放给浏览器调用(不需要鉴权),又想让管理端点(/keys、/indexes/*/settings 等)带鉴权,可以在 Nginx 层做路径分流:用 if 判断 $request_uri 是否以 /keys 或 /indexes/*/documents 开头,是的话要求带上 Authorization 头,否则 401。
数据持久化与备份
上面 docker run 命令里的 -v meili:/meili_data 是数据卷,由 Docker 自动管理目录,容器删掉重建后索引依然在。但仅靠 Docker volume 不算备份——机器宕机或磁盘损坏照样丢数据。
最稳的备份方式是把整个 /meili_data 目录定期 tar 打包传到对象存储或异地机器。建议至少做到:
- 每日全量备份:用 cron 跑
tar -czf meili-$(date +%F).tar.gz /var/lib/docker/volumes/meili/_data - 大版本升级前手动备份一次:README 提示大版本之间可能有 breaking changes,提前备份有备无患
- 恢复演练:把备份文件解压到一个新目录,挂到临时容器里跑一次,确认能正常搜索
常见坑
生产环境实际用下来,几个最容易踩的坑:
生产没设 master key:这是 README 反复强调的,但在内网测试环境很容易忽略。一旦开放到公网,没设 key 等同于公开可写,攻击者能塞垃圾数据、消耗磁盘。建议把「未设 master key」作为上线 checklist 的硬性项。
版本升级没看 release notes:Meilisearch 迭代很快,主版本号变化(如 0.x → 1.x)通常意味着 schema、配置项或 API 行为有破坏性变更。升级前先看官方 release notes,确认是否需要 reindex。任何时候升级前先备份。
中文搜索效果差:Meilisearch 默认对中文是按字符切分的,对于”南京市长江大桥”这种容易歧义的句子表现一般。README 里也提到中文有专门优化,但更精细的分词通常需要配合 jieba 等分词器在写入前预处理,或者使用 Meilisearch 提供的可配置分词选项。具体配置建议以官方文档为准。
7700 端口直接暴露公网:前面说过,攻击面太大。即使设了 master key,密码也可能被探测或泄露。多一层反代 + HTTPS,多一层保险。
忽略索引任务队列的积压:大批量写入时,建议监控 /tasks 端点的队列长度。如果任务堆积持续增长,说明磁盘 IO 或 CPU 跟不上,需要扩容或减小批量。
收尾
至此 Meilisearch 就部署完了:一个 Docker 容器挂着一个数据卷,前面是 Nginx 反代处理 HTTPS,后端业务通过 RESTful API 把搜索接入到网站。整个栈足够轻量,单台 2 核 4G 的机器就能支撑中等规模站点的搜索请求。
如果还想进一步了解 Meilisearch 在实际项目中的表现,包括它在不同数据规模、不同查询场景下的优缺点对比,可以看这篇评测:Meilisearch 评测:自托管搜索方案对比。

评论(0)