Skip to main content
The Tinfoil CLI lets you manage repository deployments and individual container instances, along with model weights, secrets, SSH keys, registry credentials, and custom domains. This page walks through the full container lifecycle from the terminal.

Prerequisites

Install the CLI:
Or download a binary from the releases page. A Docker image is published at ghcr.io/tinfoilsh/tinfoil-cli. You also need a Tinfoil organization with Containers enabled, the same prerequisite as the quickstart.

Authenticating

Container management endpoints accept an admin API key scoped to a single organization. Create one from the dashboard’s Admin tab by following Getting a Tinfoil admin key, then run:
Credentials are written to ~/.tinfoil/config.json with mode 0600. These environment variables override saved configuration for one-off invocations:
Admin keys carry the organization ID, so the CLI never asks for an org. To act on a different org, log out and log in with that org’s admin key.

Inspecting your organization

Pass -o json to get machine-readable output suitable for scripting:
Deployments can be referenced by repository name (owner/repo) or deployment UUID. Containers can be referenced by name or container UUID. If you have a debug-mode and a production-mode container with the same name, pass --debug-mode to disambiguate.

Publishing a config release

Before a tag can be deployed, the config repo must publish a measured release. In the dashboard, open the repository from ContainersRepositories, edit tinfoil-config.yml, open and merge the generated pull request, then follow the Release steps. Alternatively, commit the config change in GitHub and run the Tinfoil Release workflow from the repository’s Actions tab. Wait for both release workflow phases to finish before deploying the tag. See Updating & lifecycle for both workflows. The same flow is available from the CLI with tinfoil repo, which acts through the Tinfoil GitHub App installed on the repository:
repo build info reports the latest tag and a suggested next patch version. repo build run accepts a semver version and adds the v prefix if missing. The config repository must be public, so never place secret values in tinfoil-config.yml; use secrets instead.

Deploying a container

Once you have a measured release in your config repo (see quickstart for the GitHub setup), deploy it:
The command returns once the deployment is queued. Poll for readiness with tinfoil container get my-app. Initial creates cannot use staging. Release promotion defaults to true; pass --promote-release=false to decline it. Promotion happens only when the GitHub App is connected, the repository is active, and an initial or changed tag reaches production on a non-debug instance. Explicit --host selection requires host-selection access for the organization, and the selected host and GPU size must be available to it. --replace is destructive: the old instance is stopped and removed before the replacement is queued. If the replacement later fails, the old instance is not restored.

Managing deployments

One repository deployment contains all container instances in your organization that use the same GitHub repository. Inspect its aggregate status and instance counts with:
Set whether eligible repository deployment updates use staging mode by default:
Update all eligible instances to one release:
To update only selected instances, repeat --instance with each container UUID:
Pass --staging true or --staging false to override the deployment’s default for one update. Staging applies only to ready CPU-only and single-GPU container instances; unsupported selected instances report per-instance failures rather than updating without staging. Only ready or failed instances are otherwise eligible. The dashboard may label ready instances as Running. An instance is skipped if it is in any other state or already has an update in progress. Results are reported per instance, and the command exits non-zero if any instance is skipped or fails. Release promotion defaults to true and requests promotion for each eligible changed tag after it becomes production-serving, subject to the repository and GitHub App conditions described above. For staged updates, the request becomes eligible only after acceptance. Pass --promote-release=false to decline.

Lifecycle

start and relaunch support --tag, --variable, --secret, --ssh-key, --debug, --promote-release, --custom-domain, and --host. relaunch also supports --staging; start does not. Supplied variables replace the full saved per-instance variable map; they do not replace the measured env values in tinfoil-config.yml. A supplied secret list replaces the saved manual selection, then merges with secrets declared in tinfoil-config.yml that exist in repository or organization scope. Supplied SSH-key lists replace their saved selections. Use --host with start only to move a stopped instance, and with relaunch only to move a failed instance. Relaunching a ready instance on another host is rejected; stop it first, then start it with the new host. Host access and GPU entitlement are validated when you explicitly select or move to a host.
tinfoil container delete permanently removes the container, its secret bindings, and its DNS records. There is no undo.

Managing in-progress updates

CPU-only and single-GPU updates triggered by relaunch go through a blue-green window. While the new version is booting, you can inspect or cancel it. Multi-GPU relaunches instead request deletion of the current deployment and immediately queue the replacement; they have downtime and cannot be canceled after replacement starts.
With staging, a ready blue-green update candidate waits for update accept while the existing container instance serves production. Without staging, traffic switches automatically once the candidate is ready. For blue-green updates, update cancel discards the candidate without changing the production-serving instance.

Secrets

Manage organization secrets with tinfoil secret:
Secrets scoped to a single repository use tinfoil repo secret with the same subcommands and flags:
Repository secrets are also available from the repository’s Repository secrets section under ContainersRepositories in the dashboard. The same secret name can have different values in different repositories. An organization secret and a repository secret cannot share a name within the same organization. --value-file accepts - for stdin, which is the recommended way to set secrets — it avoids leaking the value via shell history or process listings. See secrets and env vars for the underlying model.

SSH keys

Debug-mode containers authorize SSH access using public keys registered at the org level: Choose one of the supported input forms:
Reference keys at deploy time with --ssh-key NAME on tinfoil container create (or relaunch / start).

Registry credentials

For private images, set credentials per registry. Tinfoil supports ghcr, gcr, and dockerhub:

Custom domains

Once a domain is verified, deploy a container against it with tinfoil container create ... --custom-domain api.example.com. See custom domains for the DNS record details and troubleshooting.

Model weights

For GPU inference containers, tinfoil model prepares Hugging Face weights as verified artifacts that enclaves load with integrity checking. See Model weights for how the pieces fit together.
wrap pins the repo’s latest default-branch commit unless --commit is given. update requires an existing completed wrap of the repo on that host and resolves the newest commit when --commit is omitted; when an update run with --wait completes, it prints the new models: block along with the delete command for the previous wrap job — run that delete only after the new config is released and deployed. delete is refused while a job is running or while any deployment on the host references the artifact.
Model commands require tinfoil-cli v0.17.0 or later.

Connecting to a deployed container

tinfoil container connect <name> resolves a container’s enclave domain and source repo, then runs a verified local proxy — equivalent to the nested tinfoil proxy -e <domain> -r <repo> command, but without copy-pasting either value:
The proxy binds to 127.0.0.1 by default. Pass --bind <ADDRESS> to use another interface:
Only bind beyond localhost on a trusted network because other hosts may then send requests through the proxy. In another terminal, send requests to http://localhost:3301 exactly as you would to your container’s domain. The proxy verifies attestation on startup and pins the TLS certificate for subsequent requests. See connecting for the full client story (SDKs, raw tinfoil http).
Debug-mode containers do not pass attestation, so connect (and any other SecureClient flow) will refuse to use them. SSH into debug containers directly via ssh -p <port> [email protected] — the dashboard shows the exact command on the container’s card.

Resource metrics

Returns a JSON object with data_points and interval. Each data point has a timestamp, average and maximum CPU/GPU utilization, average and maximum CPU/GPU memory utilization, and CPU/GPU total memory. interval is the width of each time bucket. This is useful for piping into jq or a chart tool.

Scripting tips

  • -o json is supported on every list/get command.
  • Exit codes are non-zero on failure, with the API error message printed to stderr.
  • All commands respect the environment overrides listed above, so the CLI is safe to use from CI — store the admin key as a secret and pass it through the environment instead of running tinfoil login.
  • --verbose and --trace increase log verbosity for debugging connectivity issues.