Skip to content
Nautilo Documentation
Administrator guideAdvanced operations

Railway upgrade and recovery

Supply protected recovery custody and run or resume Nautilo's integrated Railway maintenance transaction.

Railway recovery is part of one protected upgrade transaction. The public CLI does not provide an independent host backup, host restore, or command that restores an arbitrary old Server into a fresh Railway project.

When an authorized operator runs host upgrade, Nautilo quiesces the Server, creates one coordinated set of three Railway-native volume backups, exports an encrypted portable copy to operator-controlled S3-compatible storage, applies and verifies the selected signed release, and records durable checkpoints. If the in-place candidate cannot be accepted, the same transaction can restore the portable copy into a replacement project, verify it, and promote it. host resume continues that transaction after interruption.

Required authority

You need all of the following:

  • the saved Nautilo launch receipt on the administrator workstation;
  • Railway OAuth access to the paying workspace and exact project;
  • a private S3-compatible bucket outside the Railway project;
  • credentials scoped to read, write, list, and delete only the chosen recovery prefix; and
  • one independently stored 32-byte encryption key.

Keep the non-secret launch ID in an operations record. Do not record Railway OAuth tokens, storage credentials, the encryption key, provider keys, or database URLs there.

Create the protected recovery file

Create an owner-only directory and edit one new file. The CLI accepts no ambient default: every upgrade and relevant resume must name its absolute path.

install -d -m 700 "$HOME/.config/nautilo"
umask 077
${EDITOR:-vi} "$HOME/.config/nautilo/railway-recovery.toml"
chmod 600 "$HOME/.config/nautilo/railway-recovery.toml"

Use this exact schema, replacing every example with values for your private recovery destination:

schemaVersion = 1

[storage]
endpoint = "https://s3.example.com"
region = "us-east-1"
bucket = "replace-with-private-recovery-bucket"
objectPrefix = "nautilo-recovery"

accessKeyId = { fromEnv = "NAUTILO_RECOVERY_ACCESS_KEY_ID" }
secretAccessKey = { fromEnv = "NAUTILO_RECOVERY_SECRET_ACCESS_KEY" }
encryptionKey = { fromEnv = "NAUTILO_RECOVERY_ENCRYPTION_KEY" }

# Include only for temporary credentials.
# sessionToken = { fromEnv = "NAUTILO_RECOVERY_SESSION_TOKEN" }

Each secret field accepts exactly one object: either { fromEnv = "NAME" } or { value = "literal" }. Environment references keep secret values out of the file and are recommended, but the variables must be present in the exact shell that runs upgrade or resume. Load them through your password manager's shell integration; do not paste values into command arguments or a shared shell-history file.

Generate the encryption value as exactly 32 random bytes encoded as unpadded base64url only in a private terminal with history and session recording disabled. Store it directly in the password manager before continuing; do not copy it into logs, tickets, chat, or shared command output:

openssl rand 32 | openssl base64 -A | tr '+/' '-_' | tr -d '='

The endpoint must be a credential-free HTTPS root URL with no bucket path, query, or fragment. The bucket must already exist. objectPrefix and sessionToken are optional; remove the session-token line for long-lived scoped credentials.

The CLI refuses a relative path, symlink, non-regular file, file not owned by the current user, unsafe permissions, a file larger than 64 KiB, unexpected TOML keys, missing environment variables, or a malformed 32-byte encryption key. Repair the input. Do not weaken its permissions or copy it into the Railway project.

Inspect the exact launch

Set these non-secret operator variables for the current shell. The launch ID comes from the original deploy or adoption receipt.

export NAUTILO_LAUNCH_ID='<saved-launch-id>'
export NAUTILO_RECOVERY_CONFIG="$HOME/.config/nautilo/railway-recovery.toml"

test -n "$NAUTILO_LAUNCH_ID"
test -f "$NAUTILO_RECOVERY_CONFIG"
nautilo host inspect \
  --backend railway \
  --launch "$NAUTILO_LAUNCH_ID" \
  --json

Require the intended paying workspace, project, public domains, release, and healthy saved launch. Stop on ambiguity, missing custody, or a project that someone else is actively changing.

Review, confirm, and stay attached

First omit confirmation. The command must stop before mutation:

nautilo host upgrade \
  --backend railway \
  --launch "$NAUTILO_LAUNCH_ID" \
  --recovery-config "$NAUTILO_RECOVERY_CONFIG" \
  --json

After reviewing the target and maintenance cost, confirm the same operation:

nautilo host upgrade \
  --backend railway \
  --launch "$NAUTILO_LAUNCH_ID" \
  --recovery-config "$NAUTILO_RECOVERY_CONFIG" \
  --yes --json

Keep the process attached while checkpoints advance. The Server is unavailable during maintenance; allow time for backups, encrypted transfer, upgrade, and a possible replacement-project recovery. Completion means the final receipt identifies the active launch and release and the public HTTPS checks passed; a green Railway canvas alone is not acceptance.

If the command exits pending, the terminal closes, or connectivity is lost, run the continuation with the same launch, recovery file, environment-backed secrets, and encryption key:

nautilo host resume \
  --backend railway \
  --launch "$NAUTILO_LAUNCH_ID" \
  --recovery-config "$NAUTILO_RECOVERY_CONFIG" \
  --json --no-open-browser

Do not start a second upgrade. If resume asks for the protected provider file needed to reconstruct provider configuration on a replacement, add --provider-config <absolute-protected-path> using the same custody rules as the Railway provider file.

What recovery does—and does not—mean

  • Provider-native backups remain attached to the source Railway project and are not an independent disaster-recovery copy.
  • The encrypted portable copy is written to the configured external bucket as a phase of the upgrade; there is no separate command to create it on demand.
  • A replacement project is created only when the active maintenance transaction needs its fallback path. It is not a general restore target.
  • A promoted replacement becomes the active saved launch. The source project is retained; Nautilo does not silently delete it after cutover.
  • Manual Railway volume restore changes provider identities outside the saved Nautilo transaction and can cause later custody checks to refuse. Do not use it as the routine continuation for an interrupted upgrade.

After completion, run host inspect for the active launch, sign in as the existing owner, verify Server identity and representative durable work, and complete one useful model-backed action. Keep the recovery configuration and key for at least as long as the corresponding recovery objects may be needed.