aboutsummaryrefslogtreecommitdiffstats
path: root/docs/example.toml
blob: 95b6f52bf059ab2ceeaa907775e18f655eef780d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# An example configuration with every option, explained (`configuration.md` has the
# rules). Use it with `continuum --config example.toml`; `continuum --print-config`
# shows what a configuration amounts to, and `continuum --help` lists the options.
#
# Keys are the long option names. Nested tables join their keys with `-`: `key-file`
# under `[mycelium]` is `mycelium-key-file`. Options left out (or commented out, as most
# are here) take their defaults, shown in the comments. Command-line arguments win over
# files.
#
# Any value can come from elsewhere instead of being written out:
#   { env = "NAME" }, { file = "PATH" }, { command = "COMMAND" } or
#   { command = ["program", "argument"] }, with format = "json" to parse it as JSON;
# and text can mix in such values: "node-${env:HOSTNAME}" (`$$` for a `$`).
# Imported values are never logged or shown by --print-config.

# --- Other files -----------------------------------------------------------------------

# Load these first (a path or a list), in this order; relative to this file. This file's
# own values win over its includes, later includes over earlier ones. An entry
# { path = "...", optional = true } is skipped where the file is missing.
# include = ["/run/secrets/continuum.toml", { path = "local.toml", optional = true }]
# Options to set back to their defaults here (e.g. one an include sets).
# unset = ["alias"]

# --- Who this node is ------------------------------------------------------------------

# This node's key (Ed25519, 32 raw bytes): who the node is, whatever transport reaches
# it. Keep it with the node: a new key is a new node. Required (but with relay-only).
node-key-file = "/var/lib/continuum/node.key"

# Create a new node key at node-key-file if there is no file there (a new node). Without
# it, a missing key file is an error, so a mistyped path never makes a new node. Best
# given once on the command line (--node-key-create) rather than kept here.
# node-key-create = false

# A name for this node, shown next to its node ID (/peers, metrics). Published in the
# member list; not unique, never an identity.
# alias = "node-${env:HOSTNAME}"

# Only relay (libp2p circuit relay), without being a node: no document, no swarm, no
# node key. Needs libp2p alone (libp2p's enable, no other), its listen and
# key-file; options about a swarm or a document (node-key-file, seeds, genesis,
# state-file, ...) are errors with it. The HTTP API, with htpasswd, has /health,
# /admin/stats and /admin/log only. List such relays in the document
# (_continuum/relays) or in libp2p's relays.
# relay-only = false

# --- The HTTP API ------------------------------------------------------------------------

# Address of the HTTP API. Plain HTTP: to expose it, put a TLS proxy in front.
# bind-addr = "127.0.0.1:3000"

# Users of the HTTP API (an htpasswd file with Argon2 hashes). Required (but with
# relay-only: without it, no HTTP API).
htpasswd = "/etc/continuum/htpasswd"

# HTTP API users (from htpasswd) who may write protocol data under /store/_continuum
# (remake records, members, forget records), e.g. to repair a stuck remake. Such writes
# act on the whole swarm and are logged. Epoch metadata and the swarm ID are never
# writable.
# protocol-writers = ["alice"]

# How log lines look: text (timestamped), journal (for systemd's journal: no timestamp or
# colours, the level as each line's priority, for journalctl -p), or auto: journal when
# stdout goes to the journal, else text.
# log-format = "auto"

# Log node IDs and transport identities as they are. Without it, a member's read
# `<scheme>:<alias>` wherever they appear (`continuum:<alias>`, `libp2p:<alias>`), as the
# member list names it.
# log-raw-ids = false

# Enable the /debug endpoints (tests only).
# debug-api = false

# --- The swarm ---------------------------------------------------------------------------

# How to reach a node of the swarm to join: an address (`mycelium:<public key>` or
# `libp2p:<multiaddr>`, as GET /admin/stats lists them), a Mycelium public key or IPv6
# address, a host name with an AAAA record for one, or a libp2p multiaddr (with or
# without /p2p/<peer ID>). A node keeps trying until it has joined.
# seeds = ["node1.example.org", "libp2p:/ip6/fd00::1/tcp/9661"]

# Start a new swarm, as its genesis node, instead of joining one through seeds. Every
# start with it starts another new swarm: drop it once the swarm exists, and give the
# node seeds instead. Can't be combined with seeds. With a state file that remembers a
# swarm, it starts that swarm again instead (empty; nodes of it still running merge with
# this one). Best given once on the command line (--genesis).
# genesis = false

# With genesis: make the new swarm's document as a remake of this kind would, instead of
# starting it empty: import:PATH (an Automerge document, e.g. a backup, without its
# history and protocol data) or replace:PATH (a JSON document, the store root); compact
# changes nothing.
# remake = "import:/var/backups/continuum.automerge"

# Start the swarm again from a backup (as GET /admin/document saves it): this node loads
# it, on the swarm and epoch it names, and is ready at once; other nodes join it.
# Members of the swarm still running merge with it, or it rejoins them if they moved on
# to a newer epoch (the backup is then dropped). For one start: command line.
# recover-from = "/var/backups/continuum.automerge"

# Pre-shared swarm key: only nodes that know it may join (raw bytes, at least 16; e.g.
# `head -c 32 /dev/urandom`). Without it, any node that can reach a member may join.
# swarm-key-file = "/etc/continuum/swarm.key"

# Create a new swarm key at swarm-key-file if there is no file there: on the swarm's
# first node, as the others need a copy of it (a key of their own keeps them out).
# Without it, a missing key file is an error.
# swarm-key-create = false

# Not in files: `force` (override checks that refuse to start: swarmId,
# badDocumentFile, replaceDocumentFile) is for one start, on the command line only.

# --- Files of this node ------------------------------------------------------------------

# Where this node remembers its swarm across restarts: the swarm ID and some members to
# rejoin through (not the document). Written once ready, then rarely. Without it, a
# restarted node knows only its configured seeds.
# state-file = "/var/lib/continuum/state.json"

# This node's document on disk. Read at start: the node resumes with it, ready at once.
# Kept up to date while ready: changes are appended every document-append, and the file
# is rewritten after a switch, a rejoin or a restart, and when the appended changes
# outgrew it.
# document-file = "/var/lib/continuum/document.automerge"

# How often changes are appended to the document file.
# document-append = "5s"

# Shortest time between rewrites of the document file because its appended changes
# outgrew its full save (a new epoch or a restart rewrites it at once).
# document-rewrite = "1h"

# --- Timings and sizes -------------------------------------------------------------------
# Durations: seconds (30, 0.5) or with units (500ms, 30s, 1m, 1h30m, 7d).
# Sizes: bytes or with units (64KiB, 4MiB).

# Keepalive interval; dormancy, resync and probe timings derive from it. 15–30s on a
# LAN or between servers, 1–2m over WAN, mobile or metered links.
# keepalive = "1m"

# Longest wait between HELLOs to a member that doesn't answer: they start at 10
# keepalives and double up to this, so it bounds how long a returning member, or the
# other side of a partition, takes to be noticed. Default: 60 keepalives (1h at 1m).
# dormant-probe-max = "15m"

# Neighbours each node keeps (at least 2). Swarms of up to this many + 1 nodes are a
# full mesh; larger ones sync over several hops. With several transports, about this
# many per transport.
# neighbours = 12

# Members that renewed their alive stamp within this time vote on remakes (a majority of
# them must agree). At least 7h. Members renew their stamps every seventh of the
# shortest window any of them publishes, hourly at most, so nodes may differ. Matters
# on the node that coordinates a remake.
# electorate-window = "7d"

# What becomes of a write a remake or rejoin would carry over into the new epoch though
# a newer one touched its path (last writer wins, by the writers' clocks): "drop" leaves
# it out (logged), "quarantine" keeps it for an operator (GET /admin/quarantine).
# superseded-writes = "drop"

# Warn in the log when this node's clock differs from most of its peers' by more than
# this, for sure (beyond half the round trip it was measured over, from their PONGs); 0:
# never.
# clock-skew-warn = "2s"

# Chunk size when serving large transfers to other nodes (e.g. an epoch's snapshot to a
# rejoining node), 1KiB to 4MiB.
# blob-chunk = "64KiB"

# --- Transports --------------------------------------------------------------------------

# The transports' order of preference, whether enabled or not (each is enabled in its
# own table: enable = true). A peer is reached on the first enabled one both have until
# the paths are measured, then on the fastest; nodes on several carry the traffic
# between nodes that share none. Options of a transport not enabled are ignored.
# transport-order = ["mycelium", "libp2p", "tor"]

[mycelium]
# Use this transport (in builds with the mycelium feature). A node needs one at least;
# none is on by default.
# enable = false

# Peers of the supervised Mycelium daemon (overlay links), not continuum peers. Public
# Mycelium nodes are used only if listed here.
# peers = ["tls://127.0.0.1:9651"]

# Private key of the supervised Mycelium daemon (its identity, and so its address); a
# new one each start if absent.
# key-file = "/var/lib/continuum/mycelium.key"

# Create a new key at key-file if there is no file there (a new Mycelium address).
# Without it, a missing key file is an error.
# key-create = false

# TCP port the supervised daemon listens on for overlay peers; a free port if absent.
# tcp-listen-port = 9651

# A private Mycelium network for the supervised daemon: its key and its name, together.
# They keep other Mycelium nodes from reaching ours at all.
# network-key-file = "/etc/continuum/mycelium-network.key"
# network-name = "example"

# Use a Mycelium daemon running elsewhere (its REST API) instead of supervising one.
# Excludes the options above except peers. Secret: a URL may carry credentials.
# rest-url = "http://[::1]:8989"

[libp2p]
# Use this transport (in builds with the libp2p feature).
# enable = false

# Where to listen. Without, the node only connects out (peers answer over its
# connections, and a relay makes it reachable). Its listen addresses are published in
# the member list, loopback and link-local ones left out.
# listen = ["/ip4/0.0.0.0/tcp/9661", "/ip4/0.0.0.0/udp/9661/quic-v1", "/ip6/::/tcp/9661"]

# The addresses to publish instead of those listened on, e.g. a public address forwarded
# to this node's listen port.
# announce = ["/ip4/203.0.113.7/tcp/9661"]

# Its key (Ed25519, 32 raw bytes), which makes its peer ID; a new one each start if
# absent (the node ID stays the same either way). Worth keeping on a relay, so others'
# addresses through it stay the same.
# key-file = "/var/lib/continuum/libp2p.key"

# Create a new libp2p key at key-file if there is no file there (a new peer ID). Without
# it, a missing key file is an error.
# key-create = false

# Relay for nodes of the swarm that can't be dialled (bounded: 1024 circuits, 64 per
# peer, each up to an hour and 1 GiB), and say so in the member list, where nodes that
# need a relay find it. Needs a listen address others can dial.
# relay = false

# Relays to use when this node can't be dialled (no listen address others could dial,
# or AutoNAT says so): multiaddrs, with or without the relay's peer ID. It picks up to
# two relays, these first, then members that relay. Any libp2p node serving circuit
# relay v2 will do; most keep circuits short (2 minutes, 128 KiB), enough to punch holes.
# relays = ["/ip4/203.0.113.7/tcp/9661"]

# Find nodes on the LAN (multicast DNS, IPv4). Those that speak continuum are seeds
# while joining, so nodes on one LAN find each other without seeds; a swarm key keeps a
# new node from joining another swarm on the same LAN.
# mdns = false

# Ask the router to forward this node's listen ports (UPnP), and publish where, so that
# nodes elsewhere can dial it without a relay or hole punching. Opens those ports on the
# router for as long as the node runs.
# upnp = false

# Address ranges libp2p leaves out (VPNs, say): neither published nor offered for hole
# punching nor dialled, and connections there are refused. Announced addresses are
# published anyway.
# ignore = ["10.244.0.0/16", "42::/16"]

# Hosts on the internet (names or addresses), only to tell whether this node has a
# route to the internet, per IPv4 and IPv6 (the routing table is asked; nothing is sent
# to them). Where it has none, its own public addresses of that family aren't
# published. Without, it isn't asked.
# internet-hosts = ["one.one.one.one"]

# Use public libp2p infrastructure: join the IPFS DHT (through the IPFS bootstrap nodes)
# to find peers' addresses and public relays, picked after members that relay. Public
# relays only keep circuits for minutes and some KiB: enough to punch holes through
# NATs. Makes this node's peer ID and addresses known to the DHT. Without it, nothing
# public is used.
# public = false

[tor]
# Use this transport (in builds with the tor feature).
# enable = false

# Where arti (Tor, embedded) keeps its state and cache, among them the onion service's
# key, which makes its address: keep it with the node. Required with tor.
# state-dir = "/var/lib/continuum/tor"

# The port of this node's onion service.
# port = 9662