Skip to main content
One deployed Edge Script serves all your non-s3 storage zones. Run the bundled deploy command with your Bunny account key available:
The CLI enumerates every non-s3 zone in your config (global and per-collection) and writes each one’s credentials into its own ZONE_<NAME> script secret. On success it prints one shared edge block:
Paste that same edge: { scriptUrl, secret } into storage.clientUploads of every non-s3 zone that enables client uploads — the one script (one scriptUrl, one shared secret) handles all of them. Each zone’s credentials live in a separate ZONE_<NAME> script secret, so re-running the command is incremental: it adds a ZONE_* secret for each new zone and removes the ZONE_* secrets for zones no longer in your config. Adding a zone with the npx @seshuk/payload-storage-bunny init wizard no longer requires a full redeploy — it upserts just that zone’s secret. S3 zones need no Edge Script at all.

Deploying with the right environment

The deploy command reads your zone access keys and account key from the environment that was active when Payload loaded your config — the same env resolution Payload uses at boot (@next/env). On a dev machine that means your .env/.env.local values, not production. To deploy the production script from a dev machine, point the command at a specific env file with --env-file (it re-loads that file with override semantics and rebuilds the plan from it):
Equivalent recipes without the flag (the env is set before Payload loads its config, so it wins):
NODE_ENV=production alone isn’t enoughSetting NODE_ENV=production does not make the command use .env.production: @next/env still ranks .env.local above .env.production, so your dev values leak into a “prod” deploy. Use --env-file (or dotenv-cli/inline env vars) to select the environment explicitly. (NODE_OPTIONS='--env-file=…' is not supported — Node rejects --env-file inside NODE_OPTIONS.)
For CI or config-free deploys, --zones-file zones.json bypasses config entirely and takes the zone map from a JSON file:
Each entry supplies its access key inline (accessKey) or indirectly from an env var (accessKeyEnv, so keys stay out of the file). Combine with --secret, --name, and --api-key. --zones-file and --env-file can’t be combined.

Multiple Edge Scripts (multi-account)

If your zones resolve to different scriptUrls (for example, some zones live on a second Bunny account with its own deployed script), the command groups them and refuses to guess. It lists each group and asks you to select one:
Pair each invocation with the matching --api-key/--env-file for that account. Each deploy writes only the selected group’s zones as per-zone ZONE_* secrets; the ZONE_* secrets for other groups/accounts aren’t touched. If several separate Payload configs intentionally share one script and each deploys its own zones, pass --no-prune so a deploy only upserts its zones and never removes the others’ ZONE_* secrets. Pass --check (optionally with --script-url) to compare the deployed script version against the bundled one instead of deploying:
Pass --help to print the full flag reference: