Fly Machines are long-running containers. Same pattern as Docker: capy run wraps your process, and flyctl secrets set puts SECRETS_BLOB and PROJECT_KEY into the Machine’s env.
Dockerfile
fly.toml
No special Fly config needed - standard http_service on the port your app listens on.
Setting secrets
There is no Fly connector, so capy deploy mints the deploy token and hands the values back to you rather than pushing them anywhere: it opens a temporary page on 127.0.0.1 in your browser with SECRETS_BLOB, PROJECT_KEY, and platform instructions, and prints both values in the terminal if it can’t start that local server. You set them with flyctl yourself.
Fly restarts the Machines automatically after flyctl secrets set. Every boot re-runs capy run, which calls Capy’s service once to fetch the service key for that deploy token, decrypts the blob in memory, and spawns your process with the plaintext env. Nothing is cached across boots - a Machine that auto-stops and auto-starts calls the service again, so the Machine needs outbound HTTPS to https://api.capy.sc every time it starts. Set CAPY_API_URL to point it at a BYOC instance instead.
Anything already in the Machine’s env wins: a variable set in [env] in fly.toml or set directly with flyctl secrets set overrides the decrypted value of the same name.
Deploying
That’s it. The image has capy run as its entrypoint; Fly has the deploy-code secrets; every new Machine decrypts at boot.
Verifying
capy run hands the decrypted values to the process it spawns - it does not export them into the Machine’s environment. A fresh flyctl ssh console shell sees SECRETS_BLOB and PROJECT_KEY, not your plaintext secrets. To check decryption from inside the Machine, wrap a throwaway command the way your app is wrapped:
That is a second decrypt, so it only works while the deploy token is still valid. Note that the child keeps SECRETS_BLOB and PROJECT_KEY too - capy run layers the decrypted values under the environment it inherited rather than replacing it.
Revocation
capy deploy list shows this project’s deploy tokens; capy deploy revoke <deployId> cuts one off at the service. The next Machine boot then fails to decrypt and capy run exits 1, Fly’s health checks flag the bad rollout, and traffic stays on the previous Machines.
Machines that are already running are unaffected - they decrypted at boot and hold the plaintext in memory. Restart them after revoking if you need the old values out of circulation immediately. Last modified on August 11, 2026