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

# Configuration

> Learn how to configure your self-hosted Screenshothis instance with all available options.

# Configuration guide

Configure your self-hosted Screenshothis instance with the right environment variables and settings for your deployment. This guide covers everything from basic setup to advanced production configurations.

<Note>
  **Always check the source**: Refer to the [Screenshothis repository](https://github.com/screenshothis/screenshothis) `.env.example` files for the most up-to-date configuration options. This guide is based on the actual environment variables used in the codebase.
</Note>

## Quick configuration

Start with this minimal setup and expand as needed:

<Steps>
  <Step title="Set up database connection">
    Configure PostgreSQL connection details in your `apps/server/.env` file.
  </Step>

  <Step title="Configure storage">
    Set up S3-compatible storage credentials for screenshot storage.
  </Step>

  <Step title="Add authentication secrets">
    Generate secure secrets for user authentication and API keys.
  </Step>

  <Step title="Customize performance settings">
    Adjust rate limits, timeouts, and screenshot quality settings.
  </Step>
</Steps>

## Database configuration

Configure your PostgreSQL database connection:

<ParamField path="DATABASE_URL" type="string" required>
  Complete PostgreSQL connection string. This is the primary database configuration.

  ```bash theme={null}
  # Format: postgresql://username:password@host:port/database
  DATABASE_URL=postgresql://screenshothis:password@localhost:5432/screenshothis
  ```
</ParamField>

<ParamField path="DATABASE_HOST" type="string" required>
  Database server hostname or IP address.

  ```bash theme={null}
  DATABASE_HOST=localhost  # Development
  DATABASE_HOST=prod-db.example.com  # Production
  ```
</ParamField>

<ParamField path="DATABASE_PORT" type="integer" default="5432">
  PostgreSQL server port.
</ParamField>

<ParamField path="DATABASE_NAME" type="string" required>
  Name of the Screenshothis database.

  ```bash theme={null}
  DATABASE_NAME=screenshothis
  ```
</ParamField>

<ParamField path="DATABASE_USER" type="string" required>
  Database username for connections.
</ParamField>

<ParamField path="DATABASE_PASSWORD" type="string" required>
  Database password for the specified user.
</ParamField>

<Tabs>
  <Tab title="Development">
    ```bash theme={null}
    DATABASE_URL=postgresql://screenshothis:password@localhost:5432/screenshothis
    DATABASE_HOST=localhost
    DATABASE_PORT=5432
    DATABASE_NAME=screenshothis
    DATABASE_USER=screenshothis
    DATABASE_PASSWORD=password
    ```
  </Tab>

  <Tab title="Production">
    ```bash theme={null}
    DATABASE_URL=postgresql://user:secure_pass@prod-db.example.com:5432/screenshothis
    DATABASE_HOST=prod-db.example.com
    DATABASE_PORT=5432
    DATABASE_NAME=screenshothis
    DATABASE_USER=production_user
    DATABASE_PASSWORD=secure_production_password
    ```
  </Tab>
</Tabs>

## Redis configuration

Configure Redis for caching and session management:

<ParamField path="REDIS_URL" type="string" required>
  Complete Redis connection string. This is the primary Redis configuration.

  ```bash theme={null}
  # Development
  REDIS_URL=redis://localhost:6379

  # Production with authentication
  REDIS_URL=redis://user:password@prod-redis.example.com:6379
  ```
</ParamField>

<ParamField path="REDIS_HOST" type="string" default="localhost">
  Redis server hostname (optional if using REDIS\_URL).
</ParamField>

<ParamField path="REDIS_PORT" type="integer" default="6379">
  Redis server port (optional if using REDIS\_URL).
</ParamField>

<ParamField path="REDIS_PASSWORD" type="string">
  Redis password if authentication is required.
</ParamField>

## S3-compatible storage

Configure storage for screenshots using any S3-compatible service:

<ParamField path="AWS_ACCESS_KEY_ID" type="string" required>
  Access key ID for your S3-compatible storage service.
</ParamField>

<ParamField path="AWS_SECRET_ACCESS_KEY" type="string" required>
  Secret access key for your S3-compatible storage service.
</ParamField>

<ParamField path="AWS_REGION" type="string" required>
  Storage region. Use `auto` for Cloudflare R2, or the appropriate region for your service.
</ParamField>

<ParamField path="AWS_BUCKET" type="string" required>
  Name of the bucket where screenshots will be stored.
</ParamField>

<ParamField path="AWS_URL" type="string" required>
  Complete endpoint URL for your S3-compatible service.
</ParamField>

<ParamField path="AWS_ENDPOINT" type="string">
  S3 endpoint URL (usually same as AWS\_URL).
</ParamField>

<ParamField path="AWS_USE_PATH_STYLE_ENDPOINT" type="boolean" default="false">
  Use path-style URLs instead of virtual-hosted style. Set to `true` for MinIO and some other services.
</ParamField>

### Storage provider examples

<Tabs>
  <Tab title="AWS S3">
    ```bash theme={null}
    AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
    AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
    AWS_REGION=us-east-1
    AWS_BUCKET=my-screenshothis-bucket
    AWS_URL=https://s3.us-east-1.amazonaws.com
    AWS_USE_PATH_STYLE_ENDPOINT=false
    ```
  </Tab>

  <Tab title="DigitalOcean Spaces">
    ```bash theme={null}
    AWS_ACCESS_KEY_ID=your_do_spaces_key
    AWS_SECRET_ACCESS_KEY=your_do_spaces_secret
    AWS_REGION=nyc3
    AWS_BUCKET=my-screenshothis-space
    AWS_URL=https://nyc3.digitaloceanspaces.com
    AWS_USE_PATH_STYLE_ENDPOINT=false
    ```
  </Tab>

  <Tab title="Cloudflare R2">
    ```bash theme={null}
    AWS_ACCESS_KEY_ID=your_r2_access_key
    AWS_SECRET_ACCESS_KEY=your_r2_secret_key
    AWS_REGION=auto
    AWS_BUCKET=my-screenshothis-bucket
    AWS_URL=https://your-account-id.r2.cloudflarestorage.com
    AWS_USE_PATH_STYLE_ENDPOINT=false
    ```
  </Tab>

  <Tab title="MinIO (Local)">
    ```bash theme={null}
    AWS_ACCESS_KEY_ID=screenshothis-access-key
    AWS_SECRET_ACCESS_KEY=screenshothis-secret-key
    AWS_REGION=us-east-1
    AWS_BUCKET=screenshothis-bucket
    AWS_URL=http://localhost:9000
    AWS_ENDPOINT=http://localhost:9000
    AWS_USE_PATH_STYLE_ENDPOINT=true
    ```
  </Tab>
</Tabs>

<Tip>
  For production, we recommend AWS S3 for reliability, or DigitalOcean Spaces for cost-effectiveness. Cloudflare R2 offers excellent performance and free egress.
</Tip>

## Application settings

Configure basic application behavior:

<ParamField path="PORT" type="integer" default="3000">
  Port number for the server to listen on.
</ParamField>

<ParamField path="NODE_ENV" type="string" required>
  Environment mode. Use `development` for local work, `production` for live deployments.

  ```bash theme={null}
  NODE_ENV=development  # Development
  NODE_ENV=production   # Production
  ```
</ParamField>

## Authentication and security

Configure authentication and API key generation:

<ParamField path="BETTER_AUTH_SECRET" type="string" required>
  Secret key for Better Auth authentication system. Must be a strong, random string.

  Generate a secure secret:

  ```bash theme={null}
  openssl rand -base64 32
  ```
</ParamField>

<ParamField path="DEFAULT_API_KEY_PREFIX" type="string" default="ss">
  Prefix for generated API keys. Use different prefixes for different environments.

  ```bash theme={null}
  DEFAULT_API_KEY_PREFIX=ss_test   # Development
  DEFAULT_API_KEY_PREFIX=ss_live   # Production
  ```
</ParamField>

<Warning>
  **Production security**: Always use a strong, unique `BETTER_AUTH_SECRET` for production. Never reuse secrets across environments or share them in version control.
</Warning>

## Frontend configuration

Configure the web interface in `apps/web/.env`:

<ParamField path="VITE_SERVER_URL" type="string" required>
  URL of your backend API server.

  ```bash theme={null}
  VITE_SERVER_URL=http://localhost:3000      # Development
  VITE_SERVER_URL=https://api.yourdomain.com # Production
  ```
</ParamField>

<ParamField path="VITE_GOOGLE_CLIENT_ID" type="string">
  Google OAuth client ID for Google authentication (optional).
</ParamField>

<ParamField path="POLAR_ACCESS_TOKEN" type="string">
  Polar access token for billing integration (optional).
</ParamField>

<ParamField path="POLAR_ENVIRONMENT" type="string" default="sandbox">
  Polar environment. Use `sandbox` for testing, `production` for live billing.
</ParamField>

<Info>
  Google OAuth and Polar configurations are optional. You only need them if you want to offer Google sign-in or integrate with Polar for billing.
</Info>

## Performance and limits

Configure rate limiting and screenshot performance:

<ParamField path="RATE_LIMIT_WINDOW_MS" type="integer" default="60000">
  Rate limit window duration in milliseconds. Default is 1 minute (60000ms).
</ParamField>

<ParamField path="RATE_LIMIT_MAX_REQUESTS" type="integer" default="100">
  Maximum requests allowed per rate limit window.
</ParamField>

<ParamField path="MAX_CONCURRENT_SCREENSHOTS" type="integer" default="10">
  Maximum number of screenshots that can be processed simultaneously.
</ParamField>

<ParamField path="SCREENSHOT_TIMEOUT" type="integer" default="30000">
  Screenshot generation timeout in milliseconds. Default is 30 seconds.
</ParamField>

## Screenshot settings

Configure screenshot generation limits and defaults:

<ParamField path="MAX_SCREENSHOT_WIDTH" type="integer" default="3840">
  Maximum allowed screenshot width in pixels.
</ParamField>

<ParamField path="MAX_SCREENSHOT_HEIGHT" type="integer" default="2160">
  Maximum allowed screenshot height in pixels.
</ParamField>

<ParamField path="DEFAULT_VIEWPORT_WIDTH" type="integer" default="1280">
  Default viewport width when not specified in requests.
</ParamField>

<ParamField path="DEFAULT_VIEWPORT_HEIGHT" type="integer" default="720">
  Default viewport height when not specified in requests.
</ParamField>

<ParamField path="MAX_PAGE_LOAD_TIMEOUT" type="integer" default="30000">
  Maximum time to wait for page loading in milliseconds.
</ParamField>

## Built-in security features

Screenshothis includes several built-in security measures that you should be aware of:

<AccordionGroup>
  <Accordion title="Request size limits" icon="shield">
    **Automatically enforced limits:**

    * Header size limit: 8 KB (8192 characters) per request
    * Cookie size limit: 4 KB (4096 characters) per request
    * URL length limit: Standard browser limits (2048 characters)

    These limits prevent abuse and ensure consistent performance across all deployments.
  </Accordion>

  <Accordion title="Rate limiting system" icon="clock">
    **Built-in rate limiting:**

    * Per-user rate limiting via internal `requestLimits` system
    * Configurable via `RATE_LIMIT_*` environment variables
    * Automatic abuse protection

    The system tracks usage per API key and enforces limits automatically.
  </Accordion>

  <Accordion title="CSP bypass auditing" icon="eye">
    **Security auditing:**

    * Every use of `bypass_csp=true` is logged server-side
    * Helps identify potential security issues
    * Enables compliance and security reviews

    Monitor these logs regularly in production environments.
  </Accordion>

  <Accordion title="Input validation" icon="check-circle">
    **Automatic validation:**

    * All API inputs validated using Zod schemas
    * URL validation prevents malicious requests
    * Parameter validation ensures data integrity

    Input validation helps prevent injection attacks and maintains system stability.
  </Accordion>
</AccordionGroup>

## Complete configuration examples

### Minimal production setup

**Backend configuration** (`apps/server/.env`):

```bash theme={null}
# Database
DATABASE_URL=postgresql://user:secure_pass@db.example.com:5432/screenshothis

# Redis
REDIS_URL=redis://user:password@redis.example.com:6379

# Storage (AWS S3)
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_REGION=us-east-1
AWS_BUCKET=your-production-bucket
AWS_URL=https://s3.us-east-1.amazonaws.com

# Authentication
BETTER_AUTH_SECRET=your_strong_random_secret_here
DEFAULT_API_KEY_PREFIX=ss_live

# Application
NODE_ENV=production
PORT=3000
```

**Frontend configuration** (`apps/web/.env`):

```bash theme={null}
VITE_SERVER_URL=https://api.yourdomain.com
NODE_ENV=production
```

### High-performance production setup

For high-traffic deployments, use these optimized settings:

```bash theme={null}
# ... base configuration above ...

# Performance optimization
MAX_CONCURRENT_SCREENSHOTS=20
SCREENSHOT_TIMEOUT=15000
RATE_LIMIT_MAX_REQUESTS=1000
RATE_LIMIT_WINDOW_MS=60000

# Optimized screenshot settings
MAX_SCREENSHOT_WIDTH=1920
MAX_SCREENSHOT_HEIGHT=1080
DEFAULT_VIEWPORT_WIDTH=1280
DEFAULT_VIEWPORT_HEIGHT=720
MAX_PAGE_LOAD_TIMEOUT=20000
```

### Development with external services

For development using cloud services instead of local Docker:

```bash theme={null}
# Database (managed PostgreSQL)
DATABASE_URL=postgresql://dev_user:dev_pass@dev-db.provider.com:5432/screenshothis_dev

# Redis (managed Redis)
REDIS_URL=redis://dev_user:dev_pass@dev-redis.provider.com:6379

# Storage (DigitalOcean Spaces for cost-effective development)
AWS_ACCESS_KEY_ID=your_dev_spaces_key
AWS_SECRET_ACCESS_KEY=your_dev_spaces_secret
AWS_REGION=nyc3
AWS_BUCKET=screenshothis-dev
AWS_URL=https://nyc3.digitaloceanspaces.com

# Development authentication
BETTER_AUTH_SECRET=dev_secret_change_for_production
DEFAULT_API_KEY_PREFIX=ss_test

# Application
NODE_ENV=development
PORT=3000
```

## Docker deployment configuration

### Using environment files

Organize your configuration using environment files:

```yaml theme={null}
# docker-compose.yml
version: '3.8'
services:
  screenshothis-server:
    image: screenshothis/server
    env_file:
      - .env.production
    ports:
      - "3000:3000"
    restart: unless-stopped

  screenshothis-web:
    image: screenshothis/web
    env_file:
      - .env.web.production
    ports:
      - "3001:3000"
    restart: unless-stopped
```

### Using Docker secrets

For enhanced security in production:

```yaml theme={null}
# docker-compose.yml
version: '3.8'
services:
  screenshothis-server:
    image: screenshothis/server
    secrets:
      - better_auth_secret
      - aws_secret_key
      - database_password
    environment:
      DATABASE_URL: postgresql://user:password@postgres:5432/screenshothis
      BETTER_AUTH_SECRET_FILE: /run/secrets/better_auth_secret
      AWS_SECRET_ACCESS_KEY_FILE: /run/secrets/aws_secret_key
      DATABASE_PASSWORD_FILE: /run/secrets/database_password
    ports:
      - "3000:3000"

secrets:
  better_auth_secret:
    file: ./secrets/better_auth_secret.txt
  aws_secret_key:
    file: ./secrets/aws_secret_key.txt
  database_password:
    file: ./secrets/database_password.txt
```

## Configuration validation

Validate your configuration before deployment:

<Steps>
  <Step title="Check required variables">
    Ensure all required environment variables are set:

    ```bash theme={null}
    # Test configuration by starting the application
    pnpm run dev

    # Check for missing variables in the startup logs
    ```
  </Step>

  <Step title="Test database connection">
    Verify your database connection:

    ```bash theme={null}
    # Test database connectivity
    pnpm run db:studio

    # Should open Drizzle Studio if connection is successful
    ```
  </Step>

  <Step title="Validate storage configuration">
    Test your S3-compatible storage:

    ```bash theme={null}
    # For MinIO (local development)
    curl http://localhost:9000/minio/health/live

    # For production, test with a simple API call
    curl "https://your-api.com/v1/screenshots/take?api_key=test&url=https://example.com"
    ```
  </Step>

  <Step title="Verify rate limits">
    Test rate limiting behavior with multiple requests to ensure limits are working correctly.
  </Step>
</Steps>

## Troubleshooting configuration

<AccordionGroup>
  <Accordion title="Application won't start" icon="exclamation-triangle">
    **Common causes:**

    * Missing required environment variables
    * Invalid database connection string
    * Incorrect Redis URL format
    * S3 credentials or bucket access issues

    **Solution:** Check the startup logs for specific error messages about missing or invalid configuration.
  </Accordion>

  <Accordion title="Database connection errors" icon="database">
    **Common causes:**

    * Incorrect DATABASE\_URL format
    * Database server not accessible
    * Wrong credentials
    * Database doesn't exist

    **Solution:** Test connection manually: `psql "postgresql://user:pass@host:port/db"`
  </Accordion>

  <Accordion title="S3 storage errors" icon="cloud">
    **Common causes:**

    * Invalid credentials
    * Bucket doesn't exist
    * Wrong region configuration
    * Incorrect endpoint URL

    **Solution:** Verify bucket exists and credentials have proper permissions (read/write access).
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Deployment Guide" icon="rocket" href="/self-host/deployment">
    Deploy your configured instance to production with Docker, Kubernetes, or cloud platforms
  </Card>

  <Card title="Troubleshooting" icon="life-ring" href="/self-host/troubleshooting">
    Common issues and solutions for self-hosted deployments
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Complete API documentation for your configured instance
  </Card>

  <Card title="GitHub Repository" icon="github" href="https://github.com/screenshothis/screenshothis">
    View source code and latest configuration options
  </Card>
</CardGroup>
