Before You Start
Four things. Three of them only you can provide.
The Machine
Section titled “The Machine”Ubuntu 26.04 LTS is what the installer is tuned for; anything from 22.04 works. 2 vCPU, 4 GB RAM, at least 20 GB of disk.
3.7 GB of RAM is fine — the installer provisions a 4 GB swapfile. Below that, surface builds fail: a build killed with signal 137 is the box running out of memory. The node still installs and runs when a surface build fails; only that portal is skipped, and re-running the install retries it.
The 4 GB profile runs the database, auth, REST, edge functions, the gateway, storage and realtime. Studio, analytics, image proxying and the connection pooler are off by default.
You do not need to install Docker, Node.js or pnpm yourself. The install preflight does that, and configures the firewall to allow 22, 80 and 443.
The Domain
Section titled “The Domain”A domain you control for the node — node1.example.com, say — and the ability
to set an A record pointing at the box’s public IP.
Each web surface you enable needs its own A record as well
(admin.node1.example.com, my.node1.example.com, and so on). The installer
prints every record it needs.
The Email Provider
Section titled “The Email Provider”Required to go live. One SMTP provider carries all of the node’s mail: sign-in links, signup confirmation and password resets from the auth service, and invitations, notifications and verification codes from the edge functions.
The installer prompts for host, port, user and password, verifies the configuration against the live provider before installing anything, and offers to send you a test message.
| Provider | Host | Port | User | Password |
|---|---|---|---|---|
| Resend | smtp.resend.com | 465 | resend | your API key |
| Postmark | smtp.postmarkapp.com | 465 | server token | server token |
| Your own | per provider | 465 | per provider | per provider |
Use port 465, which is implicit TLS. This is not a preference. On port 587 the node’s function runtime does not complete the STARTTLS upgrade. The send hangs, times out and fails, so invitations, notifications and verification codes do not go out.
Two checks pass anyway, which is what makes this hard to spot. The install check uses a different mail client and connects on 587 without trouble. Sign-in links and password resets keep arriving, because the sign-in service is a separate program with a mail client of its own — so sending yourself a sign-in link, the test the checklist asks for, succeeds on a node whose application email is broken.
Port 25 egress is blocked on most hosting providers.
The from address must be a verified domain. The node sends as
noreply@<home_server> by default, and providers reject any send from a domain
they have not verified for SPF and DKIM. This is not your admin_email — that
is your own login and contact address, and its domain is not verified. If your
node is a subdomain on an account where only the parent domain is verified, set
smtp.sender_email to the verified parent. The test email at install catches
this before you go live.
Without email, the node is nearly inert. Users join through email-bound
invitation links, so a node that cannot send mail cannot onboard anyone. The
installer also forces every federation surface off when no transport is
configured, and tells you so. The only node that legitimately runs without email
is one set to registration_mode: closed, which accepts no new users at all.
Signups are never auto-confirmed on a node.
The Software
Section titled “The Software”tc-operator runs from a complete source tree. You receive the operator
distribution archive from Trusted Codes — a tarball containing the full
buildable tree, with no version-control history and no internal documents.
If you were given an enrolment token, you do not fetch the archive by hand at all; the one-line installer does it for you and verifies the download against the published, signed release manifest. See Installing a node.
What You Do Not Configure
Section titled “What You Do Not Configure”The federation trust root — the central registry URL and its root public key — is baked into the installer. It is one value for the whole mesh, identical on every node, and you neither provide nor change it.
Every per-node secret (the JWT secret, the anon and service keys, the Postgres
password, the encryption key, the federation signing key) is generated for you
into /etc/trusted-codes/secrets.env, mode 0600. You never copy a secret by
hand. The one exception is your SMTP password, which you put in operator.yaml.
A Rehearsal, If You Want One
Section titled “A Rehearsal, If You Want One”On a Mac or Linux workstation with Docker, you can run the whole container flow without any host provisioning or TLS:
scripts/tc-operator/tc-operator install --local --config operator.yaml--local boots the node on an isolated loopback project and skips apt, the
firewall, the swapfile and TLS entirely. Tear it down with
tc-operator uninstall --local --config operator.yaml --purge.