Skip to content
Nautilo Documentation
Administrator guideDeploy Nautilo

Run Nautilo on one trusted LAN

Deploy through SSH and connect a Desktop client over bounded, unencrypted LAN HTTP.

This is a bounded path for a Nautilo Desktop client and a Linux Docker host on the same trusted network. The Linux host may be a small local server or another machine on that LAN. The operator manages it over SSH; the client connects to the Server and identity endpoints over plain HTTP. Nautilo does not currently provide a supported HTTPS mode for this LAN route.

What this topology supports

Use a remote Compose profile even when the Linux host is beside you. That profile advertises the SSH host name in the generated Server and Logto URLs. A local profile advertises localhost; sharing its ports or replacing that word later does not make its identity configuration valid for another device.

This guide supports:

  • one stable LAN host name that every participating computer resolves to the same private host;
  • remote Compose lifecycle management over a pre-authorized SSH key;
  • protected config-mode first-owner creation through the trusted SSH loopback; and
  • a Nautilo Desktop client configured with the exact HTTP Server URL from the deployment receipt.

It does not support browser claim, Mobile Web, production iOS or Android clients, a browser-based Workbench on the LAN origin, or Internet exposure. It also does not turn a macOS local profile into a shared Server by opening its ports: that profile's identity endpoints remain bound to localhost.

Prepare the LAN and host

  1. Give the host a stable address through DHCP reservation or static network configuration. Create a LAN DNS name such as nautilo-lan.example and verify that the operator computer and Desktop client resolve it to the same host. Do not configure router port forwarding.
  2. Install Docker Engine and the Docker Compose plugin on the Linux host. Give a dedicated operator account permission to use Docker and write the chosen deployment directory. Have the host administrator create the path used below with sudo install -d -o operator -g operator -m 700 /srv/nautilo.
  3. Pre-authorize a dedicated SSH public key for that account. Obtain the server's SSH host-key fingerprint through a trusted channel before saving it; an unverified ssh-keyscan result is not proof of identity.
  4. Use a signed Nautilo CLI release whose nautilo deploy --help lists --owner-mode, --owner-config, and --owner-result. If those options are absent, protected LAN first-owner creation is unavailable in that release. Do not substitute browser claim.

Record and install the verified SSH host key:

export NAUTILO_LAN_HOST='nautilo-lan.example'
export NAUTILO_SSH_IDENTITY_FILE="$HOME/.ssh/nautilo_lan_operator"
export NAUTILO_SSH_KNOWN_HOSTS_FILE="$HOME/.ssh/nautilo_lan_known_hosts"

ssh-keyscan -t ed25519 -H "$NAUTILO_LAN_HOST" > /tmp/nautilo-lan.known-hosts
ssh-keygen -lf /tmp/nautilo-lan.known-hosts

Compare that fingerprint with the separately obtained value. Stop on any mismatch. Only after a match, install it and prove Docker access:

install -m 600 /tmp/nautilo-lan.known-hosts "$NAUTILO_SSH_KNOWN_HOSTS_FILE"
rm /tmp/nautilo-lan.known-hosts

ssh -o BatchMode=yes -o IdentitiesOnly=yes -l operator \
  -i "$NAUTILO_SSH_IDENTITY_FILE" \
  -o StrictHostKeyChecking=yes \
  -o UserKnownHostsFile="$NAUTILO_SSH_KNOWN_HOSTS_FILE" \
  "$NAUTILO_LAN_HOST" \
  'docker info && docker compose version && test -w /srv/nautilo'

Create a LAN profile

nautilo profile add lan-server \
  --transport=remote \
  --lifecycle=compose \
  --instance-id=lan \
  --ssh-host="$NAUTILO_LAN_HOST" \
  --ssh-user=operator \
  --ssh-identity-file="$NAUTILO_SSH_IDENTITY_FILE" \
  --ssh-known-hosts-file="$NAUTILO_SSH_KNOWN_HOSTS_FILE" \
  --remote-path=/srv/nautilo \
  --https=off \
  --yes

Do not add a public domain, https=letsencrypt, or a hand-written base URL to this LAN profile. Nautilo derives the HTTP Server and Logto endpoints from the SSH host and the allocated Compose ports.

Contain the published ports before deployment

Docker-published ports can be reachable beyond host firewall rules, depending on the Docker and firewall configuration. Treat the router, VLAN, or provider firewall as the primary boundary and account for Docker's forwarding rules on the host.

  • Permit SSH only from administrator devices.
  • Begin with every published application port denied at the upstream boundary.
  • After deployment reports owner-bound, permit only the exact Server and Logto ports in its receipt, and only from the trusted LAN client range.
  • Deny those ports from guest networks and the Internet.
  • Do not expose database or Logto administrator ports.
  • Do not create public DNS records or router port-forwarding rules for this host.

The allocated ports are deployment output; do not copy port numbers from an example or guess them. Keep the upstream policy default-deny while the CLI deploys and creates the owner through SSH loopback. Add the exact LAN-only allow rules from the successful receipt before connecting Desktop.

Create the first owner without a browser claim

The browser claim endpoint rejects non-loopback HTTP. Prepare the protected Local / Docker Compose TOML on the operator computer, then use config mode: fill in the local setup file.

Choose a new result filename. It receives one-time recovery codes and must remain outside Server storage and backups.

nautilo deploy \
  --profile lan-server \
  --owner-mode config \
  --owner-config "$HOME/.config/nautilo/deploy.toml" \
  --owner-result "$HOME/.config/nautilo/lan-owner-result.json" \
  --finish guide \
  --json --no-open-browser

Require owner-bound, save the recovery codes and permanent owner credentials in a password manager, and retain the exact deployment receipt. Continue in Desktop only after that result; this command deliberately does not open a Web page. Apply the two receipt-derived LAN port rules described above before connecting it. Do not open /claim from another computer, change to claim mode after interruption, or recreate an existing result file.

Connect a Desktop client

On a second computer on the same trusted LAN:

  1. Confirm that NAUTILO_LAN_HOST resolves to the prepared host.
  2. Copy the exact Server URL from the deployment receipt. It begins with http:// and uses the LAN host name plus its allocated port.
  3. In Nautilo Desktop, add that explicit Server URL. Review the plaintext HTTP warning and confirm that the displayed target is the host you prepared.
  4. Sign in with the existing owner account created by config mode. Do not look for a claim page.
  5. Confirm the expected Server identity and complete one useful model-backed action before inviting anyone else.

Diagnose without changing the topology

Run the DNS check for the client operating system. On macOS:

dscacheutil -q host -a name nautilo-lan.example

On Linux:

getent hosts nautilo-lan.example

Then test the exact Server URL from the same computer:

curl --fail --silent --show-error 'http://nautilo-lan.example:<server-port>/health'

Replace <server-port> with the receipt value. The health response's logtoEndpoint must use the same resolvable LAN host, not localhost. Then check the managed instance and SSH path from the operator computer:

nautilo status --profile lan-server
ssh -o BatchMode=yes -l operator \
  -i "$NAUTILO_SSH_IDENTITY_FILE" \
  -o StrictHostKeyChecking=yes \
  -o UserKnownHostsFile="$NAUTILO_SSH_KNOWN_HOSTS_FILE" \
  "$NAUTILO_LAN_HOST" 'docker info'

If DNS differs between devices, the endpoint contains localhost, client isolation blocks peers, or the Logto port is not reachable, stop and correct that boundary. Do not disable host-key checking, browser security controls, mobile cleartext policy, or claim-origin checks.

For Web, Mobile, public access, or transport confidentiality, choose an HTTPS deployment: choose a deployment.