---
title: "Public Ubuntu hosting"
---

> Documentation Index
> Fetch the complete documentation index at: https://ermahgerd-docs.t-bd7662a5eeb4.workers.ermahgerd.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Public Ubuntu hosting

This guide is for the owner of an ermahgerd installation. Managed-service
customers start with [Managed ermahgerd](/managed/) 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](/self-hosted/deployment-profiles/) for placement and
[Certificates and domains](/operations/certificates/#use-the-public-single-node-path)
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:

```sh
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:

```sh
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](/build/worker-security/).

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](/build/connect-wrangler/) describes the
application-side setup. [Platform operations](/operations/) covers ongoing
maintenance, customer support, and data ownership.

Source: https://ermahgerd-docs.t-bd7662a5eeb4.workers.ermahgerd.io/self-hosted/public-hosting/index.mdx
