Hosting it for others
Linux hosts
Raise vm.max_map_count before indexing anything (not needed on Docker Desktop). Without it Elasticsearch
starts fine and then fails searches (all shards failed, map failed in its log) as the library grows.
sudo sysctl -w vm.max_map_count=262144 # now
echo 'vm.max_map_count=262144' | sudo tee /etc/sysctl.d/99-elasticsearch.conf # after a reboot
It is a host setting, not a container one. On Unraid, put the sysctl -w line in /boot/config/go, and give
Elasticsearch a pool path (/mnt/cache/...) rather than the FUSE /mnt/user/... share.
Security
- Harden Elasticsearch before exposing anything: the bundled one is single-node with security off.
- Keep port 3001 on your LAN. The
/v1and/mcpendpoints need no sign-in and can list your whole library (never your notes). - Search engines are told to stay out (
noindexandrobots.txt). - Found a vulnerability? Report it privately: see SECURITY.md.
Behind a reverse proxy
Pass the live-updates stream (/api/v1/events) unbuffered, make /api/notes/collab WebSocket-aware with a long
idle timeout, allow large request headers (nginx: large_client_header_buffers 4 64k), match
client_max_body_size to MAX_UPLOAD_BYTES, send the real Host, and terminate TLS there. Run one app
instance: co-editing lives in-process. With sign-in on, also set AUTH_URL (see Sign-in).
Behind a web application firewall
With CrowdSec AppSec, Coraza or similar, route /api/v1/upload-* and /api/v1/audio/stage past it in the
proxy. The proxy's firewall plugin sends the whole body to the firewall before the firewall's own rules run, so a
skip rule on the firewall side (CrowdSec's DisableBodyInspection()) comes too late: a multi-GB upload times out
there and is refused, and Bibliup logs nothing. With Caddy and the CrowdSec bouncer, keep the IP check and skip only
appsec (the inner route keeps appsec in order, since handle sorts its directives and appsec has no default
order):
@upload path /api/v1/audio/stage /api/v1/upload-*
route {
crowdsec
handle @upload {
reverse_proxy app:3000
}
handle {
route {
appsec
reverse_proxy app:3000
}
}
}