Pular para o conteúdo

Buscar na documentação

Buscar na documentação do Skiffly

CLI

Install the `skiffly` CLI, log in, link a directory and deploy. Commands follow the Railway CLI wherever Skiffly has an analog.

npm i -g skiffly          # or: pnpm add -g skiffly, or npx skiffly <command>
skiffly --help

Node.js 20+. The CLI is one self-contained file with no native dependencies; it embeds the MCP server and the config-as-code runtime.

Log in#

skiffly login                     # opens app.skiffly.dev/cli-login in the browser; confirm there
skiffly login --browserless       # headless machines: prints the URL and the pairing code, waits for confirmation
skiffly login --token skiffly_…   # non-interactive: a workspace token from Settings → Developer
skiffly whoami
skiffly logout                    # revokes the account token on the server and forgets it locally

skiffly login works like railway login: the CLI opens the dashboard, you confirm the pairing code while signed in, and the CLI receives an account token (skiffly_acct_…, valid 90 days, all your workspaces). Sessions are listed and can be revoked in Settings → Developer → CLI sessions & connected apps. The token is stored in ~/.config/skiffly/config.json (mode 600). In CI set SKIFFLY_TOKEN=skiffly_… (a workspace token with the write scope); the environment variable wins over the saved token.

skiffly init                      # new project, linked to this directory
skiffly link                      # pick an existing project / environment / service
skiffly link -p my-app -e staging -s web
skiffly status                    # what is linked, plus every service's status and domains
skiffly unlink

Links are stored per path in the global config and found from subdirectories. SKIFFLY_PROJECT_ID, SKIFFLY_ENVIRONMENT_ID and SKIFFLY_SERVICE_ID override the link, and every command that needs a target accepts -p/--project, -e/--environment, -s/--service (id or name).

Deploy#

skiffly up                        # upload the current directory, build it and stream logs
skiffly up ./apps/api             # upload another directory
skiffly up -d                     # detach after the deployment is created
skiffly up --git                  # deploy the pushed HEAD of the current branch from GitHub instead
skiffly up --git --commit <sha>
skiffly redeploy                  # latest build again, current settings
skiffly restart                   # restart containers, no build
skiffly deploy --image ghcr.io/acme/api:1.4 --name api --port 8080 -v LOG_LEVEL=info
skiffly deploy --template postgres
skiffly deployment list

skiffly up works like railway up: the directory is packed into a tarball (files matched by .gitignore and .skifflyignore are skipped, .git always is; 100 MB compressed at most), uploaded to the linked service and built with Railpack or the service's Dockerfile — no commit or push required. The deployment shows up in the dashboard as CLI upload, and the service is created if the project has none (-y skips the question). --git keeps the previous behaviour: the directory must be a git repository whose origin is connected to the service, and Skiffly builds the pushed branch head.

Import from Railway#

skiffly import --from-railway     # interactive: Railway token → project → Skiffly project, with a summary table
skiffly import --from-railway --railway-token --railway-project <id> --project new --dry-run

Copies services (source, build/start commands, healthchecks, cron, replicas), variables with their ${{Service.VAR}} references, volumes, custom domains and TCP proxies into a Skiffly project and prints what still needs a manual step (DNS records, volume data). Details: Migrate from Railway.

Logs, shell, run#

skiffly logs -f                   # runtime logs, follow
skiffly logs --build              # build output; --system for restarts / OOM
skiffly logs -n 200 --filter "error"
skiffly ssh                       # /bin/sh in a running container
skiffly ssh -s api -- ls -la /app # one-off command, exit code passed through
echo "select 1" | skiffly ssh -s postgres -T -- psql -U postgres
skiffly run -- pnpm dev           # run a local command with the service's variables

Shell into a container#

skiffly ssh (alias shell) opens an interactive shell in the first running replica of the service; --deployment <id> picks a deployment, -T disables the pseudo-terminal for piping. Sessions go through the API over WebSocket with your token, are written to the audit log, limited to five per user and closed after 30 minutes idle. See Security.

Variables, domains, volumes, proxies#

skiffly variables                 # --kv for KEY=value, --shared for environment-wide
skiffly variables set KEY=value [--stdin KEY] [--skip-deploys]
skiffly variables delete KEY
skiffly domain                    # generate a *.skiffly.cloud domain
skiffly domain app.example.com    # custom domain, prints CNAME + TXT
skiffly domain status app.example.com
skiffly volume add --mount-path /data --size 5
skiffly proxy add --port 5432     # public TCP proxy
skiffly connect [service]         # psql / mysql / redis-cli / mongosh through a proxy

Environments and services#

skiffly environment               # switch
skiffly environment new staging --duplicate production
skiffly service                   # link a service; service list; service delete
skiffly open                      # dashboard in the browser (--print for the URL)

Config as code, billing, docs, raw API#

skiffly config init | validate | plan | apply
skiffly billing                   # balance, plan, current usage (alias: usage)
skiffly templates [search]
skiffly docs deploy               # search the bundled docs
skiffly api '{ me { login } }'    # raw GraphQL with the CLI token; -v '{"id":"…"}' for variables
skiffly mcp                       # MCP server over stdio; mcp install claude|cursor|codex

Output and exit codes#

Every list command has --json. Exit codes: 0 ok, 1 error, 2 usage or not linked, 3 not authenticated, 4 not found, 5 forbidden or plan limit, 6 network. SKIFFLY_DEBUG=1 prints stack traces.

The complete command table is in the CLI reference.