Environment Variables
Configure environment variables for your workers with .env file support and dashboard secrets.
Environment Variables
Ploy lets you define environment variables in ploy.yaml and access them in your worker via env.vars. Variables can be hardcoded values or references to .env files and process environment variables.
Configuration
Define environment variables in your ploy.yaml:
kind: dynamic
build: pnpm build
out: dist
env:
APP_NAME: my-app
SECRET_KEY: $SECRET_KEY
API_URL: $API_URL- Hardcoded values (e.g.
APP_NAME: my-app) are used as-is in all environments. $VARreferences (e.g.SECRET_KEY: $SECRET_KEY) are resolved from your.envfile during local development, or from the Ploy dashboard in production.
All environment variables must be defined in ploy.yaml. Variables not
declared in ploy.yaml will not be available in your worker, even if they
exist in your .env file or the Ploy dashboard.
Run ploy types to generate TypeScript types:
ploy typesThis generates an env.d.ts file with typed access to your variables:
declare global {
interface PloyEnv {
vars: {
APP_NAME: string;
SECRET_KEY: string;
API_URL: string;
};
}
}Basic Example
export default {
async fetch(request, env) {
return Response.json({
appName: env.vars.APP_NAME,
apiUrl: env.vars.API_URL,
});
},
} satisfies Ploy;Local Development with .env
Create a .env file in your project root:
SECRET_KEY=my-local-secret
API_URL=http://localhost:3000/apiWhen you run ploy dev, the emulator loads .env and resolves any $VAR references from it. Hardcoded values in ploy.yaml are always used as-is.
Add .env to your .gitignore file. Never commit secrets to version control.
Resolution Order
For $VAR references, the emulator resolves values in this order:
.envfile in your project directory (highest priority)- Process environment variables (e.g. from your shell)
If a $VAR reference cannot be resolved from either source, the variable is omitted from the worker environment.
Production: Dashboard Variables
In production, $VAR references are resolved from environment variables set in the Ploy dashboard.
Setting Variables in the Dashboard
- Go to your project settings in the Ploy dashboard
- Navigate to the Environment Variables section
- Add variables that match the
$VARreferences in yourploy.yaml
For example, if your ploy.yaml has:
env:
SECRET_KEY: $SECRET_KEYYou would add a variable with key SECRET_KEY and your production secret value in the dashboard.
You can only add variables in the dashboard that are defined in your
ploy.yaml env section. The dashboard will reject variables that are not
declared in ploy.yaml.
Secret vs Plaintext
When adding variables in the dashboard, you can choose between:
- Secret: The value is encrypted and never displayed after creation. Use for API keys, tokens, and passwords.
- Plaintext: The value is stored and displayed in plain text. Use for non-sensitive configuration.
How It Works
Hardcoded Values
Values without a $ prefix are injected directly into the worker environment:
env:
APP_NAME: my-app # Always "my-app" in all environments
NODE_ENV: production # Always "production"These values cannot be overridden by .env files or dashboard settings.
Variable References
Values starting with $ are references that get resolved at runtime:
env:
SECRET_KEY: $SECRET_KEY # Resolved from .env (local) or dashboard (production)
DB_URL: $DATABASE_URL # The reference name can differ from the keyThe reference name after $ is looked up in the .env file or dashboard. The key name (left side) is what your worker accesses via env.vars.
Accessing Variables
All variables are available under env.vars in your worker:
export default {
async fetch(request, env) {
// Hardcoded values
const appName = env.vars.APP_NAME;
// Resolved references
const secretKey = env.vars.SECRET_KEY;
return new Response(`${appName}: ${secretKey}`);
},
} satisfies Ploy;Full Example
Project Structure
my-worker/
├── .env # Local secrets (gitignored)
├── ploy.yaml # Variable definitions
├── env.d.ts # Generated types
├── package.json
├── tsconfig.json
└── src/
└── index.tsploy.yaml
kind: dynamic
build: pnpm build
out: dist
env:
APP_NAME: my-app
SECRET_KEY: $SECRET_KEY
API_URL: $API_URL.env
SECRET_KEY=dev-secret-key-123
API_URL=https://api.dev.example.comsrc/index.ts
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === "/config") {
return Response.json({
appName: env.vars.APP_NAME,
apiUrl: env.vars.API_URL,
// Never expose secrets in responses!
});
}
// Use SECRET_KEY for authentication
const authHeader = request.headers.get("Authorization");
if (authHeader !== `Bearer ${env.vars.SECRET_KEY}`) {
return new Response("Unauthorized", { status: 401 });
}
return Response.json({ message: "Authenticated" });
},
} satisfies Ploy;Next Steps
- Workers - Learn about Ploy workers
- Configuration - Full
ploy.yamlreference - Databases - Add persistent SQLite databases
How is this guide?
Last updated on