Skip to content
install & set up
$ npm i -g turnout-cli
$ cargo install turnout

# then, once:
$ turnout setup
$ turnout app add
$ turnout server add
$ turnout use

turnout

Point local apps at any backend stand, keep servers and secrets at hand, build and deploy - from any directory.
Terminal window
$ turnout use web staging
'web' now uses 'staging'.
The running gateway picks this up automatically.
'staging' is up: https://staging.example.com/health answered 200 in 84 ms.
$ turnout status --short
staging · gw ok · 1 dev
$ cd ~/dev/web/src/components
$ turnout dev --open
[web] pnpm dev --port 5100
[web] http://web.localhost -> dev server port 5100
◇ web ready in 1.4s - http://web.localhost

Nothing in the project changed - the app still talks to localhost, and the gateway routes it to the stand you picked. Cookies are kept per app and stand, so the switch does not log you out.

Dev gateway

Your apps always talk to localhost; turnout routes requests to the selected stand. Switching is one command, and sessions survive it - the gateway keeps a cookie jar per app+server pair. You never type a port: turnout assigns them, and the app gets the address as a variable on turnout dev and from a dotenv file turnout keeps in step. And every app has one address of its own - http://myapp.localhost - whatever port its dev server took. The servers are one command away too: turnout ssh and turnout exec reach them with nothing to remember.

One window onto the switchyard

turnout status shows where every app points, the gateway, running jobs and the latest actions - in colour, with clickable addresses. status --short puts prod · gw ok · 2 dev into your prompt or tmux bar; turnout use - goes back to the stand before, and the server picker shows which stands are up before you pick one. Every command that reports takes --json.

The gateway speaks up

When a stand answers 502 or its session expires, the gateway says so - in status, in the prompt line, and once on the desktop - instead of leaving you to debug your own app. A stand you can only log in to in a browser gets its session handed over with turnout cookie set, straight from the developer tools.

A doctor for why it does not work

turnout doctor finds the dev server a closed terminal left on the app’s port, the dotenv file that names an old gateway port, the stand that is down and the session that lapsed overnight - each with its fix; --fix repairs what is turnout’s to repair. doctor --server prod signs in as the deploy would and says where it would stop: a directory it cannot write, a full disk, a restart that wants a sudo password.

Servers, logins and paths, apart

A machine, the credential that logs into it and the directory files land in are three named entities. Define the deploy account once and point every stand at it; the same web root serves staging and production without being retyped.

Named deploy targets

An app, a server, a credential and a path join into one named target - myapp-prod - that deploy, backup and restore all address directly, from any directory, without a project folder or a binding in the way.

Key access, set up for you

turnout key setup prod generates a key, authorizes it on the server, proves it signs in and only then switches the credential over - so a misconfigured server never costs you the password that still works. Windows administrators keep their keys in a different file, and turnout writes to that one.

The SSH agent signs for you

A credential can authenticate with a key your agent already holds, so a passphrase is typed once per session rather than once per command. SSH_AUTH_SOCK on Linux and macOS; Pageant or the OpenSSH agent service on Windows - whichever is running.

Secrets in the OS keyring

Windows Credential Manager, macOS Keychain or Linux Secret Service. A secret belongs to a credential, so one pass set covers every stand it reaches. Copy a password to the clipboard with one command; nothing lives in plain files.

Commands from anywhere

dev, build, test and lint run in the right project folder for you - no cd required. Commands come from your actual package.json scripts.

Jobs in the background

turnout dev --detach gives the terminal back and the server keeps running. turnout ps shows everything turnout runs - dev servers, builds, deploys, the gateway - with ports, addresses and uptime; logs -f follows any of them, and stop takes a job down with every process it started. When a job is done, a desktop notification says so and opens the page, the stand or the log; TURNOUT_DETACH makes the background the default.

A quiet console

A build shows a loader and its elapsed time, not two minutes of scrollback; a dev server goes quiet once it is up and speaks again only when something breaks. A failure prints its output on the spot, every job’s output is kept in a log file, and -v still gives you everything.

Deploy

Build, upload over SSH/SFTP, restart the service, then ask the stand whether it works - and roll it back by itself when it does not. --diff shows what would change before anything is written; one command ships one build to several targets; a long restart survives a dropped connection. Artifacts travel as one archive, to Linux and Windows servers alike.

Portable settings

export writes your apps, servers, credentials, paths and groups to one file; import merges it on another machine. Secrets come along only when you ask, sealed with a passphrase.

Nothing to memorize

Leave a name out and pick it from a list; in bash, Tab completes app, server, credential, path and group names from your own catalogs.

An action journal

Every state change appends one JSON line - what happened and to which entities, never secrets. tail, grep and jq work on it directly.