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" \
--jsonRequire 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" \
--jsonAfter 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 --jsonKeep 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-browserDo 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.