> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tinfoil.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Production checklist

> A checklist for running Tinfoil Containers in production.

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](/containers/secrets-and-env-vars#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](/containers/private-images).
* **Rotate secrets periodically.** Update secret values in the dashboard, then redeploy your container to pick up the new values.
* **Only expose necessary paths.** The `paths` list in your config acts as an allowlist — only list the endpoints your app needs to serve externally.

## Reliability

* **Use blue-green updates.** Always update running containers via the [Update flow](/containers/updates) rather than deleting and redeploying. This gives you zero-downtime deploys and the ability to fix things if the new version is broken. Note: [multi-GPU containers](/containers/updates#gpu-container-updates) have downtime during updates by default.
* **Validate releases in staging.** Before switching production traffic, deploy the new version in [staging mode](/containers/staging-mode) 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](/containers/limits#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](/containers/custom-domains) rather than the default `*.containers.tinfoil.dev` URL. This gives you control over DNS and makes it easier to migrate later.
* **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. Redeploy 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](https://github.com/tinfoilsh/tinfoil-containers-template) to get the latest `cvm-version` value.
* **Pin images with SHA256 digests.** Always use `image:tag@sha256:...` in your config. This ensures the exact image binary is verified and recorded in the transparency log. If you build your own image, the release workflow handles this — use a placeholder on `main` and it substitutes the real digest at the tagged commit. See [Building images](/containers/building-images#image-digests-in-the-release-workflow).
* **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.
