Skip to main content
Not every item here will apply to your container. Use this as a starting point and adapt it to your workload.

Security

  • Don’t use debug mode in production. Debug mode enables SSH access and logging that you don’t want in a production enclave. Deploy a separate debug instance for troubleshooting.
  • Use secrets for all sensitive values. Database URLs, API keys, tokens, and credentials should be stored as secrets, not as environment variables in your config file or repo.
  • Use minimal registry credentials. If you’re pulling from a private registry, create access tokens with read-only scope. See registry auth.
  • Rotate application credentials periodically. Update managed secret values in the dashboard, then update your container to pick up the new values. Persistent-volume keys are different: retain the original key in your private secret store. Volume-key rotation requires explicit migration or re-encryption, not just a secret-value change.
  • Only expose necessary paths. The paths list in your config acts as an allowlist. Only list the endpoints your app needs to serve externally.
  • Know the CLI’s connection policy. CLI connections to your containers (connect, forward, ssh, scp, attest-ssh) check the resolved config against a local policy; scripts without a terminal fail closed on unknown configs and should state their expectation with --repo. Avoid --dangerous — it skips the config check entirely. If a machine should never learn new trust, tinfoil trust set --mode frozen locks the policy.

Reliability

  • Use the update flow. Update running containers through the Update flow rather than deleting and recreating them. CPU-only and single-GPU containers without persistent volumes update blue/green, so the current version keeps serving if the new one fails its health checks. Multi-GPU containers and containers with persistent volumes have downtime during updates; the dashboard and CLI ask you to confirm it first.
  • Hold updates for review before they take traffic. For running CPU-only and single-GPU instances without persistent volumes, hold the update, try it at its review URL, and promote it after testing. Reserve debug mode for troubleshooting with non-sensitive data.

Resources

  • Right-size your container. Start with the smallest resource tier that works and scale up if needed. Over-provisioning wastes resources; under-provisioning causes OOM kills and slow responses. See resource options for guidance.
  • Monitor memory usage. If your container is using close to its memory limit, it may get killed under load. Allocate headroom above your typical usage.

Networking

  • Set up a custom domain. For production APIs, use a custom domain rather than the default *.containers.tinfoil.dev URL to control your application’s address.
  • Listen on the right port. Your app must listen on the port you configured as upstream-port in tinfoil-config.yml.

Secrets hygiene

  • Watch for stale secrets. The dashboard shows a warning when secrets have been updated since the container was last deployed. Update promptly after rotating secrets.
  • Don’t log secret values. Even though secrets are only available inside the enclave, avoid printing them to stdout/stderr. Treat the enclave runtime the same way you’d treat any production server.
  • Clean up unused secrets. Remove organization and repository secrets that are no longer referenced by any container.

Deployment workflow

  • Start from the template. Create your repo from the tinfoil-containers-template for a complete config and measured-release workflows.
  • Pin images with SHA256 digests. Commit the real image digest before releasing the config so verification identifies the exact image. See Building images.
  • Tag releases in Git. Use semantic versioning or a consistent tagging scheme so you can track which version is deployed and roll back to a known-good tag.