Run a node on the Flowsta network. Your node stores and serves the network's public data — decentralized identities and document signatures — adding redundancy and geographic spread. Optionally, it can also serve as an open bootstrap/relay, helping peers find and reach each other even if Flowsta's own infrastructure is unreachable.
- Stores public data only: identity records (W3C DIDs, agent linking attestations, public profiles) and Sign It signatures (document signatures, content rights, perceptual hashes, thumbnails). Private user data never reaches your node — it lives in per-user encrypted networks your node is not a member of, by construction.
- Auto-installs the current DNAs on first boot and auto-updates by polling the Flowsta API every 6 hours, verifying every download against published checksums.
- Runs anywhere Docker runs: an old PC, a home server, a repurposed HoloPort, a small VPS.
- 64-bit Linux with Docker + Docker Compose
- 2 GB+ RAM, 20 GB+ free disk (grows slowly with network history)
- Always-on internet; no inbound ports needed for the basic node
- For the optional bootstrap role: a public IP or forwarded port 443, a domain name, and a TLS certificate (guide below)
git clone https://github.com/WeAreFlowsta/flowsta-dht-node.git
cd flowsta-dht-node
./setup.shThat's it. The script checks Docker, writes the production-network config, and starts the node. The conductor image is public (no registry login), the bundled DNAs install on first boot, and the sidecar keeps them current - including any public DNAs Flowsta adds in the future, each download verified against published checksums before install.
Prefer to do it by hand?
cp conductor-config-example.yaml conductor-config.yaml # works as-is for production
echo "API_URL=https://auth-api.flowsta.com" > .env
docker compose up -d- Public data only. Your node stores identity records and document signatures - the network's public layer. Private user data never reaches your node, by construction.
- Disk grows slowly with network history (20 GB headroom is plenty today). Bandwidth is light for the basic node; only the optional bootstrap role relays traffic.
- Zero maintenance. DNA updates are automatic and
checksum-verified.
git pull && docker compose up -doccasionally for node software updates. - Stop anytime.
docker compose down- the network loses one redundant copy and nothing else. No penalties, no obligations.
Questions or want to tell us your node exists (especially bootstrap nodes - see below)? Discord or hello@flowsta.com.
A node can look healthy while gossiping with nobody (wrong config, wrong network, blocked egress). Two checks, a couple of minutes after startup:
# 1. DNAs installed and enabled?
docker exec flowsta-sidecar node -e "
import('@holochain/client').then(async ({ AdminWebsocket }) => {
const a = await AdminWebsocket.connect({ url: new URL('ws://localhost:4444'),
wsClientOptions: { origin: 'flowsta-dht-node' } });
const apps = await a.listApps({});
console.log(apps.map(x => x.installed_app_id + ' [' + x.status.type + ']').join('\n'));
process.exit(0); });"
# 2. Seeing remote peers? (should climb well past your own app count)
docker exec flowsta-sidecar node -e "
import('@holochain/client').then(async ({ AdminWebsocket }) => {
const a = await AdminWebsocket.connect({ url: new URL('ws://localhost:4444'),
wsClientOptions: { origin: 'flowsta-dht-node' } });
console.log('peer store entries:', (await a.agentInfo({ dna_hashes: null })).length);
process.exit(0); });"If the peer count stays at (roughly) your own app count, your node is
isolated — check the bootstrap URLs and auth material in
conductor-config.yaml, and that outbound HTTPS/QUIC isn't blocked.
Flowsta's primary bootstrap server is how peers first find each other. Community bootstrap nodes are the network's fallback: an open (unauthenticated), rate-limited rendezvous + relay that keeps peer discovery alive even if the primary is unreachable. Running one is the single most valuable thing a community operator can contribute.
Extra requirements: a domain (or dynamic DNS) pointing at your node, port 443 reachable from the internet, and a TLS certificate.
Check for CGNAT first — before touching DNS or certificates:
compare your router's WAN IP (its status page) with what the internet
sees (curl ifconfig.me). If they differ — especially if the router
shows an address starting with 100.64–100.127, 10., or 172. —
your ISP has you behind carrier-grade NAT and no port forwarding can
work. Ask your ISP for a public IP (many provide one on request,
free or cheap), then continue. The basic node needs none of this —
CGNAT only blocks the bootstrap role.
Then, with a domain pointed at your public IP and ports 80/443 forwarded:
./setup.sh bootstrapThe script re-checks CGNAT with you, verifies your DNS, obtains the certificate, and starts the node with the bootstrap role.
Prefer to do it by hand?
sudo certbot certonly --standalone -d node.example.com # stop anything on :80 first
TLS_DOMAIN=node.example.com docker compose --profile bootstrap up -dVerify: curl -s https://node.example.com/ should answer. Then tell
us about your node — community bootstrap URLs are distributed to
Flowsta apps as fallback rendezvous.
Bandwidth note, honestly: the bootstrap role includes an Iroh relay, which carries traffic for peers that can't connect to each other directly. On a home connection this is typically modest, but it is not zero — monitor it, and drop the role at any time by restarting without the profile.
A HoloPort is a capable little x86 box for this. The path:
Tested end-to-end on a real HoloPort (it becomes the network's kind of node it was always meant to be):
- Flash Ubuntu Server 24.04 LTS (amd64) to a 4 GB+ USB stick
(balenaEtcher or
dd). Everything on the HoloPort - HoloPortOS and any HoloFuel state - will be erased. - Plug in keyboard, monitor, ethernet, and the USB. Power on and tap the boot-menu key: F11 (then F10 or DEL/F2 for the BIOS boot order if the menu doesn't bite).
- Through the installer: use entire disk, and install the OpenSSH server - after this the box runs headless.
- While you're in the BIOS anyway: enable restore on power loss (usually under Chipset/ACPI) so the node comes back by itself after an outage.
- Reboot, pull the USB, SSH in, install Docker
(
curl -fsSL https://get.docker.com | sh,sudo usermod -aG docker $USER, log out and back in). - Follow the Quick start above. Done in ~45 minutes, most of it unattended.
Create a .env file in the repo root:
| Variable | Required | Default | Description |
|---|---|---|---|
API_URL |
Yes | — | Flowsta API URL for auto-updates |
CONDUCTOR_IMAGE |
No | public Flowsta image | Override the conductor image |
UPDATE_INTERVAL |
No | 21600 (6 h) |
Seconds between auto-update checks |
TLS_DOMAIN |
bootstrap role | — | Domain whose Let's Encrypt cert to serve |
NODE_SECRET |
No | — | Legacy; bundle downloads are open (sha256-verified) |
Networks: the example config joins the production network — the only network community nodes should join. (Flowsta operates separate internal networks for testing; nodes must never mix networks.)
Auth material: the value in the example config is the shared community client id — public by design. It identifies community nodes to Flowsta's rate limiting and can be rotated if abused; it is not a secret and grants nothing beyond bootstrap access.
Three containers (host networking):
- conductor — Holochain 0.6.1/Iroh edge node; stores data, runs
gossip, admin WebSocket on
localhost:4444(not exposed beyond the host). Data persists in theconductor-dataDocker volume across restarts and upgrades. - sidecar — installs bundled DNAs on first boot; polls the Flowsta API for new versions every 6 hours and verifies every bundle against the manifest's sha256 before installing.
- bootstrap-srv (optional,
--profile bootstrap) — upstreamkitsune2-bootstrap-srv: open peer discovery + SBD signal + Iroh relay.
DNA updates are automatic. To trigger one manually:
docker exec flowsta-sidecar node /app/updater/dht-update.mjsTo update the node software itself:
git pull
docker compose pull
docker compose up -d # add --profile bootstrap if you run itOld DNA versions are kept on purpose — your node keeps serving history for peers on older versions.
docker logs flowsta-conductor --tail 50 # conductor
docker logs flowsta-sidecar --tail 50 # DNA installs + updates- Peer count stuck at ~your own apps — wrong bootstrap URL/auth material, or the config was edited after first boot: recreate the conductor container to regenerate from the template.
CellAlreadyExists/AppAlreadyInstalledin sidecar logs — harmless; the DNA is already installed.- Disk growth — logs are capped by the compose logging config; DHT data growth is gradual at current network size.
- Bootstrap role: cert renewal — certbot renews automatically;
restart the container after renewal
(
docker restart flowsta-bootstrap-srv).
Apache-2.0 - see LICENSE. The bundled .happ files are built
from Flowsta's DNA repositories, also Apache-2.0.