Skip to content

Public Ubuntu hosting

This guide is for the owner of an ermahgerd installation. Managed-service customers start with Managed ermahgerd instead.

Prepare your installation

Use Ubuntu 24.04 or 26.x and provision an SSH key for the operator account. The compact topology runs all capabilities on one host. The reference host has 4 vCPUs and 16 GiB RAM; choose disk capacity for both tenant data and telemetry.

The checked-in inventory describes the project’s existing Latitude host and ermahgerd.io domain. For your own server, adapt a separate inventory and its host/group variables before provisioning. Set your SSH address, user, and key; public DNS domain and origins; certificate contact and issuer; and fresh secret inventory. Merely overriding the SSH address does not change the domain or bootstrap account. Do not run the checked-in Latitude targets against somebody else’s installation.

See Deployment profiles for placement and Certificates and domains for the DNS records and HTTP-01 issuance flow. Public HTTP and HTTPS must reach the ingress host; backing APIs and administrator access remain private.

Reference Latitude workflow

The checked-in latitude inventory applies the compact topology to an ordinary Ubuntu 24.04 or 26.x server. It uses the same roles as Lima; only inventory, public origins, firewall exposure, and certificate policy differ. Set LATITUDE_HOST, LATITUDE_SSH_USER, or LATITUDE_SSH_KEY to override the reference host, user, and key.

Once the apex, portal, *.workers, and *.r2 A records resolve to the host, bootstrap the complete installation with:

make latitude-up

That target generates encrypted, untracked per-installation secrets, converges Ansible, deploys the production example set through Wrangler over an SSH tunnel, obtains trusted certificates with Certbot HTTP-01, reconverges secure origins and cookies, and verifies the applications over HTTPS. The public profile seeds the photo publishing workflow and Nimbus documentation site; the local-only sum, order pipeline, and Durable Object counter remain available in the disposable Lima profiles. Re-running the target is safe.

Use focused lifecycle targets afterward:

make latitude-site         # converge services without deploying applications
make latitude-harden       # apply SSH, firewall, kernel, and fail2ban policy
make latitude-deploy       # redeploy curated applications through Wrangler
make latitude-check        # verify existing applications over public HTTPS
make latitude-waf-check    # verify Observe publication, then restore the gallery to Off
make latitude-status       # report failed systemd units
make latitude-ssh          # open an operator shell
make latitude-credentials  # display the locally held bootstrap identity
make latitude-vault-edit   # edit the encrypted installation secret inventory

The generated secret inventory lives in the Ansible Vault at .local/latitude/secrets.yml, with owner-only permissions, and is deliberately excluded from Git. On macOS its randomly generated Vault password is held in the login Keychain as service io.ermahgerd.ansible-vault, account latitude. On other controllers, set LATITUDE_VAULT_PASSWORD_FILE to an owner-readable password-file path before the first command. make latitude-credentials decrypts and displays the initial owner identity only on demand; it is not kept in a second plaintext file.

Back up both the encrypted Vault and its password in a real secret manager before treating the server as durable infrastructure. Losing either and generating replacements does not rotate an existing installation safely. An existing plaintext Latitude secret inventory is migrated in place on the next Latitude command without rotating any platform credentials.

The public listener serves the landing page, tenant console, status page, Workers, Access, and tenant R2 endpoints. The administrator portal is intentionally absent from public ingress. Give it a private listener reached through VPN or another operator-only network rather than publishing it beside tenant traffic.

The reference Latitude profile also runs the bounded ingress inspector. Worker policies remain Off until an organization selects Observe or Enforce under the Worker’s Security tab. Begin in Observe, exercise legitimate traffic, and add narrow rule exceptions before enforcing. See Worker ingress protection.

The host hardening role denies unsolicited inbound and routed traffic by default, exposes only SSH, HTTP, HTTPS, and the WireGuard underlay, and admits platform service ports only on wg0. SSH accepts public-key authentication for the declared operator account, permits local forwarding for the Wrangler SSH tunnel, and disables root, password, agent, remote, X11, and tunnel forwarding. UFW rate-limits new SSH connections. Fail2ban watches the systemd SSH journal in aggressive mode, bans five failures within ten minutes for an hour, and increases repeat-offender bans up to one week. Loopback and the platform WireGuard subnet are excluded from bans.

Handoff to application users

Give customers their console origin, organization ID, and a way to reach the private deployment API with their own token. The public tenant console is not the Wrangler API. Connect Wrangler describes the application-side setup. Platform operations covers ongoing maintenance, customer support, and data ownership.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close