LogoBoring Template

Environment Variables

Learn how to securely manage environment variables for different deployment environments on Vercel.

This guide explains how to securely manage environment variables for your application across different deployment environments using Vercel.

Setup Process

Setting up environment variables in Vercel involves a few simple steps:

1. Access Project Settings

Navigate to your project in the Vercel dashboard and click on 'Settings'.

2. Environment Variables

Select 'Environment Variables' from the left sidebar to access the variables management interface.

3. Add Variables

Click 'Add New' and enter your key-value pairs. Each variable requires:

  • Name (key)
  • Value
  • Environment selection

4. Configure Environments

For each variable, select which environments should use it:

  • Production: Live application environment
  • Preview: Pull request and branch deployments
  • Development: Local development with Vercel CLI

You can select multiple environments for each variable, or configure different values for each environment.

Required Variables

The following environment variables are required for the application to function properly.

Core Variables

# Database Connection
DATABASE_URL="postgres://username:password@host:port/database"
 
# Authentication
BETTER_AUTH_URL="https://your-domain.com"
BETTER_AUTH_SECRET="your-secret-key"
 
# Email Service
RESEND_API_KEY="re_123456789"
 
# AWS S3
AWS_ACCESS_KEY_ID="your-access-key"
AWS_SECRET_ACCESS_KEY="your-secret-key"
AWS_REGION="your-region"
S3_UPLOAD_BUCKET="your-bucket-name"
 
# Stripe
STRIPE_SECRET_KEY="sk_live_123456789"
STRIPE_WEBHOOK_SECRET="whsec_123456789"
 
# Redis
UPSTASH_REDIS_REST_URL="your-redis-url"
UPSTASH_REDIS_REST_TOKEN="your-redis-token"

Variable Descriptions

Database

DATABASE_URL: Connection string for your PostgreSQL database

Authentication

BETTER_AUTH_URL: Your application's URL for authentication callbacks


BETTER_AUTH_SECRET: Secret key for JWT token signing and verification

Email

RESEND_API_KEY: API key for Resend email service

Storage

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION: AWS credentials


S3_UPLOAD_BUCKET: S3 bucket name for file uploads

Payments

STRIPE_SECRET_KEY: Stripe secret API key


STRIPE_WEBHOOK_SECRET: Secret for validating Stripe webhook events

Caching

UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN: Upstash Redis credentials

Environment Configuration

Different environments require different configurations to ensure proper isolation and security.

Production Environment

The production environment represents your live application:

  • Use production API keys (Stripe live keys, etc.)
  • Configure live database credentials
  • Use production URLs for services
  • Implement strict security measures

Production secrets should have the highest level of security and should be accessible only to team members who absolutely need them.

Preview Environment

Preview environments are used for testing pull requests and branch deployments:

  • Use test API credentials where possible (Stripe test keys, etc.)
  • Connect to a staging or test database
  • Configure test webhooks for services
  • Enable debug features if needed

Preview environments let you test changes in isolation before merging to your main branch.

Development Environment

For local development:

  • Use development or test credentials
  • Connect to a local or development database
  • Mock external services when appropriate
  • Enable debugging tools

Best Practices

Security Best Practices

Never Commit .env Files

Always add .env* files to .gitignore to prevent accidentally exposing secrets

Use Strong Values

Generate strong, unique values for secrets and API keys

Rotate Secrets

Regularly rotate secrets and API keys, especially when team members leave

Limit Access

Restrict access to production environment variables to essential team members

Organization Best Practices

  1. Use Clear Names: Choose descriptive names following a consistent pattern (e.g., SERVICE_PURPOSE_KEY)
  2. Group Related Variables: Keep related variables together in your configuration
  3. Document All Variables: Maintain documentation on what each variable is used for
  4. Validate Required Variables: Add server-side validation to check for required variables on startup

Local Development

For local development, you'll need to set up environment variables on your machine.

Creating a Local Configuration

  1. Create a .env.local file in your project root
  2. Add your development environment variables
  3. Ensure this file is in your .gitignore

Example .env.local file:

# Database
DATABASE_URL="postgres://localhost:5432/myapp_dev"
 
# Authentication
BETTER_AUTH_URL="http://localhost:3000"
BETTER_AUTH_SECRET="development-secret-key"
 
# Test API keys
STRIPE_SECRET_KEY="sk_test_123456789"
RESEND_API_KEY="re_test_123456789"
 
# AWS S3 (local or development bucket)
AWS_ACCESS_KEY_ID="development-key"
AWS_SECRET_ACCESS_KEY="development-secret"
AWS_REGION="us-east-1"
S3_UPLOAD_BUCKET="dev-uploads"
 
# Redis (local or development instance)
UPSTASH_REDIS_REST_URL="https://your-dev-redis-url"
UPSTASH_REDIS_REST_TOKEN="your-dev-redis-token"

Never commit your .env.local file to version control. Make sure it's listed in your .gitignore file.

Loading Environment Variables

Next.js automatically loads environment variables from .env.local for local development. For variables that should be accessible in the browser, prefix them with NEXT_PUBLIC_:

# Accessible in browser
NEXT_PUBLIC_API_BASE_URL="http://localhost:3000/api"
 
# Server-side only (more secure)
API_SECRET_KEY="your-secret"

Validation and Type Safety

To ensure all required environment variables are present, consider adding validation at application startup:

lib/env.ts
import { z } from "zod";
 
const envSchema = z.object({
  // Database
  DATABASE_URL: z.string().url(),
 
  // Authentication
  BETTER_AUTH_URL: z.string().url(),
  BETTER_AUTH_SECRET: z.string().min(32),
 
  // Services
  RESEND_API_KEY: z.string().startsWith("re_"),
  STRIPE_SECRET_KEY: z.string().startsWith("sk_"),
 
  // ... other variables
});
 
// Process will exit if validation fails
export const env = envSchema.parse(process.env);

Environment Variables in CI/CD

For GitHub Actions or other CI/CD systems, add your environment variables to the CI secrets:

.github/workflows/ci.yml
name: CI
 
jobs:
  test:
    runs-on: ubuntu-latest
    env:
      DATABASE_URL: ${{ secrets.DATABASE_URL }}
      BETTER_AUTH_SECRET: ${{ secrets.BETTER_AUTH_SECRET }}
      # ... other environment variables
    steps:
      - uses: actions/checkout@v3
      - name: Run tests
        run: npm test

Troubleshooting

If your application isn't working as expected, environment variables are often the culprit.

Common issues:

  1. Missing Variables: Check if all required variables are set
  2. Invalid Values: Verify the format and content of your variables
  3. Environment Mismatch: Ensure you're using the correct variables for each environment
  4. Casing Issues: Environment variable names are case-sensitive
  5. Quoting Problems: Make sure values with special characters are properly quoted

Additional Resources