Running a Couchbase Edge Server
Shipped
View as MarkdownThis is the concrete server-side companion to Sync. It gives you a working Couchbase Edge Server you can run in Docker and point the app at. For what actually replicates, how secrets are kept out of the sync stream, and the in-app connection form, read the Sync page — this page is just the server.
Remember the version rule from that page: Bring Your LM is Couchbase Lite 3.x, and Couchbase Edge Server is a 3.x-protocol product. Pin the image to a 1.x release, as below — there is no Edge Server for the newer Couchbase Lite 4.x line yet.
Build the image
Couchbase publishes Edge Server as a Debian package; this Dockerfile installs it onto a slim base and runs it against a mounted config file.
FROM debian:bookworm-slim
ARG CBES_VERSION=1.0.1
ARG CBES_DEB_URL=https://packages.couchbase.com/releases/couchbase-edge-server/${CBES_VERSION}/couchbase-edge-server_${CBES_VERSION}_amd64.deb
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl ca-certificates \
&& curl -fsSL -o /tmp/cbes.deb "${CBES_DEB_URL}" \
&& apt-get install -y --no-install-recommends /tmp/cbes.deb \
&& rm -f /tmp/cbes.deb \
&& apt-get purge -y curl \
&& apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/*
USER couchbase
WORKDIR /opt/couchbase-edge-server/etc
EXPOSE 59840
CMD ["/opt/couchbase-edge-server/bin/couchbase-edge-server", "config.json"]
Build it:
docker build -t couchbase-edge-server:1.0.1 .
The config file
Save this next to the Dockerfile as config.json. It defines one database,
byllm, syncing bidirectionally, and lists every collection the app
replicates. The list must cover them all — a collection the app pushes but the
server doesn't serve will 404. Don't add the server's own _default._default;
the app deliberately doesn't sync it.
{
"interface": "0.0.0.0:59840",
"users": "/opt/couchbase-edge-server/etc/users.json",
"enable_anonymous_users": false,
"logging": { "console": true },
"databases": {
"byllm": {
"path": "/opt/couchbase-edge-server/var/databases/byllm.cblite2",
"create": true,
"enable_client_writes": true,
"enable_client_sync": "bidirectional",
"collections": [
"_default.memories",
"_default.tools",
"_default.api_providers",
"_default.bots",
"_default.conversations",
"_default.conversation_messages",
"_default.image_blobs",
"_default.image_blob_chunks",
"_default.settings",
"_default.workspaces",
"_default.jobs",
"_default.devices",
"_default.key_offers",
"_default.embedded_model_bundles",
"_default.elicitations"
]
}
}
}
The users file
Save this as users.json. Each user needs a bcrypt password hash and the
replicate role. The username and password here are what you type into the
app's sync settings.
{
"alice": {
"password": "$2a$12$REPLACE_WITH_A_BCRYPT_HASH",
"roles": ["replicate"]
}
}
Generate the hash with Apache's htpasswd (from apache2-utils) and drop the
user: prefix it prints, leaving just the $2a$... / $2y$... string:
htpasswd -nbBC 12 alice 'your-strong-password'
If you'd rather run an open server on a trusted network, set
"enable_anonymous_users": true in config.json, drop the "users" line and
the users.json mount, and turn Anonymous access on in the app instead.
Prefer real users for anything reachable beyond your own machine.
Run it
Mount the two config files read-only and keep the database on a named volume so it survives restarts:
docker run -d \
--name couchbase-edge-server \
--restart unless-stopped \
-p 59840:59840 \
-v "$PWD/config.json:/opt/couchbase-edge-server/etc/config.json:ro" \
-v "$PWD/users.json:/opt/couchbase-edge-server/etc/users.json:ro" \
-v cbes-data:/opt/couchbase-edge-server/var/databases \
couchbase-edge-server:1.0.1
Or, with a docker-compose.yml:
services:
couchbase-edge-server:
build: .
image: couchbase-edge-server:1.0.1
container_name: couchbase-edge-server
ports:
- "0.0.0.0:59840:59840"
volumes:
- cbes-data:/opt/couchbase-edge-server/var/databases
- ./config.json:/opt/couchbase-edge-server/etc/config.json:ro
- ./users.json:/opt/couchbase-edge-server/etc/users.json:ro
restart: unless-stopped
volumes:
cbes-data:
Point the app at it
In the app, open Settings, then Sync, enable it, and set the endpoint to
your host, port 59840, and the database name byllm:
ws://<host>:59840/byllm
Fill in the username and password from users.json. On a plain LAN ws:// is
fine; over the internet, terminate TLS at a reverse proxy and use wss:// —
the endpoint carries all your synced data.
wss://cbe.example.com/byllm
Behind a reverse proxy
For remote access, put the container behind a proxy that terminates HTTPS on a
hostname and forwards to 59840. With Traefik, labels on the container do it:
labels:
traefik.enable: "true"
traefik.http.routers.cbe.rule: "Host(`cbe.example.com`)"
traefik.http.routers.cbe.entrypoints: "websecure"
traefik.http.services.cbe.loadbalancer.server.port: "59840"
The app then connects with wss://cbe.example.com/byllm.
Keep the collection list current
When a future version of the app adds a new collection, this server's
collections list has to grow to match, or that new data silently won't sync.
The list above is the complete set the current app replicates.