How to Self-Host Sonic with Docker Compose
What Is Sonic?
Sonic is a lightweight, schema-less search backend designed to replace heavy search engines like Elasticsearch when you need basic full-text search with minimal resource usage. Written in Rust, Sonic uses less than 20 MB of RAM while providing fast search with auto-complete suggestions. It’s not a database — it stores search indexes only and returns document IDs that you look up in your actual database.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 64 MB+ RAM (Sonic is extremely lightweight)
- 1 GB free disk space
- No GPU required
Docker Compose Configuration
Create a docker-compose.yml file:
services:
sonic:
image: valeriansaliou/sonic:v1.4.9
container_name: sonic
ports:
- "1491:1491"
volumes:
- sonic_data:/var/lib/sonic/store
- ./sonic.cfg:/etc/sonic.cfg:ro
restart: unless-stopped
volumes:
sonic_data:
Create a sonic.cfg configuration file:
[server]
log_level = "info"
[channel]
inet = "0.0.0.0:1491"
tcp_timeout = 300
[channel.search]
query_limit_default = 10
query_limit_maximum = 100
query_alternates_try = 4
suggest_limit_default = 5
suggest_limit_maximum = 20
[store]
[store.kv]
path = "/var/lib/sonic/store/kv/"
retain_word_objects = 1000
[store.kv.pool]
inactive_after = 1800
[store.kv.database]
flush_after = 900
compress = true
[store.fst]
path = "/var/lib/sonic/store/fst/"
[store.fst.pool]
inactive_after = 300
[store.fst.graph]
consolidate_after = 180
max_size = 2048
max_words = 250000
Start the stack:
docker compose up -d
Initial Setup
Sonic uses a custom text protocol over TCP (not HTTP). Use a Sonic client library or telnet:
telnet localhost 1491
Connect and Push Data
START search SecretPassword
# Connected to Sonic
# Push text into the index
PUSH messages user:1 conv:1 "Hello, how are you today?"
PUSH messages user:1 conv:2 "Let's talk about self-hosting"
# Search
QUERY messages user:1 "self-hosting"
# Returns: conv:2
# Auto-suggest
SUGGEST messages user:1 "sel"
# Returns: self-hosting
QUIT
Using Client Libraries
Sonic has official and community client libraries for most languages:
- Node.js:
sonic-channel - Python:
sonic-client - Go:
go-sonic - Ruby:
sonic-ruby - PHP:
php-sonic
Example with Node.js:
const Sonic = require("sonic-channel");
const search = new Sonic.Search({ host: "localhost", port: 1491, auth: "SecretPassword" });
await search.connect();
const results = await search.query("messages", "user:1", "self-hosting");
// results = ["conv:2"]
Configuration
Key Config Options
| Section | Setting | Default | Description |
|---|---|---|---|
channel.inet | 0.0.0.0:1491 | Listen address and port | |
channel.search.query_limit_default | 10 | Default results per query | |
channel.search.query_alternates_try | 4 | Typo correction alternatives | |
channel.search.suggest_limit_default | 5 | Default suggestions count | |
store.kv.retain_word_objects | 1000 | Word objects kept in memory | |
store.fst.graph.max_words | 250000 | Max words in suggestion graph |
Authentication
Set a password in sonic.cfg:
[channel]
auth_password = "YourSecretPassword"
All client connections must authenticate with START [mode] [password].
Reverse Proxy
Sonic uses a TCP protocol, not HTTP. You cannot put it behind a standard HTTP reverse proxy. Access it directly via port 1491 from your application servers. Restrict access via firewall rules. See Reverse Proxy Setup.
Backup
Back up the Sonic data volume:
docker run --rm -v sonic_data:/data -v $(pwd):/backup alpine \
tar czf /backup/sonic-backup.tar.gz /data
Sonic stores search indexes only. If you lose the data, you can re-index from your source database. See Backup Strategy.
Troubleshooting
Connection Refused
Symptom: Can’t connect on port 1491.
Fix: Verify channel.inet in sonic.cfg is set to 0.0.0.0:1491. Check Docker port mapping. Ensure the config file is mounted correctly.
No Search Results
Symptom: QUERY returns empty results.
Fix: Verify data was pushed with PUSH. The collection and bucket names must match exactly. Sonic indexes text — it returns document IDs, which you look up in your database.
High Memory Usage
Symptom: Sonic using more RAM than expected.
Fix: Reduce retain_word_objects in config. Reduce max_words in FST graph settings. Sonic is designed to use minimal RAM, so high usage usually indicates a very large index.
Resource Requirements
- RAM: 10-50 MB (extremely lightweight)
- CPU: Very low
- Disk: Index size is typically 10-20% of indexed text
Verdict
Sonic is the lightest search engine you can self-host. If you need basic full-text search and auto-suggest for an application and don’t want the overhead of Elasticsearch or even Meilisearch, Sonic does the job in 20 MB of RAM. The trade-off is a limited feature set — no faceting, no aggregations, no HTTP API.
Choose Sonic for minimal search on resource-constrained servers (Raspberry Pi, cheap VPS). Choose Meilisearch for a more complete search engine with an HTTP API. Choose Elasticsearch for full-featured search and analytics.
Frequently Asked Questions
How does Sonic compare to Meilisearch?
Sonic is a search index that returns document IDs — it doesn’t store or serve documents. Meilisearch is a full search engine with an HTTP API, faceting, filtering, and document storage. Sonic uses 10-50 MB of RAM; Meilisearch uses 500+ MB. Choose Sonic for minimal search on constrained hardware; Meilisearch for a complete search solution.
Does Sonic have an HTTP API?
No. Sonic uses a custom TCP-based text protocol, not REST/HTTP. You need a Sonic client library (available for Node.js, Python, Go, Ruby, PHP) to integrate with your application. This is simpler to implement but less standard than HTTP APIs.
Can Sonic handle typos and fuzzy matching?
Yes. Sonic includes built-in typo correction via the query_alternates_try setting. It also supports auto-suggest through the SUGGEST command, which provides word completions as users type.
Does Sonic replace my database?
No. Sonic is a search index only — it stores search terms mapped to document IDs. When you search, Sonic returns IDs that you look up in your actual database (PostgreSQL, MySQL, MongoDB, etc.). It’s a complement to your database, not a replacement.
Can Sonic run on a Raspberry Pi?
Yes. Sonic is one of the few search engines that runs well on ARM hardware with as little as 64 MB of RAM. The Rust binary is efficient on low-power devices, making it ideal for homelab search functionality.
How do I add data to Sonic?
Use the PUSH command via a client library or TCP connection. For each document, push the text content along with a collection name, bucket name, and unique object ID. Sonic indexes the text and returns the object ID when searches match.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments