Skip to main content
This walkthrough deploys a working container to a Tinfoil enclave using the tinfoil-containers-template. The template ships with a pre-built hello-world image, so you can run through the full flow end-to-end before swapping in your own.

Prerequisites

1. Create a repo from the template

Use tinfoil-containers-template to make a new repo: click Use this templateCreate a new repository. Give it any name you’d like, and make sure it’s public. The tinfoil-config.yml needs to be public so the deployment can be independently verified — Tinfoil fetches it at deploy time to compute the enclave measurement, and your users’ SDKs fetch it (via the Sigstore transparency log) to check that the running enclave matches what you published. The Docker image itself can still be private — see Private images.

2. Read the tinfoil-config.yml

This is the file that defines your deployment. It’s already wired up:
tinfoil-config.yml
cvm-version: 0.7.5
cpus: 2
memory: 8192

containers:
  - name: "hello-world"
    image: "ghcr.io/tinfoilsh/tinfoil-containers-hello-world@sha256:<hash>"
    env:
      - MESSAGE: "Hello from Tinfoil"
    secrets:
      - GREETING_TOKEN

shim:
  upstream-port: 8080
  paths:
    - /*
The containers section defines a hello-world container, which points to a prebuilt Tinfoil image, tinfoil-containers-hello-world. This image takes in an environment variable, and a secret, and on an HTTP request it returns the message & the presence of the secret. For now, leave it alone — we’ll customize it later. See the configuration reference for the full schema (paths, healthchecks, GPUs, multi-container setups, etc.).
Deploying a Hugging Face model with an inference server like vLLM? Prepare the model weights first in the dashboard’s Models tab, then add the generated models: block to your config. See Model weights.

3. Release a version

Trigger the Tinfoil Release workflow with a version. This creates the Git tag, measures the image, signs the attestation, and publishes a GitHub release:
gh workflow run tinfoil-release.yml -f version=v0.0.1
Or via the GitHub UI: ActionsTinfoil ReleaseRun workflow → enter v0.0.1.
Two workflows run back-to-back: tinfoil-release.yml creates the tag, then auto-dispatches tinfoil-release-publish.yml, which runs measure-image-action to compute the enclave measurement and publish the release. Wait for both to finish (~1 min) before deploying — the tag won’t appear in the dashboard’s picker until then.

4. Add the GREETING_TOKEN secret

The config declares a GREETING_TOKEN secret. That means we’ll have to add a value for it before deploying. Tinfoil Dashboard will refuse to deploy unless this secret exists. To add the value:
  1. Open the Tinfoil Dashboard
  2. Navigate to Tinfoil ContainersSecrets
  3. Click Add Secret, enter the name GREETING_TOKEN and any value
  4. Save

5. Deploy

In the dashboard:
  1. All Containers tab → New Container
  2. Enter a container name (lowercase, hyphens allowed — e.g. hello-world)
  3. Select your new repository (enter owner/repo manually or pick from connected repos)
  4. The v0.0.1 tag will auto-select
  5. Confirm the env vars and secrets shown match your config
  6. Click Deploy Container
The status will show Deploying while the image is pulled and the enclave boots. After a minute or two it flips to Running.
Click Connect GitHub in the dashboard to install the Tinfoil GitHub App on your repo. This enables automatic latest-release promotion when an update succeeds. Without it, you’ll need to mark each release as latest yourself after every update.

6. Make a request

Your container is live at https://<name>.<org>.containers.tinfoil.dev. To test it out:
curl https://<name>.<org>.containers.tinfoil.dev/
You should see:
MESSAGE: Hello from Tinfoil
GREETING_TOKEN: present
For real-time, attested requests (where the SDK verifies the enclave measurement before sending data), use one of the Tinfoil SDKs.

Making your own

The template you just used deployed a pre-built Docker image. If you have another pre-built Docker image, you can use that by referencing it in the tinfoil-config.yml However, if you have some code in a repository and want to deploy it, you’ll have to build an image for it first. How you do this depends on the visibility of the repository:
  • Public source code → use tinfoil-public-containers-template. When deploying public code you can do it all in one repo. The public-containers template contains one workflow that builds the image, updates the local config with the new digest, and releases a new version. Essentially, it consolidates the tinfoil-containers-hello-world repo & the tinfoil-containers-template repo.
  • Private source code → keep your code in its own private repo and use tinfoil-containers-hello-world as the build-and-publish pattern (Dockerfile + workflow that pushes to GHCR). Then reference the published image from a tinfoil-containers-template fork like this quickstart.
If the published image is private (not just the source), Tinfoil needs registry credentials to pull it at deploy time. See Private images. Public images work without any configuration.
Container images must be pinned by SHA256 digest (e.g. image:tag@sha256:...). The release workflow uses the digest to compute the measurement that clients verify against. Get the digest with: docker pull <image> && docker inspect --format='{{index .RepoDigests 0}}' <image>.
Pin digests behind an immutable tag (e.g. v1.2.3), not just :latest. On ghcr.io an un-tagged digest is garbage-collected once :latest moves.

Updating

To roll out a change — new image digest, new env var, new path — edit tinfoil-config.yml, commit, then release a new version: For example, change the MESSAGE env var:
tinfoil-config.yml
    env:
      - MESSAGE: "A new message!"
Commit, then:
gh workflow run tinfoil-release.yml -f version=v0.0.2
Or via the GitHub UI: ActionsTinfoil ReleaseRun workflow → enter v0.0.2. In the dashboard, click Update on your container and select v0.0.2. This triggers a blue-green update (no downtime). curl again to see the new message.

Using the CLI

Steps 4–5 also work from the Tinfoil CLI. Once you have an admin API key:
tinfoil login                                           # one-time setup
tinfoil secret create GREETING_TOKEN --value-file -     # paste secret, ctrl-D
tinfoil container create hello-world \
  --repo <owner>/<repo> \
  --tag v0.0.1 \
  --secret GREETING_TOKEN
tinfoil container get hello-world                       # poll status until "ready"
See Managing containers from the CLI for the full lifecycle reference.