Skip to content

🔐 Environment Variables Setup Guide

📁 Where to Set Environment Variables

Root .env (for Docker Compose)

Location: .env (project root, same directory as docker-compose.yml)

Used by: - Docker Compose (reads from root directory) - Can be accessed by backend if needed

Required Variables:

# ============================================
# SECURITY - REQUIRED (No Defaults)
# ============================================

# API Key for backend authentication
API_KEY=your_new_secure_api_key_here

# Database Configuration
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your_strong_password_here
POSTGRES_DB=pcbstackup

# ============================================
# APPLICATION CONFIGURATION
# ============================================

# Environment
ENVIRONMENT=development

# Server Port (FastAPI backend — read by backend/main.py, defaults to 8000)
PORT=8000

# ============================================
# DATABASE & CACHE
# ============================================

# Database URL (auto-constructed from POSTGRES_* vars in docker-compose)
# Or set manually if not using docker-compose:
# DATABASE_URL=postgresql://postgres:password@localhost:5432/pcbstackup

REDIS_URL=redis://localhost:6379/0

# ============================================
# SUPABASE AUTHENTICATION
# ============================================

SUPABASE_URL=https://orjmlibnlzkyuauaysye.supabase.co
SUPABASE_JWT_SECRET=your_jwt_secret_here
SUPABASE_SERVICE_KEY=your_service_key_here
SUPABASE_WEBHOOK_SECRET=your_webhook_secret_here

# Frontend Supabase (public keys - safe to expose)
VITE_SUPABASE_URL=https://orjmlibnlzkyuauaysye.supabase.co
VITE_SUPABASE_ANON_KEY=your_anon_key_here

# ============================================
# EXTERNAL APIs
# ============================================

# Nexar API
NEXAR_CLIENT_ID=your_nexar_client_id
NEXAR_CLIENT_SECRET=your_nexar_client_secret

# DigiKey API
DIGIKEY_CLIENT_ID=your_digikey_client_id
DIGIKEY_CLIENT_SECRET=your_digikey_client_secret
ENABLE_DIGIKEY_API=true

# Gemini/Google AI
GEMINI_API_KEY=your_gemini_api_key
GOOGLE_API_KEY=your_google_api_key

# ============================================
# EMAIL SERVICE
# ============================================

# SendGrid
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASSWORD=your_sendgrid_api_key
EMAIL_SERVICE=sendgrid

# Or MailerSend
# EMAIL_SERVICE=mailersend
# SMTP_HOST=smtp.mailersend.com
# SMTP_PORT=587
# SMTP_USER=your_mailersend_user
# SMTP_PASSWORD=your_mailersend_password

# ============================================
# CORS & SECURITY
# ============================================

# CORS Origins (comma-separated)
CORS_ORIGINS=http://localhost:5180,http://localhost:3000

# Trusted Hosts
TRUSTED_HOSTS=localhost,127.0.0.1,pcbgenerator.com,www.pcbgenerator.com

# HTTPS (set to true in production)
FORCE_HTTPS=false

# ============================================
# LOGGING
# ============================================

LOG_LEVEL=DEBUG

# ============================================
# FRONTEND CONFIGURATION
# ============================================

# API URLs
VITE_API_URL=http://localhost:8000
VITE_FASTAPI_URL=http://localhost:8000
VITE_API_KEY=your_api_key_here

# ============================================
# OLLAMA (Local AI)
# ============================================

OLLAMA_URL=http://localhost:11434
DEFAULT_MODEL=mistral:latest


backend/.env (for local backend development)

Location: backend/.env

Used by: - Backend Python code when running locally (not in Docker) - backend/main.py loads the root .env first, then backend/.env as a legacy fallback (lines 34-35; first call wins — root .env values are not overridden)

When to use: - Running backend locally with python backend/main.py - Not using Docker Compose - Need backend-specific overrides

Template:

# ============================================
# Backend Local Development Overrides
# ============================================
# 
# These override root .env when running backend locally
# Most variables should be in root .env for consistency
# Only add backend-specific overrides here

# Example: Override database connection for local testing
# DATABASE_URL=postgresql://postgres:password@localhost:5432/pcbstackup

# Example: Override API key for local development
# API_KEY=local_dev_key_123

Note: If you're using Docker Compose, you don't need backend/.env - root .env is sufficient.


Frontend (VITE_*) variables — root .env only

Location: root .env (NOT frontend/.env)

Vite loads VITE_* variables from the repo-root .env — this is configured via envDir: rootDir in frontend/vite.config.ts. A frontend/.env file is ignored at runtime and is deleted by start-all-servers-windowed.ps1 on every run, so never put variables there.

Required Variables (in root .env):

# ============================================
# Frontend Environment Variables
# ============================================
# Note: Vite requires VITE_ prefix for client-side variables

# Supabase (public keys - safe to expose)
VITE_SUPABASE_URL=https://orjmlibnlzkyuauaysye.supabase.co
VITE_SUPABASE_ANON_KEY=your_anon_key_here

# API Configuration
VITE_API_URL=http://localhost:8000
VITE_FASTAPI_URL=http://localhost:8000
VITE_API_KEY=your_api_key_here

After editing the root .env, fully restart Vite — HMR does not re-read env variables.


🔄 Variable Priority (How They're Loaded)

When Using Docker Compose:

  1. Root .env → Read by Docker Compose
  2. Docker Compose passes variables to containers via environment: section
  3. Backend container receives variables as environment variables
  4. backend/main.py can also load backend/.env as fallback

When Running Backend Locally (No Docker):

  1. System environment variables (already-set vars are never overridden by .env files)
  2. Root .env → Loaded first by backend/main.py (lines 34-35)
  3. backend/.env → Loaded second as a legacy fallback (first call wins, so it cannot override root .env)

✅ Quick Setup Checklist

For Docker Compose Setup:

  • Create/update root .env with all required variables
  • Set API_KEY (generate new secure key)
  • Set POSTGRES_PASSWORD (strong password)
  • Set POSTGRES_USER (default: postgres)
  • Set POSTGRES_DB (default: pcbstackup)
  • Set Supabase keys (VITE_SUPABASE_ANON_KEY, etc.)
  • Set external API keys (Nexar, DigiKey, etc.)
  • Verify .env is in .gitignore ✅ (already done)

For Local Development (No Docker):

  • Put all variables (backend + VITE_*) in the root .env — the backend loads it (main.py lines 34-35) and Vite reads it via envDir
  • Do NOT create frontend/.env — Vite ignores it and the start script deletes it
  • Optionally use backend/.env only for legacy backend-specific overrides (root .env values win)

🔒 Security Best Practices

  1. Never commit .env files ✅ (already in .gitignore)
  2. Use different keys for dev/prod:
  3. Development: Use test keys or local values
  4. Production: Use real, secure keys
  5. Rotate exposed secrets:
  6. After security fixes, generate new API keys
  7. Change database passwords
  8. Use strong passwords:
  9. Database passwords: 20+ characters, mixed case, numbers, symbols
  10. API keys: Use secure random generators

📝 Example: Setting Up After Security Fix

After removing hardcoded secrets from docker-compose.yml, add to root .env:

# Generate new secure API key (use: openssl rand -base64 32)
API_KEY=NEW_SECURE_KEY_HERE_GENERATE_ONE

# Strong database password
POSTGRES_USER=postgres
POSTGRES_PASSWORD=StrongPassword123!@#ChangeThis
POSTGRES_DB=pcbstackup

Then test:

# Verify docker-compose can read them
docker-compose config

# Should show your values (not errors about missing vars)


🆘 Troubleshooting

Issue: "API_KEY not set" error

Solution: Add API_KEY=... to root .env

Issue: Database connection fails

Solution: 1. Check POSTGRES_PASSWORD is set in root .env 2. Verify password matches what's in database 3. Check DATABASE_URL is correct

Issue: Frontend can't connect to backend

Solution: 1. Check VITE_API_URL in the root .env (Vite does not read frontend/.env) 2. Verify backend is running on that URL 3. Check CORS settings

Issue: Variables not loading

Solution: 1. Verify .env file is in correct location 2. Check file has no syntax errors (no spaces around =) 3. Restart services after changing .env 4. For Docker: Rebuild containers if needed


📚 Reference: Which File for What

Variable Root .env backend/.env Notes
API_KEY Docker uses root, local uses backend
POSTGRES_* Docker uses root
DATABASE_URL Auto-built in docker-compose
SUPABASE_* Frontend needs VITE_ prefix
VITE_* Frontend variables — root .env only (Vite envDir); frontend/.env is ignored
NEXAR_* Backend only
DIGIKEY_* Backend only
GEMINI_API_KEY Backend only
SMTP_* Backend only

💡 Recommendation

For simplicity, use root .env for everything: - Docker Compose reads it automatically - Backend loads it explicitly (backend/main.py lines 34-35) - Frontend (Vite) reads it automatically (envDir: rootDir in frontend/vite.config.ts) - Single source of truth - Easier to manage

Only use backend/.env if: - You need different values for local vs Docker - You're running services separately (not with docker-compose) - You need environment-specific overrides (note: root .env values load first and win)

Never use frontend/.env — Vite ignores it at runtime and start-all-servers-windowed.ps1 deletes it on every run.