Meilisearch — это быстрый поисковый движок с простым API. Его часто используют как альтернативу тяжёлым решениям вроде Elasticsearch, когда нужна скорость и минимальная настройка. Он отлично подходит для проектов на VDS: занимает мало ресурсов, поднимается за минуты и не требует сложной конфигурации.
Если вы только купили сервер:
Подключитесь к серверу
Выполните подготовку сервера к работе
Самый простой способ это скачать готовый бинарник.
curl -L https://install.meilisearch.com | sh
После выполнения появится файл meilisearch в текущей директории.
Сделаем его исполняемым и перенесём в системный путь:
chmod +x meilisearch
mv meilisearch /usr/local/bin/
/usr/local/bin — стандартное место для пользовательских утилит.
Проверим, что всё установилось:
meilisearch --version
Запустим Meilisearch в простом режиме:
meilisearch
По умолчанию он стартует на порту 7700.
По умолчанию Meilisearch запускается без защиты. Это удобно для тестов, но опасно на проде.
Добавим master key:
meilisearch --master-key="СЛОЖНЫЙ_КЛЮЧ"
meilisearch --master-key="Jgfjhgf%^HGFD@32123"
Почему это критично: без ключа любой может отправлять запросы к вашему поиску. В реальности это означает утечку данных или мусор в индексе.
Чтобы сервис не падал после перезагрузки, оформим его как systemd-сервис.
1. Создадим системного пользователя meilisearch.
sudo useradd -r -s /bin/false meilisearch
2. Выдадим права.
sudo chown -R meilisearch:meilisearch /var/lib/meilisearch
3. Создадим файл.
sudo nano /etc/systemd/system/meilisearch.service
Вставляем:
[Unit]
Description=Meilisearch
After=network.target
[Service]
User=meilisearch
ExecStart=/usr/local/bin/meilisearch --db-path /var/lib/meilisearch --http-addr 127.0.0.1:7700
Environment="MEILI_MASTER_KEY=СЛОЖНЫЙ_КЛЮЧ"
Restart=always
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
User=meilisearch — запуск от безопасного пользователя, а не root;Restart=always — сервис перезапустится при падении;LimitNOFILE — увеличивает лимит файлов, иначе при нагрузке можно упереться в ограничения.Сохраняем и запускаем:
sudo systemctl daemon-reload
sudo systemctl enable meilisearch
sudo systemctl start meilisearch
Проверим статус:
sudo systemctl status meilisearch
Статус active означает, что сервис запущен.
Если статус failed, то причину можно посмотреть в логах.
journalctl -f -u meilisearch
Проверим, что API отвечает:
curl http://127.0.0.1:7700/health
Ожидаемый ответ:
{"status":"available"}
Если не отвечает — смотрите логи:
journalctl -u meilisearch -f
Представим ту же задачу: есть сайт со статьями или товарами.
Нужно сделать быстрый полнотекстовый поиск без сложной инфраструктуры.
Meilisearch здесь заменяет и Elasticsearch, и отдельный поисковый слой, он сам хранит и индексирует данные.
Если требуется, то установите mysql-connector-python. Если у вас уже он есть или вы используете другую БД, то не нужно.
pip install meilisearch mysql-connector-python
Клиент позволяет работать с поиском напрямую через API, без лишней логики и настроек. Установка должна происходить в виртуальную среду вашего проекта.
Если у вас есть своя БД, то пропустите этот шаг.
Подключаемся к MySQL и создаём тестовую таблицу для демонстрации работы. Если у вас есть реальные данные, то можете попробовать на них.
mysql
CREATE DATABASE search_demo;
USE search_demo;
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
content TEXT,
category VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Потом создадим пользователя и выдадим права.
CREATE USER 'search_user'@'localhost' IDENTIFIED BY 'StrongPass123';
GRANT ALL PRIVILEGES ON search_demo.* TO 'search_user'@'localhost';
FLUSH PRIVILEGES;
Если у вас есть реальные данные, то этот шаг тоже можно пропустить.
У нас их нет, поэтому создадим нагрузку, похожую на реальный проект.
import mysql.connector
import random
import string
DB_CONFIG = {
"host": "localhost",
"user": "search_user",
"password": "StrongPass123",
"database": "search_demo"
}
conn = mysql.connector.connect(**DB_CONFIG)
cursor = conn.cursor()
categories = ["devops", "backend", "frontend", "database", "security"]
def random_text(words=12):
return " ".join(
"".join(random.choices(string.ascii_lowercase, k=random.randint(4, 10)))
for _ in range(words)
)
print("Генерация данных...")
for _ in range(10000):
title = random_text(6)
content = random_text(25)
category = random.choice(categories)
cursor.execute(
"INSERT INTO articles (title, content, category) VALUES (%s, %s, %s)",
(title, content, category)
)
conn.commit()
print("Готово: 10 000 записей создано")
Скопируем это в новый файл gen_data.py и выполним.
Было создано нужное количество записей для теста поиска по ним.
В отличие от Elasticsearch, здесь не нужно заранее описывать схему.
Meilisearch сам понимает структуру документов.
from meilisearch import Client
import mysql.connector
client = Client('http://127.0.0.1:7700', 'MyStrongKey123')
index = client.index("articles")
DB_CONFIG = {
"host": "localhost",
"user": "search_user",
"password": "StrongPass123",
"database": "search_demo"
}
conn = mysql.connector.connect(**DB_CONFIG)
cursor = conn.cursor()
cursor.execute("SELECT id, title, content, category FROM articles")
rows = cursor.fetchall()
documents = []
for row in rows:
documents.append({
"id": row[0],
"title": row[1],
"content": row[2],
"category": row[3]
})
task = index.add_documents(documents)
print("Индексация запущена...")
index.wait_for_task(task.task_uid)
print("Индексация завершена")
Скопируем это в новый файл index.py и выполним.
from meilisearch import Client
client = Client('http://127.0.0.1:7700', 'MyStrongKey123')
index = client.index("articles")
def search(query):
result = index.search(query)
print(f"\nРезультаты поиска по: {query}\n")
for hit in result["hits"][:10]:
print("ID:", hit["id"])
print("Title:", hit["title"])
print("Category:", hit["category"])
print("-" * 40)
search("backend")
Создадим файл search.py и выполним поиск по слову backend или по другому нужному вам слову.
Поиск занял очень маленькое время, были выведены все нужные данные.
Установка Meilisearch действительно простая, а результат ощущается сразу. Вы получаете быстрый поиск без сложной инфраструктуры.