Install prerequisites

Size the Ubuntu VM, static IPv4, NTP, ports, entitlement. Do this before lattice-install.

This page is before lattice-install. When the host is ready, run the installer on the node (no arguments for the wizard). Topology and HA details: ha. Entitlement: license.

If you administer Windows Server / AD and not Linux: start with windows-admin (SSH vs RDP, WinSCP, sudo, what not to paste into cmd.exe). This page still has the commands; that page teaches why they look like that. Larger shops with Linux teams can skip it.

Ubuntu networking, time, and SSH change between LTS releases. For the latest installer checkboxes and YAML keys, use Canonical’s docs; this page is the Lattice-specific checklist.

Just show me the steps — commands at the bottom, without the sizing lecture.

TopicOfficial docs
Ubuntu Server networking / netplanConfiguring networks · Netplan YAML · netplan try
ChronySynchronize time using chrony
OpenSSH serverOpenSSH server (Ubuntu)

What you are installing

One tarball, community and paid. The signed entitlement is the SKU.

CommunityPaid
Managed IPs1000Starter 5k · Professional 10k · Team 25k · Org 50k · Scale 100k · or Enterprise
TopologySingle Ubuntu nodeSame single node, or three-node HA
Installerlattice-installSame command; the wizard asks

Managed IPs = addresses that are leased, reserved, quarantined, or assigned. Prefix size and free pool do not count. A /16 with 200 live addresses is 200, not 65,536.

Community has no HA: one Postgres, no VIP, no Patroni. Paid may run HA; it is not required.

Lattice Fleet (many clusters, one console) is a different tarball (fleet-install). It does not serve DHCP: fleet-deploy.

1. Pick a topology

Single node (community, or paid that does not need failover)

  • One Ubuntu VM
  • Relays and browsers point at that VM’s address (HTTPS :443 for community UI)
  • Fine for a branch, a proof of concept, or a site that can take a maintenance window

Three-node HA (paid)

The three VMs sit in the same site (low RTT, same L2). That is only for Patroni, etcd, and the keepalived VIP — one unused IPv4 on that subnet. It is not a limit on client VLANs.

  • Relays and browsers point at the VIP (HTTPS :443, DHCP :67, DNS :53)
  • Client subnets can be any VLAN, building, or DC. Relays unicast to the VIP (or to a dhcp-only node at that site)
  • Two nodes cannot form a safe quorum; do not try “HA on two VMs”

Extra DHCP or DNS at another subnet or DC (paid, after the control plane exists)

  • Another Ubuntu VM (lattice-install --mode dhcp-only or dns-only)
  • Relays at that site point at this VM, not the VIP
  • Needs Postgres RTT ≲ ~50 ms to the control-plane VIP. Above ~100 ms, use a second cluster
  • Fresh join token from the primary after each join (lattice-install --mode join-token; tokens are single-use)

Two data centers (active / passive)

Do not leave the three HA VMs split across DCs (2+1). Live cluster in the primary DC; dhcp-only in the other if RTT allows; or restore a backup onto a new cluster in the DR DC and cut relays. A planned vMotion / live migrate of all three to DC-B is fine when the destination keeps the same L2 and IPs (move one VM at a time, replicas first). That is not unplanned DR. Details: ha.

If you are unsure: start with one node. You can rebuild as HA later with the same binaries and the same entitlement.

2. Size the VM(s)

Per control-plane node. For HA, each of the three VMs needs this — Postgres data is on every node.

Licensed managed IPsCPU (min → recommended)RAMFree disk on /var/lib
≤ 1,000 (community)2 → 24 → 8 GB20 → 40 GB
≤ 5,0002 → 48 → 16 GB40 → 80 GB
≤ 25,0004 → 816 → 32 GB80 → 200 GB
≤ 100,0008 → 1632 → 64 GB200 → 500 GB
> 100,00016 → 3264 → 128 GB500 GB → 1 TB

DHCP-only / DNS-only extra nodes: 1 → 2 CPU, 2 → 4 GB RAM, 10 → 20 GB disk.

Disk growth is Postgres in Docker volumes, almost always under /var/lib/docker on /var/lib. Binaries in /opt/lattice are small. Prefer a single disk large enough for /var/lib; do not put /var on a tiny root filesystem.

The installer refuses a host below minimum unless you pass --skip-specs (not for production).

x86_64 or arm64.

3. Operating system

Supported: Ubuntu Server 22.04 LTS or 24.04 LTS.

Best-effort: Ubuntu derivatives on the same LTS bases (Pop!_OS, Linux Mint, elementary, …) where ID_LIKE includes ubuntu. The installer allows these and prints a warning; we test and support Ubuntu Server only.

Bring-your-own Docker: other Linux distros when Docker Engine and the Compose plugin are already installed (docker compose version works). The installer proceeds with a warning and does not run apt package installs. Firewall automation may be skipped or manual.

Not supported: other distros without Docker Compose, Ubuntu 20.04, and desktop-only images without the Server stack.

Use a fresh VM. Do not share the box with another DHCP server, BIND on :53, or a second Postgres on :5432.

You need:

  • Root or a sudo user
  • Outbound HTTPS the first time (Docker packages and images), unless you bring an air-gap image bundle
  • python3 (Ubuntu Server includes it)

The installer installs Docker Engine + Compose plugin if they are missing. You do not need to install Docker yourself.

Check

. /etc/os-release
echo "$ID $VERSION_ID"          # ubuntu 22.04 or 24.04 (derivatives: pop, linuxmint, …)
whoami                          # root, or use sudo -i
python3 --version
nproc
free -h
df -h / /opt /var/lib

Create the VM (typical)

This is a Linux guest, not a Windows Server with the DHCP role and not WSL.

  1. Hypervisor: one NIC, virtio/synthetic, enough vCPU/RAM/disk from the table. Hyper-V: Generation 2 is fine; Ubuntu Server ISO; enable OpenSSH in the Ubuntu installer. If the ISO will not boot, turn off Secure Boot or use Ubuntu’s UEFI image.
  2. Install Ubuntu Server 22.04 or 24.04 (or an Ubuntu-derivative LTS you accept as best-effort). Enable OpenSSH when the installer asks — that is how you reach the box from your PC (there is no RDP desktop).
  3. After first boot, from SSH or the hypervisor console:
sudo apt update && sudo apt upgrade -y

Reboot if the kernel updated (sudo reboot). Then set a static IPv4 (§4) before you rely on a DHCP reservation that might vanish.

  1. For HA, clone or repeat until you have three VMs. Give them distinct hostnames (lattice-a, lattice-b, lattice-c).

On-prem VMware / Proxmox / Hyper-V: put all three control-plane HA nodes on the same port group / virtual switch. The VIP is just another IPv4 on that network — do not assign it inside Ubuntu. Client VLANs do not need to share that switch — point relays at the VIP (or at a dhcp-only VM in that site). relays.

Public cloud: keepalived needs a real L2 (or equivalent) and a free address the platform will accept. Many VPCs do not. Prefer single-node, or BYO Postgres plus a cloud load balancer, unless you already know how to run VRRP in that VPC.

4. Give the node a stable IPv4

This is the same job as setting a static address in ncpa.cpl on Windows. Lattice detects the default-route address, netmask, and gateway. It does not write a static address onto the NIC (that can drop your SSH session).

Do this in the OS before lattice-install.

Netplan (Ubuntu Server)

Netplan is Ubuntu’s NIC config: a YAML file under /etc/netplan/. You edit it with nano (windows-admin §6), then apply. There is no GUI.

ip -4 route show default
ip -4 addr show
ls /etc/netplan

Edit the netplan file (name varies). Example: this node is 10.0.0.11/24, gateway 10.0.0.1, DNS 10.0.0.1.

network:
  version: 2
  ethernets:
    eth0:                         # use the name ip -br link showed
      dhcp4: false
      addresses: [10.0.0.11/24]
      routes:
        - to: default
          via: 10.0.0.1
      nameservers:
        addresses: [10.0.0.1]
sudo netplan try
ip -4 addr
ping -c 2 10.0.0.1

netplan try applies the YAML and waits for you to press Enter. If SSH drops, it reverts after about two minutes (netplan try). sudo netplan apply is permanent with no rollback — use it from the hypervisor console, or after try has already proved the address.

If you are on SSH, apply from the hypervisor console the first time, or add the new address before removing DHCP so you are not cut off.

HA VIP is a different address, for example 10.0.0.10. It must be:

  • In the same subnet as the three node IPs
  • Not used by any host
  • Not configured in netplan on any of the three nodes — keepalived owns it

Reserve it in the hypervisor / IPAM so nobody else takes it.

5. Clock sync

Lease times are wall-clock. Kerberos (AD DDNS) dies if this VM and the DCs differ by ~5 minutes. This is the same discipline as domain time / w32time — the VM must actually sync, not just “have NTP in the guest tools.”

On Ubuntu 22.04 / 24.04, systemd-timesyncd is often already running. Canonical’s current how-to is Synchronize time using chrony (chrony is the default on newer Ubuntu). Either client is fine if timedatectl shows NTP synchronized: yes. Chrony is what we recommend when you need to install something. UTC on the VM is fine (Windows clients can stay on local time).

sudo apt-get update
sudo apt-get install -y chrony
sudo systemctl enable --now chrony
chronyc tracking          # System time offset should be well under 500 ms
timedatectl               # NTP synchronized: yes

On all three HA nodes, use the same NTP source (or the site’s NTP).

6. Entitlement file

Default path: /etc/lattice/entitlement.json (mode 0640).

You areWhat to do
CommunityNothing. Missing file is 1000 IPs, single node.
PaidDownload lattice.entitlement.json from the customer portal.

The wizard can paste the JSON, or you copy the file. From a Windows PC, copy the file to /tmp on the VM with WinSCP (windows-admin §4), then SSH:

sudo mkdir -p /etc/lattice
sudo mv /tmp/lattice.entitlement.json /etc/lattice/entitlement.json
sudo chmod 640 /etc/lattice/entitlement.json

From a Linux/macOS laptop (or PowerShell with OpenSSH):

# after the VM has a reachable IP
ssh [email protected] 'sudo mkdir -p /etc/lattice && sudo chmod 755 /etc/lattice'
scp lattice.entitlement.json [email protected]:/tmp/lattice.entitlement.json
ssh [email protected] 'sudo mv /tmp/lattice.entitlement.json /etc/lattice/entitlement.json && sudo chmod 640 /etc/lattice/entitlement.json'

Do not edit max_managed_ips in the file. That breaks the signature and falls back to community.

7. Ports

Containers do not each need a public port. Clients talk to the VIP (HA) or to 443/67/53 (single node). HAProxy/Caddy and keepalived on the host fan that out to backends on the node IPs.

If you let the installer apply the firewall profile, skip this section.

Single node (community / paid Compose)

PortWhy
22/tcpSSH (use your real SSH port if it is not 22)
80/tcp/readyz and HTTP→HTTPS
443/tcpUI and API
67/udpDHCP (relays)
53/tcp and 53/udpDNS if you use lattice-dns

Postgres is published on 127.0.0.1:5433 only. Worker metrics stay on loopback.

HA — public (clients, relays, browsers)

PortWhy
22/tcpSSH
80/tcp/readyz and HTTP→HTTPS
443/tcpUI and API (join bundle too)
67/udpDHCP VIP (keepalived IPVS)
53/tcp + 53/udpDNS VIP

HA — three node IPs only (not the internet)

PortWhy
2379, 2380/tcpetcd
8008/tcpPatroni REST (HAProxy /primary check)
15432/tcpPostgres replication + HAProxy
8080/tcpAPI backend (HAProxy)
8082/tcpdhcpd /readyz (IPVS health)
6767/udp, 5353/tcp+udpDHCP/DNS backends
VRRP (proto 112)keepalived

HA — private (RFC1918 / Docker), not the internet

PortWhy
5432/tcpHAProxy Postgres VIP. App containers (host.docker.internal) and dhcp-only/dns-only nodes.

Stay on loopback — never open

PortWhy
9999/tcpHAProxy admin socket
8404/tcpkeepalived health of HAProxy
8081/tcpworker metrics

Health checks are HTTP /readyz, never a UDP probe on 67.

Adding a dhcp-only / dns-only node does not change UFW on the three control-plane nodes. Join uses public 443. After that the leaf only needs outbound 5432 to the VIP. The installer already allows 5432 from RFC1918 (same site, VPN, typical WAN). If the leaf’s source IP as seen at the VIP is public, allow it on all three control nodes (the VIP moves):

ufw allow from <leaf-ip> to any port 5432 proto tcp

Do not manage host firewall rules from the Lattice UI. A stolen admin token must not be able to open ports. Host UFW stays an installer / SSH job.

8. Optional: DNS name for the UI

HA terminates HTTPS on the VIP with a cluster-minted certificate. If operators will type https://ddi.example.com, create an A record to the VIP and pass that name in the wizard (TLS SAN). You can replace /etc/lattice/tls/haproxy.pem with a real certificate later.

Community single-node is HTTPS on :443 (self-signed cluster cert, same idea as HA). HTTP /readyz and /healthz stay on :80; everything else redirects. API :8080 is loopback-only.

After install, open https://<this-vm> from your laptop (not http://127.0.0.1:8080). The first admin token is printed once and written to /etc/lattice/bootstrap.token. Closing the browser tab forgets it; paste that file again.

First lease: Community dhcpd is Docker on UDP 67. A laptop on the same VLAN sending a broadcast Discover often never reaches the container — that is not a failed install. Point an ip helper-address at this VM (relays), or run lattice-dhcptest -server 127.0.0.1:67 -giaddr <gateway> on the node (windows-admin). Settings → Trusted relays: empty drops relayed packets (direct clients still served). Add the real relay IPs; lattice-dhcptest on the node still works. If lattice-dns did not start, port 53 is probably already in use — UI and DHCP are still up. Console: first-login.

9. Get the package onto the VM

Download the Linux tarball for the VM’s architecture (amd64 is typical on Hyper-V/VMware x86; arm64 only if the guest is ARM). This is not an .msi. From your Windows PC, copy it with WinSCP to /tmp on the VM (windows-admin §4).

Then on the VM (SSH), extract as root. tar is unzip for this archive; -C /opt means extract into /opt:

tar -tzf /tmp/lattice-*-linux-amd64.tar.gz | head
sudo tar -C /opt -xzf /tmp/lattice-*-linux-amd64.tar.gz
# directory name includes the version, e.g. /opt/lattice-0.x.y-linux-amd64
cd /opt/lattice-*-linux-amd64

Air-gap: on a connected host that already has images, lattice-install --mode save-bundle --out lattice-images.tar, copy that tar with the release, then --bundle lattice-images.tar on the dark site.

Just the steps

Run on each node. Replace IPs. Netplan YAML keys: Canonical.

. /etc/os-release; echo "$ID $VERSION_ID"
sudo apt update && sudo apt upgrade -y
ip -4 route show default
ip -4 addr show
ls /etc/netplan
sudo nano /etc/netplan/00-installer-config.yaml   # static IPv4; not the HA VIP
sudo netplan try
ping -c 2 10.0.0.1
sudo apt-get install -y chrony
sudo systemctl enable --now chrony
timedatectl | grep -i ntp
nproc; free -h; df -h /var/lib

Paid entitlement (optional): copy lattice.entitlement.json to /tmp, then:

sudo mkdir -p /etc/lattice
sudo mv /tmp/lattice.entitlement.json /etc/lattice/entitlement.json
sudo chmod 640 /etc/lattice/entitlement.json

Tarball already in /tmp:

sudo tar -C /opt -xzf /tmp/lattice-*-linux-amd64.tar.gz
cd /opt/lattice-*-linux-amd64
sudo ./scripts/lattice-install

The wizard asks for license, specs, topology, and firewall. Type b to go back. Nothing is installed until you confirm. Flags: installer --help and ha.

You are ready when Ubuntu is 22.04/24.04, sizing matches the table, the NIC is a stable IPv4, NTP is synchronized, and (HA) three VMs share one L2 with one unused VIP not in netplan.