> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Ishaq74/concordia/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment Variables

> Complete reference for all environment variables required to run Concordia

Concordia requires several environment variables for database connections, authentication, email, and API configuration.

## Setup

Create a `.env` file in the root directory:

```bash theme={null}
cp .env.example .env
```

Then configure the variables according to your environment.

## Database Configuration

<ParamField path="USE_DB_TEST" type="boolean" default="false">
  Controls which database to use during development:

  * `true` - Use test database (`DATABASE_URL_TEST`)
  * `false` - Use local or production database

  ```bash theme={null}
  USE_DB_TEST=true
  ```
</ParamField>

<ParamField path="USE_PROD_DB" type="boolean" default="false">
  Whether to connect to the production database:

  * `true` - Use production database (`DATABASE_URL_PROD`)
  * `false` - Use local or test database

  ```bash theme={null}
  USE_PROD_DB=false
  ```

  <Warning>
    Never set `USE_PROD_DB=true` in development unless you know what you're doing.
  </Warning>
</ParamField>

<ParamField path="DATABASE_URL_LOCAL" type="string" required>
  PostgreSQL connection string for local development database.

  **Format:**

  ```
  postgresql://username:password@localhost:port/database_name
  ```

  **Example:**

  ```bash theme={null}
  DATABASE_URL_LOCAL=postgresql://concordia:secret@localhost:5432/concordia_dev
  ```
</ParamField>

<ParamField path="DATABASE_URL_TEST" type="string" required>
  PostgreSQL connection string for test database used during automated testing.

  **Format:**

  ```
  postgresql://username:password@localhost:port/database_name_test
  ```

  **Example:**

  ```bash theme={null}
  DATABASE_URL_TEST=postgresql://concordia:secret@localhost:5432/concordia_test
  ```
</ParamField>

<ParamField path="DATABASE_URL_PROD" type="string" required>
  PostgreSQL connection string for production database.

  **Format (Neon):**

  ```
  postgresql://username:password@host.neon.tech/database?sslmode=require&channel_binding=require
  ```

  **Example:**

  ```bash theme={null}
  DATABASE_URL_PROD=postgresql://neondb_owner:abc123xyz@ep-cool-forest-123456.us-east-2.aws.neon.tech/neondb?sslmode=require&channel_binding=require
  ```

  <Warning>
    Always use SSL (`sslmode=require`) for production database connections.
  </Warning>
</ParamField>

## Authentication Configuration

<ParamField path="BETTER_AUTH_SECRET" type="string" required>
  Secret key used to sign JWT tokens and secure sessions. Must be a strong random string.

  **Generation:**

  ```bash theme={null}
  openssl rand -base64 32
  ```

  **Example:**

  ```bash theme={null}
  BETTER_AUTH_SECRET=8TxJZ5K3m9qLp2Hn7YvR4wG6fU1sD0aB
  ```

  <Warning>
    Never commit this secret to version control. Generate a unique value for each environment.
  </Warning>
</ParamField>

<ParamField path="BETTER_AUTH_URL" type="string" required>
  The base URL where your application is accessible. Used for generating callback URLs and verification links.

  **Development:**

  ```bash theme={null}
  BETTER_AUTH_URL=http://localhost:4321
  ```

  **Production:**

  ```bash theme={null}
  BETTER_AUTH_URL=https://concordia.example.com
  ```

  <Note>
    Do not include a trailing slash.
  </Note>
</ParamField>

## SMTP Email Configuration

Concordia uses SMTP for sending transactional emails (verification, password reset, notifications).

<ParamField path="SMTP_PROVIDER" type="string" required>
  The name of your SMTP provider. Common values:

  * `gmail`
  * `sendgrid`
  * `mailgun`
  * `custom`

  ```bash theme={null}
  SMTP_PROVIDER=gmail
  ```
</ParamField>

<ParamField path="SMTP_USER" type="string" required>
  The email address or username for SMTP authentication.

  ```bash theme={null}
  SMTP_USER=contact@example.com
  ```
</ParamField>

<ParamField path="SMTP_PASS" type="string" required>
  The password or app-specific password for SMTP authentication.

  ```bash theme={null}
  SMTP_PASS=your_password_here
  ```

  <Warning>
    For Gmail, use an [App Password](https://support.google.com/accounts/answer/185833) instead of your account password.
  </Warning>
</ParamField>

<ParamField path="SMTP_FROM" type="string" required>
  The "From" email address used in outgoing emails.

  ```bash theme={null}
  SMTP_FROM=noreply@concordia.example.com
  ```
</ParamField>

### Optional SMTP Configuration

<ParamField path="SMTP_HOST" type="string">
  Custom SMTP server hostname. If not set, automatically determined from `SMTP_PROVIDER`.

  ```bash theme={null}
  SMTP_HOST=smtp.gmail.com
  ```
</ParamField>

<ParamField path="SMTP_PORT" type="number" default="587">
  SMTP server port. Common values:

  * `587` - TLS (recommended)
  * `465` - SSL
  * `25` - Unencrypted (not recommended)

  ```bash theme={null}
  SMTP_PORT=587
  ```
</ParamField>

<ParamField path="SMTP_SECURE" type="boolean" default="false">
  Whether to use SSL/TLS:

  * `true` - Use SSL (port 465)
  * `false` - Use STARTTLS (port 587)

  ```bash theme={null}
  SMTP_SECURE=false
  ```
</ParamField>

<ParamField path="SMTP_POOL" type="boolean" default="true">
  Whether to use connection pooling for better performance.

  ```bash theme={null}
  SMTP_POOL=true
  ```
</ParamField>

<ParamField path="SMTP_MAX_CONNECTIONS" type="number" default="5">
  Maximum number of simultaneous SMTP connections in the pool.

  ```bash theme={null}
  SMTP_MAX_CONNECTIONS=5
  ```
</ParamField>

<ParamField path="SMTP_RATE_DELTA" type="number" default="1000">
  Time window in milliseconds for rate limiting.

  ```bash theme={null}
  SMTP_RATE_DELTA=1000
  ```
</ParamField>

<ParamField path="SMTP_RATE_LIMIT" type="number" default="5">
  Maximum number of emails to send within the rate limit window.

  ```bash theme={null}
  SMTP_RATE_LIMIT=5
  ```
</ParamField>

## Alternative Email Provider: Resend

As an alternative to SMTP, you can use [Resend](https://resend.com) for email delivery:

<ParamField path="RESEND_API_KEY" type="string">
  API key from your Resend account. When set, Resend will be used instead of SMTP.

  ```bash theme={null}
  RESEND_API_KEY=re_123456789abcdefghijklmnop
  ```

  <Info>
    To use Resend, comment out or remove SMTP variables and set only `RESEND_API_KEY`.
  </Info>
</ParamField>

## Application Configuration

<ParamField path="NODE_ENV" type="string" default="development">
  The environment mode for Node.js. Affects logging, error handling, and optimizations.

  **Valid values:**

  * `development` - Development mode with verbose logging
  * `production` - Production mode with optimizations
  * `test` - Test mode for automated testing

  ```bash theme={null}
  NODE_ENV=development
  ```
</ParamField>

<ParamField path="PUBLIC_API_URL" type="string">
  Public-facing API URL used by client-side code. Must be accessible from the browser.

  **Development:**

  ```bash theme={null}
  PUBLIC_API_URL=http://localhost:4321/api
  ```

  **Production:**

  ```bash theme={null}
  PUBLIC_API_URL=https://concordia.example.com/api
  ```

  <Note>
    Variables prefixed with `PUBLIC_` are exposed to client-side code. Never put secrets in `PUBLIC_` variables.
  </Note>
</ParamField>

## Complete Example Configuration

Here's a complete `.env` file template with all variables:

```bash .env theme={null}
# Database Selection
USE_DB_TEST=true
USE_PROD_DB=false

# Database URLs
DATABASE_URL_LOCAL=postgresql://concordia:dev_password@localhost:5432/concordia_dev
DATABASE_URL_TEST=postgresql://concordia:test_password@localhost:5432/concordia_test
DATABASE_URL_PROD=postgresql://user:pass@host.neon.tech/db?sslmode=require&channel_binding=require

# Authentication
BETTER_AUTH_SECRET=8TxJZ5K3m9qLp2Hn7YvR4wG6fU1sD0aB
BETTER_AUTH_URL=http://localhost:4321

# SMTP Configuration (Primary)
SMTP_PROVIDER=gmail
SMTP_USER=contact@example.com
SMTP_PASS=your_app_password
SMTP_FROM=noreply@example.com

# Optional: SMTP Overrides
# SMTP_HOST=smtp.gmail.com
# SMTP_PORT=587
# SMTP_SECURE=false
# SMTP_POOL=true
# SMTP_MAX_CONNECTIONS=5
# SMTP_RATE_DELTA=1000
# SMTP_RATE_LIMIT=5

# Alternative: Resend API (Comment out SMTP if using this)
# RESEND_API_KEY=re_123456789abcdefghijklmnop

# Application
NODE_ENV=development
PUBLIC_API_URL=http://localhost:4321/api
```

## Testing Your Configuration

### Test Database Connection

```bash theme={null}
npm run db:check
```

### Test SMTP Configuration

```bash theme={null}
npm run smtp:check
```

This will attempt to send a test email and report any configuration issues.

## Environment-Specific Files

<Tabs>
  <Tab title="Development">
    Create `.env.development`:

    ```bash theme={null}
    USE_DB_TEST=true
    USE_PROD_DB=false
    DATABASE_URL_LOCAL=postgresql://localhost:5432/concordia_dev
    BETTER_AUTH_URL=http://localhost:4321
    NODE_ENV=development
    PUBLIC_API_URL=http://localhost:4321/api
    ```
  </Tab>

  <Tab title="Production">
    Create `.env.production`:

    ```bash theme={null}
    USE_DB_TEST=false
    USE_PROD_DB=true
    DATABASE_URL_PROD=postgresql://[secure-connection-string]
    BETTER_AUTH_SECRET=[generate-new-secret]
    BETTER_AUTH_URL=https://concordia.example.com
    NODE_ENV=production
    PUBLIC_API_URL=https://concordia.example.com/api
    ```

    <Warning>
      Never commit production `.env` files to version control. Use your hosting platform's environment variable management.
    </Warning>
  </Tab>

  <Tab title="Testing">
    Create `.env.test`:

    ```bash theme={null}
    USE_DB_TEST=true
    USE_PROD_DB=false
    DATABASE_URL_TEST=postgresql://localhost:5432/concordia_test
    BETTER_AUTH_SECRET=test-secret-key
    BETTER_AUTH_URL=http://localhost:4321
    NODE_ENV=test
    PUBLIC_API_URL=http://localhost:4321/api
    ```
  </Tab>
</Tabs>

## Security Best Practices

<AccordionGroup>
  <Accordion title="Never Commit Secrets">
    Add `.env*` to your `.gitignore`:

    ```gitignore .gitignore theme={null}
    .env
    .env.local
    .env.production
    .env.development
    .env.test
    ```
  </Accordion>

  <Accordion title="Generate Strong Secrets">
    Use cryptographically secure random values:

    ```bash theme={null}
    # Generate BETTER_AUTH_SECRET
    openssl rand -base64 32

    # Generate alternative secret
    node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
    ```
  </Accordion>

  <Accordion title="Use Different Secrets Per Environment">
    Never reuse the same `BETTER_AUTH_SECRET` across development, staging, and production.
  </Accordion>

  <Accordion title="Rotate Secrets Regularly">
    Change authentication secrets and API keys periodically, especially after:

    * Team member departures
    * Security incidents
    * Suspected compromise
  </Accordion>

  <Accordion title="Limit Database Permissions">
    Use database users with minimal required permissions:

    * Development: Full access to dev database only
    * Production: No DDL permissions, only DML (SELECT, INSERT, UPDATE, DELETE)
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Database Connection Failed">
    **Error:** `Error: connect ECONNREFUSED`

    **Solutions:**

    1. Ensure PostgreSQL is running:
       ```bash theme={null}
       sudo service postgresql status
       ```
    2. Check connection string format
    3. Verify username, password, and database name
    4. Test with `npm run db:check`
  </Accordion>

  <Accordion title="SMTP Authentication Failed">
    **Error:** `Invalid login: 535-5.7.8 Username and Password not accepted`

    **Solutions:**

    1. For Gmail: Use an App Password, not your account password
    2. Check `SMTP_USER` and `SMTP_PASS` are correct
    3. Verify SMTP provider settings
    4. Test with `npm run smtp:check`
  </Accordion>

  <Accordion title="JWT Token Invalid">
    **Error:** `JsonWebTokenError: invalid signature`

    **Solutions:**

    1. Ensure `BETTER_AUTH_SECRET` is set and matches between environments
    2. Check for whitespace or newlines in the secret
    3. Regenerate the secret if corrupted
  </Accordion>

  <Accordion title="Environment Variables Not Loading">
    **Issue:** Variables are undefined at runtime

    **Solutions:**

    1. Ensure `.env` file is in the project root
    2. Restart the development server after changing `.env`
    3. Check for typos in variable names
    4. Verify `dotenv` is configured in `astro.config.mjs`
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Database Setup" icon="database" href="/deployment/database-setup">
    Learn about the database schema and migrations
  </Card>

  <Card title="Authentication" icon="shield" href="/guides/authentication">
    Configure authentication and user management
  </Card>
</CardGroup>
