celld opens two HTTP listeners when it starts: the public Worker listener that handles incoming requests to your application, and the internal peer/operator listener that handles cell-ownership messages, operator API calls, and peer-to-peer coordination between nodes. For local development the built-in defaults are sufficient. A fleet node — one that sits behind a load balancer and communicates with peers — needs both listeners configured explicitly so that traffic is routed to the right place.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/denoland/celld/llms.txt
Use this file to discover all available pages before exploring further.
Local development
For a single local node you need only the three bucket settings. The public Worker listener defaults to127.0.0.1:8080:
The internal listener defaults to
127.0.0.1:0 — a random loopback port
chosen by the OS. That is fine for a single-node setup, but a fleet node
must bind the internal listener to a stable address that peers can reach.Fleet node
A fleet node must bind the public and internal listeners to separate, explicitly named addresses, and must advertise the internal address that other nodes can actually reach.| Flag | Env var | Purpose |
|---|---|---|
--listen | CELLD_ADDR | The address the public Worker listener binds to. The load balancer or ingress proxy sends Worker traffic here. |
--internal-listen | CELLD_INTERNAL_ADDR | The address the internal listener binds to. Peers send ownership and coordination traffic here. The operator API is also on this listener. |
--advertise | CELLD_ADVERTISE | The address (hostname or IP, plus port) that other nodes put in ownership records when they try to contact this node. Must be reachable by all peers. |
--listen address is what your load balancer forwards public application
traffic to. The --internal-listen / --advertise address is what other
celld nodes use to hand off cell ownership and exchange coordination messages.
Keep these two paths completely separate — do not expose the internal listener
to the public internet.
Listener rules
celld enforces several rules at startup to prevent common misconfiguration:-
Explicit non-loopback public listener requires an explicit internal
listener. If you set
--listento a non-loopback address (anything other than127.0.0.1/::1), you must also set--internal-listen. This rule catches an obsolete single-listener configuration from earlier releases. -
Explicit advertised address requires an explicit internal listener. If
you set
--advertise, you must also set--internal-listen. -
Literal public IPs in
--advertiseare rejected by default. If you need to advertise a public IP address, setCELLD_UNSAFE_PUBLIC_ADVERTISE=1. This setting does not resolve DNS names or restrict which address the internal listener binds to. -
celld cannot verify hostname or port translation. You are responsible for
ensuring that the address in
--advertiseroutes to the--internal-listenport, not to the public Worker listener.
Health check
Every celld node exposes a health endpoint on the public listener:| Condition | HTTP status | Body |
|---|---|---|
| Node is healthy | 200 OK | {"ok":true} |
| Node is draining (shutting down) | 503 Service Unavailable | drain info |
Docker
To run a celld node in a Docker container, create a named volume for SQLite files, then pass the network, bucket, and listener settings through environment variables and CLI flags:--endpoint and --region for AWS S3. --network host gives the
container direct access to the host network interfaces, which makes the
--internal-listen IP address available without additional port-mapping
configuration. If you use bridge networking instead, ensure that --advertise
resolves to the address that other containers (or hosts) use to reach this
container’s internal port.