Skip to content

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

  1. Copy the example environment file:

    cp .env.example .env
    

  2. Edit .env with your values

  3. Never commit .env to 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

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:

.env
.env.local
.env.*.local

2. Use Strong Secrets

Generate secure secrets:

# Generate JWT secret
openssl rand -base64 32

# Generate cookie secret
openssl rand -base64 32

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

Additional Resources