Environment Variables Documentation¶
This document describes all environment variables used in the AzharStore Medusa backend.
Overview¶
Environment variables are used to configure the application without modifying code. They should be stored in a .env file in the project root and never committed to version control.
Getting Started¶
-
Copy the example environment file:
-
Edit
.envwith your values -
Never commit
.envto version control
Environment Variables¶
Database Configuration¶
DATABASE_URL¶
Description: PostgreSQL connection string for the Medusa database.
Format: postgresql://[user]:[password]@[host]:[port]/[database]
Example: postgresql://postgres:postgres@localhost:5432/medusa
Required: Yes
Notes: - Use strong password in production - Use PostgreSQL 16 or later - Database must exist before starting
Redis Configuration¶
REDIS_URL¶
Description: Redis connection string for event bus and caching.
Format: redis://[host]:[port]
Example: redis://localhost:6379
Required: Yes
Notes: - Use Redis 7 or later - Can use Redis Cloud for production
CORS Configuration¶
STORE_CORS¶
Description: Allowed origins for store API requests.
Format: Comma-separated list of URLs
Example: http://localhost:3000,https://azhar.store
Required: Yes
Notes: - Include all frontend URLs - No trailing slashes - Include protocol (http/https)
ADMIN_CORS¶
Description: Allowed origins for admin API requests.
Format: Comma-separated list of URLs
Example: http://localhost:9000,https://admin.azhar.store
Required: Yes
Notes: - Include all admin dashboard URLs - No trailing slashes - Include protocol (http/https)
Authentication Secrets¶
JWT_SECRET¶
Description: Secret key for signing JWT tokens.
Format: Random string (recommended 32+ characters)
Example: your-super-secret-jwt-key-change-this
Required: Yes
Security: High - Keep secret, rotate regularly
Notes: - Use strong random string - Different from COOKIE_SECRET - Rotate periodically
COOKIE_SECRET¶
Description: Secret key for signing session cookies.
Format: Random string (recommended 32+ characters)
Example: your-super-secret-cookie-key-change-this
Required: Yes
Security: High - Keep secret, rotate regularly
Notes: - Use strong random string - Different from JWT_SECRET - Rotate periodically
Admin Configuration¶
ADMIN_EMAIL¶
Description: Email address for the initial admin user.
Format: Valid email address
Example: admin@azhar.store
Required: Yes
Notes: - Used by seed-admin script - Can be changed later via admin UI
ADMIN_PASSWORD¶
Description: Password for the initial admin user.
Format: String (minimum 8 characters recommended)
Example: your-secure-password
Required: Yes
Security: High - Keep secret, change after first login
Notes: - Used by seed-admin script - Change immediately after first login - Use strong password
Supabase Configuration (Migration Only)¶
SUPABASE_URL¶
Description: Supabase project URL for data migration.
Format: Supabase project URL
Example: https://your-project.supabase.co
Required: Only for data migration
Security: Medium - Keep secret
Notes: - Only needed when migrating from Supabase - Can be removed after migration
SUPABASE_SERVICE_KEY¶
Description: Supabase service role key for data migration.
Format: Supabase service role key
Example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Required: Only for data migration
Security: High - Keep secret, rotate regularly
Notes: - Only needed when migrating from Supabase - Has full database access - Can be removed after migration
Frontend Configuration¶
VITE_API_BASE_URL¶
Description: API base URL for frontend requests.
Format: Full URL with path
Example: http://localhost:9000/store (development) or https://api.azhar.store/store (production)
Required: No (defaults to localhost:9000/store)
Notes:
- Set in frontend/store/.env
- Must include /store path
- Use HTTPS in production
Example .env File¶
# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/medusa
# Redis
REDIS_URL=redis://localhost:6379
# CORS
STORE_CORS=http://localhost:3000,https://azhar.store
ADMIN_CORS=http://localhost:9000,https://admin.azhar.store
# Secrets
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
COOKIE_SECRET=your-super-secret-cookie-key-change-this-in-production
# Admin
ADMIN_EMAIL=admin@azhar.store
ADMIN_PASSWORD=your-secure-password-change-this
# Supabase (Migration Only)
# SUPABASE_URL=https://your-project.supabase.co
# SUPABASE_SERVICE_KEY=your-service-role-key
Security Best Practices¶
1. Never Commit .env Files¶
Add .env to .gitignore:
2. Use Strong Secrets¶
Generate secure secrets:
3. Rotate Secrets Regularly¶
Change secrets periodically: - Every 90 days for production - After any suspected breach - When team members leave
4. Use Different Secrets per Environment¶
Use different secrets for: - Development - Staging - Production
5. Limit Access¶
Restrict access to .env files:
- File permissions: chmod 600 .env
- Only necessary team members
- Use secret management in production
6. Validate Variables¶
Validate required variables on startup:
const requiredVars = ['DATABASE_URL', 'REDIS_URL', 'JWT_SECRET', 'COOKIE_SECRET']
requiredVars.forEach(var => {
if (!process.env[var]) {
throw new Error(`Missing required environment variable: ${var}`)
}
})
Production Considerations¶
Use Secret Management¶
In production, use a secret management solution: - AWS Secrets Manager - HashiCorp Vault - Google Secret Manager - Azure Key Vault
Environment-Specific Files¶
Use different files for different environments:
- .env.development - Local development
- .env.staging - Staging environment
- .env.production - Production environment
Load appropriate file:
# Development
cp .env.development .env
# Staging
cp .env.staging .env
# Production
cp .env.production .env
Docker Secrets¶
For Docker deployments, use Docker secrets:
services:
medusa:
secrets:
- jwt_secret
- cookie_secret
secrets:
jwt_secret:
file: ./secrets/jwt_secret.txt
cookie_secret:
file: ./secrets/cookie_secret.txt
Troubleshooting¶
Missing Environment Variable¶
Error: Missing required environment variable: DATABASE_URL
Solution: Add the missing variable to .env file
Invalid Database URL¶
Error: Invalid connection string
Solution: Verify DATABASE_URL format: postgresql://user:password@host:port/database
CORS Errors¶
Error: CORS policy blocked request
Solution: Add your frontend URL to STORE_CORS and ADMIN_CORS
Authentication Failures¶
Error: Invalid JWT token
Solution: Verify JWT_SECRET matches between backend and any external services
Redis Connection Failed¶
Error: ECONNREFUSED redis://localhost:6379
Solution: Verify Redis is running and REDIS_URL is correct
Variable Reference Table¶
| Variable | Required | Default | Description |
|---|---|---|---|
| DATABASE_URL | Yes | - | PostgreSQL connection string |
| REDIS_URL | Yes | - | Redis connection string |
| STORE_CORS | Yes | - | Store CORS origins |
| ADMIN_CORS | Yes | - | Admin CORS origins |
| JWT_SECRET | Yes | - | JWT signing secret |
| COOKIE_SECRET | Yes | - | Cookie signing secret |
| ADMIN_EMAIL | Yes | - | Admin email address |
| ADMIN_PASSWORD | Yes | - | Admin password |
| SUPABASE_URL | No* | - | Supabase project URL |
| SUPABASE_SERVICE_KEY | No* | - | Supabase service key |
| VITE_API_BASE_URL | No | http://localhost:9000/store | Frontend API base URL |
*Required only for data migration