Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.capy.sc/llms.txt

Use this file to discover all available pages before exploring further.

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

FROM node:22-slim

WORKDIR /app
RUN npm install -g @capy/cli

COPY package.json bun.lock ./
RUN bun install --production
COPY . .

EXPOSE 3000
ENTRYPOINT ["capy", "run", "--"]
CMD ["node", "server.js"]

fly.toml

app = "my-app"
primary_region = "sjc"

[build]

[http_service]
  internal_port = 3000
  force_https = true

[[vm]]
  memory = "512mb"
  cpu_kind = "shared"
No special Fly config needed - standard http_service on the port your app listens on.

Setting secrets

capy deploy      # pick Fly.io; copy the printed values

flyctl secrets set \
  SECRETS_BLOB="<value-from-capy-deploy>" \
  PROJECT_KEY="<value-from-capy-deploy>"
Fly restarts the Machines automatically after flyctl secrets set. The first boot under the new deploy code calls Capy’s service once, caches the decrypted env for the Machine’s lifetime, and serves traffic.

Deploying

flyctl deploy
That’s it. The image has capy run as its entrypoint; Fly has the deploy-code secrets; every new Machine decrypts at boot.

Verifying

Shell into a running Machine and inspect its env:
flyctl ssh console
# Inside the Machine:
env | grep -E "DATABASE_URL|STRIPE"  # should show plaintext
SECRETS_BLOB and PROJECT_KEY are still set too - capy run passes the parent env through to the child.

Revocation

Revoke the deploy token → next Machine boot fails to decrypt, Fly’s health checks flag the bad rollout, traffic stays on the previous Machines. Rotate the project key instead if you need to kill all running Machines’ ability to decrypt.