Overalls.

An AI-first developer platform that you own.

Guide Self-host
Design Architecture
Source GitHub · MIT Appearance

Set up DNS

Overalls uses two kinds of DNS. Your domain's apex stays with your normal DNS provider and points at your Marshall hosts. A subzone, apps.<your-domain>, is delegated to Audi, which answers for every machine's hostname itself. That's what lets a machine move between hosts without you touching DNS.

You create
One apex A record per Marshall host, two to eight ns A records, and one NS delegation
Audi serves
<machine>.apps.<your-domain>, and the wildcard certificate challenge
Ports
UDP and TCP 53 on each Audi DNS host; 22, 80 and 443 on each Audi gateway
┌─ your DNS provider · example.com ──────────────┐
│ example.com        A   one per Marshall host   │
│ ns1.example.com    A   Audi DNS host 1         │
│ ns2.example.com    A   Audi DNS host 2         │
│ ns3, ns4 …         A   optional, up to eight   │
│ apps.example.com   NS  ns1, ns2 (, ns3, ns4)   │
└───────────────────────┬────────────────────────┘
                        │  delegated
                        ▼
┌─ Audi DNS · authoritative for apps.example.com ─────────────┐
│ <machine>.apps.example.com       A    gateway on its host   │
│                                       TTL up to 20 s        │
│ _acme-challenge.apps.example.com TXT  wildcard DNS-01       │
└─────────────────────────────────────────────────────────────┘
The apex stays with your provider; Audi answers for everything under apps.

1. Choose where Audi DNS runs

Audi doesn't need hosts of its own. Its DNS role can run on your Marshall control-plane hosts, and on Lilly hosts too. We recommend running it in several places: the module needs two to eight nameservers, and spreading them across hosts keeps DNS answering when one goes down. Each one needs a stable public IPv4 address that's reachable on UDP and TCP port 53. Every Lilly host also runs an Audi gateway, which carries SSH and web traffic to its own machines, but gateways don't need DNS records of their own.

2. Create the records at your DNS provider

NameTypeValue
<your-domain>AOne record per Marshall host, each with that host's public address. Browsers, sign-in links, HTTP-01 certificates and Porsche all use this name.
ns1.<your-domain>AThe first Audi DNS host
ns2.<your-domain>AThe second Audi DNS host
ns3, ns4 …AOptional extra Audi DNS hosts, up to eight in total
apps.<your-domain>NSns1.<your-domain>, ns2.<your-domain>, and any others

Porsche, the SSH gateway, runs on the Marshall hosts and answers on port 22 of these same apex addresses, so ssh <your-domain> reaches it with no extra records. Keep the apex records at your provider. Audi serves only the delegated subzone and never answers for the apex. With several Marshall hosts behind one name, a certificate challenge can arrive at any of them, so list the other frontends as services.marshallProxy.acme.http01.peers on each one (see Deploy the control plane).

3. Enable Audi DNS

services.audiDns = {
  enable = true;
  zone = "apps.example.com";
  nameservers = [ "ns1.example.com" "ns2.example.com" ];
  mailbox = "hostmaster.example.com";
  controlPlane = "https://example.com";
  credentialFile = "/run/kittens-secrets/audi-dns/token";
  openFirewall = true;
};

Every Audi DNS host lists the same zone and the same set of nameservers. mailbox is the SOA contact address, written in DNS form. The module refuses fewer than two or more than eight nameservers.

4. Enroll Audi with Marshall

Each Audi DNS server and each gateway authenticates to Marshall with its own token. Issue the tokens with the operator CLI and write them to private files outside your checkout:

bin/marshall eval 'Marshall.Operations.CLI.main()' audi-dns-rotate audi-host1-dns /private/host1-dns.token
bin/marshall eval 'Marshall.Operations.CLI.main()' audi-gateway-rotate audi-host1 HOST_UUID ADDRESS /private/host1.token

Check each file with audi-dns-verify or audi-gateway-verify. Then encrypt the tokens into each host's secret documents with nix run .#secrets -- encrypt and run nix run .#secrets -- check. HOST_UUID is the enrolled Lilly host's ID, and ADDRESS is the gateway's public address.

5. Wildcard certificate

Marshall requests one Let's Encrypt certificate for *.apps.<your-domain> using DNS-01. Every Audi DNS replica publishes the challenge record, so you don't need DNS provider credentials for it, and Marshall installs the certificate on every gateway. Machine hostnames get HTTPS without any per-machine records.

6. Validate

dig @ns1.example.com apps.example.com SOA
dig @ns2.example.com apps.example.com SOA
dig +trace apps.example.com NS

Check that UDP and TCP 53 reach every Audi DNS host, and that 22, 80 and 443 reach every gateway, from a network outside your fleet. Then stop one audi-dns at a time and confirm the others keep answering.

Full reference: docs/audi.md

Full reference: docs/fleet-network.md