bolt Valebyte VPS from $4/mo — NVMe, 60s deploy.

Get a VPS arrow_forward
eco Beginner Tutorial/How-to

Installing MeiliSearch on a VPS

calendar_month Jul 20, 2026 schedule 16 min read visibility 64 views
info

Need a server for this guide? We offer dedicated servers and VPS in 50+ countries with instant setup.

Need a server for this guide?

Deploy a VPS or dedicated server in minutes.

Installing MeiliSearch on a VPS: Fast and Powerful Search for Your Applications

TL;DR

In this guide, we will step-by-step set up and launch MeiliSearch – a high-performance, open-source search engine – on your virtual or dedicated server. You will learn how to install MeiliSearch using Docker, configure it for secure HTTPS access with Caddy, and set up basic maintenance and backup to ensure reliable search functionality for your web applications.

  • Setting up a secure and performant search server on a VPS.
  • Using Docker for simple and reliable MeiliSearch installation.
  • HTTPS configuration with automatic certificate management via Caddy.
  • Server protection basics with Fail2ban and UFW.
  • Creating a simple script for MeiliSearch data backup.
  • Recommendations for choosing the optimal VPS configuration for search tasks.

What we are setting up and why

In the modern world, the speed of access to information is critically important. For any web application, online store, blog, or content management system, the presence of fast and relevant search is a key factor in user experience. This is precisely the problem MeiliSearch solves – a powerful and lightweight open-source search engine written in Rust.

MeiliSearch provides a RESTful API that allows for easy integration into any application. It features high indexing and search speeds, "out-of-the-box" result relevance thanks to smart ranking algorithms, and support for faceted search, filtering, and morphology. Ultimately, the reader will have a fully functional MeiliSearch server, ready to receive data and process search queries from their applications.

There are various approaches to implementing search: using cloud services (e.g., Algolia, Elastic Cloud) or self-hosting solutions like Elasticsearch, Solr, or MeiliSearch. Cloud services are convenient but can be expensive with large data volumes or queries, and they impose limitations on infrastructure control. Self-hosting on a VPS or dedicated server, conversely, provides full control, flexibility, and often lower operational costs in the long run. MeiliSearch, in this context, stands out for its ease of installation, low resource requirements compared to Elasticsearch, and excellent performance, making it an ideal choice for deployment on your own VPS.

What VPS configuration is needed for this task

Choosing the right VPS configuration for MeiliSearch depends on the volume of data you plan to index and the expected search load. MeiliSearch uses resources efficiently, but certain minimums are required for stable operation.

Minimum Requirements:

  • CPU: 1-2 cores. MeiliSearch scales well with the number of cores, especially during indexing.
  • RAM: 2 GB. This is sufficient for small to medium data volumes (up to several million documents) and moderate load. MeiliSearch loads the index into RAM for fast searching.
  • Disk: 20-40 GB NVMe SSD. Disk speed is critical for indexing and writing data. NVMe significantly outperforms SATA SSDs.
  • Network: 100 Mbps. This is sufficient for most applications.

Recommended VPS Plan for Starting (valid for 2026):

For most projects where the data volume does not exceed 10-20 million documents and up to several hundred search queries per minute are expected, a VPS with the following configuration will be optimal:

  • CPU: 2-4 vCPU (e.g., Intel Xeon E5 or AMD EPYC).
  • RAM: 4-8 GB. This will provide headroom for a larger index and the operating system.
  • Disk: 50-100 GB NVMe SSD. Sufficient for storing the index and system files.
  • Network: 1 Gbps. This will ensure fast data transfer between the application and MeiliSearch.

You can get a VPS with the specified characteristics to ensure stable MeiliSearch operation with room for growth.

When a dedicated server is needed, not a VPS:

A dedicated server becomes necessary when:

  • The volume of indexed data exceeds hundreds of millions or billions of documents.
  • Very high throughput is required for thousands of search queries per second.
  • The application has strict requirements for latency and stable performance, which a VPS cannot guarantee due to "noisy neighbors".
  • Full control over hardware is needed, including specific processors (e.g., with large cache) or RAID arrays.

In such cases, it's worth considering a suitable dedicated server.

Location: What it affects

Server location affects the latency between your main application and MeiliSearch, as well as between users and your application. It is advisable to place the MeiliSearch VPS as close as possible to your main application to minimize latency during indexing and searching. If your application is in Europe, choose a European data center. If your target audience is in North America, then the server should be there too.

Server Preparation

Before installing MeiliSearch, you need to perform basic security setup and update the operating system. We will be using Ubuntu Server 24.04 LTS, the current and supported version for 2026.

1. SSH Connection and Creating a Sudo User:

After receiving your VPS access details, connect to it as the root user:


ssh root@YOUR_IP_ADDRESS

Create a new user for daily operations (e.g., meiliuser) and add them to the sudo group:


adduser meiliuser
usermod -aG sudo meiliuser

Set up SSH keys for the new user. Copy your public SSH key from your local machine:


# On your local machine
ssh-copy-id meiliuser@YOUR_IP_ADDRESS

Disable SSH login for root and password login, leaving only key-based login for meiliuser. Edit the file /etc/ssh/sshd_config:


sudo nano /etc/ssh/sshd_config

Find and change the following lines:


PermitRootLogin no
PasswordAuthentication no

Restart the SSH service:


sudo systemctl restart sshd

Exit the root session and log in as meiliuser.

2. System Update:

Always start by updating the package database and installed packages:


sudo apt update         # Update the list of available packages
sudo apt upgrade -y     # Upgrade all installed packages to the latest versions
sudo apt autoremove -y  # Remove unnecessary dependencies

3. Installing Basic Utilities and Fail2ban:

Let's install the necessary utilities and Fail2ban to protect SSH from brute-force attacks:


sudo apt install -y curl wget git htop fail2ban unzip

Fail2ban is configured by default to protect SSH. To enable it, simply install it. For more fine-grained configuration, you can create the file /etc/fail2ban/jail.local:


sudo nano /etc/fail2ban/jail.local

Add the following content:


[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 1h

Restart Fail2ban:


sudo systemctl restart fail2ban

4. UFW Firewall Configuration:

Enable UFW (Uncomplicated Firewall) and allow only the necessary ports:


sudo ufw allow OpenSSH       # Allow SSH (port 22)
sudo ufw allow http          # Allow HTTP (port 80)
sudo ufw allow https         # Allow HTTPS (port 443)
sudo ufw enable              # Enable the firewall
sudo ufw status verbose      # Check firewall status

Confirm firewall activation by pressing y.

Software Installation — Step-by-step

We will install MeiliSearch using Docker, as this is the most flexible and recommended method, ensuring isolation and easy version management. Current versions for 2026: Docker Engine 26.x, MeiliSearch 1.9.x, Caddy 2.8.x.

1. Installing Docker Engine:

Install the necessary packages for Docker:


sudo apt install -y ca-certificates curl gnupg lsb-release

Add Docker's official GPG key:


sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Add the Docker repository to APT sources:


echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Update the package list and install Docker Engine, Docker CLI, and containerd:


sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Add the current user to the docker group to run Docker commands without sudo:


sudo usermod -aG docker meiliuser

Log out of SSH and log in again for group changes to take effect. Verify Docker installation:


docker run hello-world  # Run a Docker test container

2. Installing MeiliSearch with Docker Compose:

Create a directory for MeiliSearch and the docker-compose.yml file:


mkdir ~/meilisearch
cd ~/meilisearch
nano docker-compose.yml

Paste the following content into docker-compose.yml. Specify the current MeiliSearch version (e.g., v1.9) and your own MEILI_MASTER_KEY:


version: '3.8'
services:
  meilisearch:
    image: getmeili/meilisearch:v1.9 # Use the current MeiliSearch version
    container_name: meilisearch
    ports:
      - "127.0.0.1:7700:7700" # Bind to local interface, access will be via Caddy
    volumes:
      - ./data.ms:/meili_data # Directory for storing index data
    environment:
      - MEILI_MASTER_KEY=YOUR_SECRET_MASTER_KEY # Be sure to replace with a strong key
      - MEILI_ENV=production # Indicate that this is a production environment
      - MEILI_HTTP_ADDR=0.0.0.0:7700 # MeiliSearch will listen on all interfaces inside the container
    restart: always # Automatic container restart on failure

Start MeiliSearch using Docker Compose:


docker compose up -d # Start the MeiliSearch container in the background

Verify that the container is running:


docker ps # Shows running containers

You should see the meilisearch container running on port 7700 (bound to 127.0.0.1).

3. Installing Caddy (Reverse Proxy and HTTPS):

Caddy is a powerful and easy-to-use web server that automatically configures HTTPS with Let's Encrypt. It is ideal for proxying requests to MeiliSearch.

Add Caddy's GPG key:


sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

Add the Caddy repository:


curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list

Update the package list and install Caddy:


sudo apt update
sudo apt install -y caddy

Check Caddy's status:


sudo systemctl status caddy # Verify that Caddy is running and active

Configuration

Now that MeiliSearch and Caddy are installed, you need to configure Caddy to proxy requests to MeiliSearch and provide HTTPS access.

1. Caddyfile Configuration:

Edit the main Caddy configuration file — Caddyfile:


sudo nano /etc/caddy/Caddyfile

Remove all default content and insert the following, replacing your-domain.com with your domain name (e.g., search.mydomain.com) and YOUR_SECRET_MASTER_KEY with the same key you used in docker-compose.yml:


your-domain.com {
    # Automatic SSL certificate acquisition from Let's Encrypt
    tls {
        dns cloudflare {env.CLOUDFLARE_API_TOKEN} # Example for Cloudflare. Use your DNS provider or leave tls if you are using A/AAAA records
    }

    # API key protection (additional layer of security)
    header Authorization "Bearer YOUR_SECRET_MASTER_KEY"

    # Proxying requests to MeiliSearch, running on local port 7700
    reverse_proxy 127.0.0.1:7700 {
        header_up Host {host}
        header_up X-Real-IP {remote_ip}
        header_up X-Forwarded-Proto {scheme}
    }

    # Logging configuration (optional)
    log {
        output file /var/log/caddy/meilisearch_access.log
        format json
    }

    # Error handling (optional)
    handle_errors {
        respond "{http.error.status_code} {http.error.status_text}" {http.error.status_code}
    }
}

Important: For automatic TLS certificate acquisition using a DNS provider (as in the Cloudflare example), you will need to install the appropriate Caddy plugin and configure environment variables. If you are using A/AAAA records and your domain is externally accessible, simply specifying tls without additional options is sufficient, and Caddy will obtain the certificate itself. If you are using a DNS plugin, ensure that environment variables (e.g., CLOUDFLARE_API_TOKEN) are set in the Caddy service file or via system variables.

For Caddy with Cloudflare DNS, install the plugin:


# Example of installing the Caddy plugin for Cloudflare DNS.
# This step may vary depending on your DNS provider.
# If you are not using a DNS plugin, skip this step.
sudo apt install -y caddy-dns-cloudflare # Or another plugin, e.g., caddy-dns-digitalocean

If you use a DNS plugin, add environment variables to the Caddy service file. Edit the file /etc/systemd/system/caddy.service.d/override.conf (create if it doesn't exist):


sudo systemctl edit caddy

Add the following lines (replace with your token):


[Service]
Environment="CLOUDFLARE_API_TOKEN=YOUR_CLOUDFLARE_API_TOKEN"

Save the file and restart Caddy:


sudo systemctl daemon-reload # Reload systemd to apply service changes
sudo systemctl restart caddy # Restart Caddy to apply the configuration and obtain the certificate
sudo systemctl status caddy  # Check Caddy status

Ensure that Caddy has started successfully and obtained an SSL certificate. There should be no TLS-related errors in the logs.

2. Health Check:

Use curl to check MeiliSearch availability via Caddy:


curl -I https://your-domain.com/health # Check MeiliSearch health status

If everything is configured correctly, you should receive a response with HTTP status 200 OK. You can also check the MeiliSearch version:


curl -X GET 'https://your-domain.com/version' \
  -H 'Authorization: Bearer YOUR_SECRET_MASTER_KEY'

You should see a JSON response with MeiliSearch version information.

3. Open Firewall Ports (if not done previously):

Ensure that ports 80 and 443 are open in UFW:


sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

Backups and Maintenance

Reliable backups and regular maintenance are critically important for any production service, including MeiliSearch.

1. What to Back Up:

  • MeiliSearch Data: The main volume of data, including indexes, settings, and documents, is stored in the directory specified in docker-compose.yml (in our case, ./data.ms).
  • Configuration Files: docker-compose.yml, /etc/caddy/Caddyfile, as well as any files related to system or firewall settings.

2. Simple Auto-Backup Script:

Let's create a simple script to create a snapshot of MeiliSearch data and archive it. MeiliSearch has a built-in snapshot feature.

Create a directory for backups and the script:


mkdir -p ~/backups/meilisearch
nano ~/backup_meilisearch.sh

Insert the following content, replacing YOUR_SECRET_MASTER_KEY and your-domain.com:


#!/bin/bash

# Path to MeiliSearch directory
MEILI_DIR="/home/meiliuser/meilisearch"
# Path for storing backups
BACKUP_DIR="/home/meiliuser/backups/meilisearch"
# MeiliSearch domain
MEILI_DOMAIN="your-domain.com"
# MeiliSearch master key
MEILI_MASTER_KEY="YOUR_SECRET_MASTER_KEY"
# Backup filename
BACKUP_FILENAME="meilisearch_$(date +%Y%m%d%H%M%S).dump"

echo "Starting MeiliSearch dump creation..."

# Create MeiliSearch dump via API
curl -X POST "https://${MEILI_DOMAIN}/dumps" \
  -H "Authorization: Bearer ${MEILI_MASTER_KEY}" \
  -H "Content-Type: application/json"

# Wait a few seconds for the dump to be created.
# In production, it's better to check the dump status via the API /dumps/{dump_uid}/status
sleep 10

# Copy the created dump from the Docker container
# First, find the UID of the latest dump
LATEST_DUMP_UID=$(curl -X GET "https://${MEILI_DOMAIN}/dumps" \
  -H "Authorization: Bearer ${MEILI_MASTER_KEY}" \
  | jq -r '.[-1].uid')

# If jq is not installed, you can install it: sudo apt install -y jq
# If LATEST_DUMP_UID is empty, something went wrong
if [ -z "$LATEST_DUMP_UID" ]; then
    echo "Error: Failed to get the UID of the latest dump."
    exit 1
fi

echo "Copying dump ${LATEST_DUMP_UID} from the container..."
docker cp meilisearch:/meili_data/dumps/${LATEST_DUMP_UID}.dump ${BACKUP_DIR}/${BACKUP_FILENAME}

if [ $? -eq 0 ]; then
    echo "Dump successfully copied to ${BACKUP_DIR}/${BACKUP_FILENAME}"
    # Clean up old backups (keep the last 7 days)
    find ${BACKUP_DIR} -type f -name 'meilisearch_*.dump' -mtime +7 -delete
    echo "Old backups deleted."
else
    echo "Error copying dump."
fi

echo "Backup completed."

Make the script executable:


chmod +x ~/backup_meilisearch.sh

Add the script to cron for daily execution (e.g., at 3 AM):


crontab -e

Add the following line to the end of the file:


0 3 * * * /home/meiliuser/backup_meilisearch.sh >> /var/log/meilisearch_backup.log 2>&1

3. Where to Store Backups:

Storing backups on the same server as the main service is insecure. It is recommended to use:

  • External S3-compatible storage: For example, AWS S3, DigitalOcean Spaces, Backblaze B2. Utilities like s3cmd or rclone can be used for automatic uploads.
  • Separate VPS: A small VPS dedicated exclusively to storing backups. rsync over SSH can be used for synchronization.
  • Local Network Attached Storage (NAS): If you have your own infrastructure.

For an example with rclone (install sudo apt install -y rclone):


# Example of adding S3 upload to the backup_meilisearch.sh script
# ... after the line "Backup completed."
echo "Uploading dump to S3..."
rclone copy ${BACKUP_DIR}/${BACKUP_FILENAME} remote:bucket_name/meilisearch_backups/
if [ $? -eq 0 ]; then
    echo "Dump successfully uploaded to S3."
else
    echo "Error uploading dump to S3."
fi

Configure rclone beforehand using rclone config.

4. Updates:

  • OS Updates: Regularly run sudo apt update && sudo apt upgrade -y. Plan this once a month or as important security updates are released.
  • Docker Updates: Update Docker Engine as stable versions are released.
  • MeiliSearch Updates: Updating MeiliSearch usually involves changing the image tag in docker-compose.yml (e.g., from v1.9 to v1.10) and restarting the container:
    
                cd ~/meilisearch
                # Change the version in docker-compose.yml
                docker compose pull meilisearch # Pull the new image
                docker compose up -d           # Recreate the container with the new image
                

    Rolling vs. Maintenance Window: For MeiliSearch, which is a critically important search service, updates are best performed during a "maintenance window" with prior notification to users. Although Docker allows for quick switching between versions, there is always a risk of incompatibility or data migration issues. Always back up before updating MeiliSearch.

  • Caddy Updates: Caddy is updated via APT: sudo apt update && sudo apt upgrade -y caddy. After the update, Caddy will automatically restart.

Troubleshooting and FAQ

Troubleshooting + FAQ

MeiliSearch does not start or is inaccessible

What to check: Ensure that the MeiliSearch Docker container is running (docker ps). Check the container logs (docker logs meilisearch) for errors. Make sure that port 7700 is not occupied by another application (sudo netstat -tulnp | grep 7700) and that MeiliSearch is bound to 127.0.0.1, as specified in docker-compose.yml. Also, check that Caddy is running (sudo systemctl status caddy) and its logs (sudo journalctl -u caddy).

How to fix: If the container does not start, correct errors in docker-compose.yml (typos, incorrect master key). If the port is occupied, change it or stop the other application. If Caddy cannot obtain a certificate, check the domain's DNS records and the correctness of the Caddy DNS plugin configuration (if used).

Slow indexing or searching

What to check: Monitor server resources (htop, docker stats meilisearch). Check CPU, RAM, and disk subsystem usage. A slow disk (non-NVMe) can be a bottleneck during indexing. A large number of documents or complex filters can slow down searches. Ensure that MeiliSearch has enough RAM to load the index.

How to fix: Increase RAM or switch to a VPS with a faster NVMe disk. Optimize data structure, reduce the number of fields for indexing, or use facets more efficiently. Consider scaling MeiliSearch to a more powerful server or distributing the load, if possible.

401 Unauthorized error when accessing API

What to check: Ensure that you are passing the correct MEILI_MASTER_KEY in the Authorization: Bearer YOUR_KEY header. Check that the key in docker-compose.yml and in Caddyfile (if you are using Caddy to add the header) match.

How to fix: Carefully check the master key. If you forgot it, you can change it in docker-compose.yml and restart the container, but this may affect existing applications using the old key. Ensure that Caddy correctly adds the Authorization header if it is configured to do so.

Unable to obtain SSL certificate for domain

What to check: Ensure that your domain correctly points to your VPS's IP address (A/AAAA records). Check that ports 80 and 443 are open in UFW. If you are using the Caddy DNS plugin, ensure that the API token for your DNS provider is correct and has the necessary permissions.

How to fix: Correct DNS records. Open ports 80 and 443 in the firewall. Recheck the API token and permissions for the DNS plugin. Check Caddy logs (sudo journalctl -u caddy) for more detailed information about Let's Encrypt errors.

What is the minimum suitable VPS configuration?

What to check: For small projects with data volumes up to several million documents and low load (up to several requests per second), a VPS with 2 vCPU, 2 GB RAM, and 20-40 GB NVMe SSD will be minimally suitable. This will be sufficient for basic MeiliSearch operation.

How to fix: Always focus on the data volume. If the index grows, RAM requirements will also increase. With increased search load, more CPU will be needed. It's always better to have a small reserve of resources to avoid performance degradation.

What to choose — VPS or dedicated for this task?

What to check: The choice depends on the scale of your project. A VPS is suitable for most medium-sized projects where flexibility, rapid deployment, and cost-effectiveness are critical. It is ideal for startups, small, and medium web applications.

How to fix: A dedicated server is necessary for very large data volumes (hundreds of millions of documents or more), high load (thousands of requests per second), or strict requirements for stable performance without "neighbor" influence. It also provides full control over hardware, which can be important for specific optimization or security.

Conclusions and Next Steps

Congratulations! You have successfully installed and configured MeiliSearch on your VPS, providing fast and powerful search for your applications, secured with HTTPS using Caddy. Now your search engine is ready for data indexing and processing search queries.

Next steps for further development and optimization:

  • Application Integration: Use the official MeiliSearch SDKs for your programming language (JavaScript, PHP, Python, Ruby, etc.) to send data for indexing and execute search queries.
  • Performance Monitoring: Set up a monitoring system (e.g., Prometheus + Grafana) to track MeiliSearch metrics such as response time, number of documents, and resource usage.
  • Index Optimization: Study the MeiliSearch documentation on configuring relevance, synonyms, stop words, facets, and filters to maximize search quality for your users.

Was this guide helpful?

Your feedback helps us improve our guides.

Share this post:

Send this guide to someone who may find it useful.

Telegram VKVK WhatsApp Facebook LinkedIn XX

Meilisearch Installation on VPS: Fast and Powerful Search for Your Applications
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.