Files
flyer-crawler.projectium.com/docs/getting-started/ENVIRONMENT.md

9.7 KiB

Environment Variables Reference

Complete guide to environment variables used in Flyer Crawler.

Configuration by Environment

Production

Location: Gitea CI/CD secrets injected during deployment Path: /var/www/flyer-crawler.projectium.com/ Note: No .env file exists - all variables come from CI/CD

Test

Location: Gitea CI/CD secrets + .env.test file Path: /var/www/flyer-crawler-test.projectium.com/ Note: .env.test overrides for test-specific values

Development Container

Location: .env.local file in project root Note: Overrides default DSNs in compose.dev.yml

Required Variables

Database

Variable Description Example
DB_HOST PostgreSQL host localhost (dev), projectium.com (prod)
DB_PORT PostgreSQL port 5432
DB_USER_PROD Production database user flyer_crawler_prod
DB_PASSWORD_PROD Production database password (secret)
DB_DATABASE_PROD Production database name flyer-crawler-prod
DB_USER_TEST Test database user flyer_crawler_test
DB_PASSWORD_TEST Test database password (secret)
DB_DATABASE_TEST Test database name flyer-crawler-test
DB_USER Dev database user postgres
DB_PASSWORD Dev database password postgres
DB_NAME Dev database name flyer_crawler_dev

Note: Production and test use separate _PROD and _TEST suffixed variables. Development uses unsuffixed variables.

Redis

Variable Description Example
REDIS_URL Redis connection URL redis://localhost:6379 (dev)
REDIS_PASSWORD_PROD Production Redis password (secret)
REDIS_PASSWORD_TEST Test Redis password (secret)

Authentication

Variable Description Example
JWT_SECRET JWT token signing key (minimum 32 characters)
SESSION_SECRET Session encryption key (minimum 32 characters)
GOOGLE_CLIENT_ID Google OAuth client ID xxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET Google OAuth client secret (secret)
GH_CLIENT_ID GitHub OAuth client ID xxx
GH_CLIENT_SECRET GitHub OAuth client secret (secret)

AI Services

Variable Description Example
VITE_GOOGLE_GENAI_API_KEY Google Gemini API key (prod) AIzaSy...
VITE_GOOGLE_GENAI_API_KEY_TEST Google Gemini API key (test) AIzaSy...
GOOGLE_MAPS_API_KEY Google Maps Geocoding API AIzaSy...

Application

Variable Description Example
NODE_ENV Environment mode development, test, production
PORT Backend server port 3001
FRONTEND_URL Frontend application URL http://localhost:5173 (dev)

Error Tracking

Variable Description Example
SENTRY_DSN Sentry DSN (production) https://xxx@sentry.io/xxx
VITE_SENTRY_DSN Frontend Sentry DSN (production) https://xxx@sentry.io/xxx
SENTRY_DSN_TEST Sentry DSN (test) https://xxx@sentry.io/xxx
VITE_SENTRY_DSN_TEST Frontend Sentry DSN (test) https://xxx@sentry.io/xxx
SENTRY_AUTH_TOKEN Sentry API token for releases (secret)

Optional Variables

Variable Description Default
LOG_LEVEL Logging verbosity info
REDIS_TTL Cache TTL in seconds 3600
MAX_UPLOAD_SIZE Max file upload size 10mb
RATE_LIMIT_WINDOW Rate limit window (ms) 900000 (15 min)
RATE_LIMIT_MAX Max requests per window 100

Configuration Files

File Purpose
src/config/env.ts Zod schema validation - source of truth
ecosystem.config.cjs PM2 process manager config
.gitea/workflows/deploy-to-prod.yml Production deployment workflow
.gitea/workflows/deploy-to-test.yml Test deployment workflow
.env.example Template with all variables
.env.local Dev container overrides (not in git)
.env.test Test environment overrides (not in git)

Adding New Variables

1. Update Zod Schema

Edit src/config/env.ts:

const envSchema = z.object({
  // ... existing variables ...
  NEW_VARIABLE: z.string().min(1),
});

2. Add to Gitea Secrets

For prod/test environments:

  1. Go to Gitea repository Settings > Secrets
  2. Add NEW_VARIABLE with value
  3. Add NEW_VARIABLE_TEST if test needs different value

3. Update Deployment Workflows

Edit .gitea/workflows/deploy-to-prod.yml:

env:
  NEW_VARIABLE: ${{ secrets.NEW_VARIABLE }}

Edit .gitea/workflows/deploy-to-test.yml:

env:
  NEW_VARIABLE: ${{ secrets.NEW_VARIABLE_TEST }}

4. Update PM2 Config

Edit ecosystem.config.cjs:

module.exports = {
  apps: [
    {
      env: {
        NEW_VARIABLE: process.env.NEW_VARIABLE,
      },
    },
  ],
};

5. Update Documentation

  • Add to .env.example
  • Update this document
  • Document in relevant feature docs

Security Best Practices

Secrets Management

  • NEVER commit secrets to git
  • Use Gitea Secrets for prod/test
  • Use .env.local for dev (gitignored)
  • Rotate secrets regularly

Secret Generation

# Generate secure random secrets
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Database Users

Each environment has its own PostgreSQL user:

Environment User Database
Production flyer_crawler_prod flyer-crawler-prod
Test flyer_crawler_test flyer-crawler-test
Development postgres flyer_crawler_dev

Setup Commands (as postgres superuser):

-- Production
CREATE DATABASE "flyer-crawler-prod";
CREATE USER flyer_crawler_prod WITH PASSWORD 'secure-password';
ALTER DATABASE "flyer-crawler-prod" OWNER TO flyer_crawler_prod;
\c "flyer-crawler-prod"
ALTER SCHEMA public OWNER TO flyer_crawler_prod;
GRANT CREATE, USAGE ON SCHEMA public TO flyer_crawler_prod;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE EXTENSION IF NOT EXISTS pg_trgm;

-- Test (similar commands with _test suffix)

Validation

Environment variables are validated at startup via src/config/env.ts. If validation fails:

  1. Check the error message for missing/invalid variables
  2. Verify .env.local (dev) or Gitea Secrets (prod/test)
  3. Ensure values match schema requirements (min length, format, etc.)

Troubleshooting

Variable Not Found

Error: Missing required environment variable: JWT_SECRET

Solution: Add the variable to your environment configuration.

Invalid Value

Error: JWT_SECRET must be at least 32 characters

Solution: Generate a longer secret value.

Wrong Environment Selected

Check NODE_ENV is set correctly:

  • development - Local dev container
  • test - CI/CD test server
  • production - Production server

Database Connection Issues

Verify database credentials:

# Development
podman exec flyer-crawler-postgres psql -U postgres -d flyer_crawler_dev -c "SELECT 1;"

# Production (via SSH)
ssh root@projectium.com "psql -U flyer_crawler_prod -d flyer-crawler-prod -c 'SELECT 1;'"

Reference

See Also