Skip to content
Nautilo Documentation
Deploy / Build / AdministerDeploy

Deploy to a Linux server

Review the in-progress release-candidate SSH + Compose lifecycle for a Docker-capable host.

This is the persistent self-hosted path: one SSH-reachable Linux machine, one Docker Compose lifecycle, and one Server owned by your circle. A DigitalOcean Droplet is one example. The provider is not the deployment driver.

Prepare the host

The target needs a running Docker Engine and a pre-authorized, noninteractive SSH identity whose account can use Docker. Have the host administrator install that identity's public key first. Obtain the expected host-key fingerprint through a trusted channel; do not trust an unverified ssh-keyscan result.

export NAUTILO_SSH_IDENTITY_FILE=/path/to/operator-authorized-key
export NAUTILO_SSH_KNOWN_HOSTS_FILE="$HOME/.ssh/nautilo_known_hosts"

# Inspect this fingerprint, then compare it with the value received through a
# trusted channel. Do not run the next block until they match.
ssh-keyscan -t ed25519 -H nautilo-host.example.org > /tmp/nautilo-host.known_hosts
ssh-keygen -lf /tmp/nautilo-host.known_hosts

If the fingerprint does not match, remove the temporary file and stop. Do not replace an existing known-hosts entry until its change has been verified. Only after a match, install the verified entry and test the pre-authorized identity:

install -m 600 /tmp/nautilo-host.known_hosts "$NAUTILO_SSH_KNOWN_HOSTS_FILE"
rm /tmp/nautilo-host.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-host.example.org 'docker info'

Create the remote Compose profile

nautilo profile add circle-server \
  --transport=remote \
  --lifecycle=compose \
  --instance-id=circle \
  --ssh-host=nautilo-host.example.org \
  --ssh-user=operator \
  --ssh-identity-file="$NAUTILO_SSH_IDENTITY_FILE" \
  --ssh-known-hosts-file="$NAUTILO_SSH_KNOWN_HOSTS_FILE" \
  --remote-path=/opt/nautilo \
  --domain=circle.example.org \
  --base-url=https://circle.example.org \
  --https=letsencrypt \
  [email protected] \
  --tag=<immutable-tag> \
  --yes

DNS for circle.example.org must already resolve to the host. Nautilo checks DNS but does not change it. If a non-root SSH account cannot write /opt/nautilo, choose a path it owns.

Deploy and prove ownership

nautilo deploy --from-registry --tag <immutable-tag>
nautilo status

Remote lifecycle authority is SSH plus Docker privilege. Nautilo application roles do not revoke that infrastructure access. Rotate or remove SSH authority at the host/provider layer.

Before calling the Server ready, prove the expected instance identity, HTTPS route, owner sign-in, SPA delivery, and a real model response. Day-two changes use nautilo upgrade --image <immutable-reference> so backup, runtime acceptance, and automatic rollback surround replacement. Do not use deploy as the ordinary upgrade command.