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.
Always check the source: Refer to the Screenshothis repository .env.example files for the most up-to-date configuration options. This guide is based on the actual environment variables used in the codebase.

Quick configuration

Start with this minimal setup and expand as needed:
1

Set up database connection

Configure PostgreSQL connection details in your apps/server/.env file.
2

Configure storage

Set up S3-compatible storage credentials for screenshot storage.
3

Add authentication secrets

Generate secure secrets for user authentication and API keys.
4

Customize performance settings

Adjust rate limits, timeouts, and screenshot quality settings.

Database configuration

Configure your PostgreSQL database connection:
DATABASE_URL
string
required
Complete PostgreSQL connection string. This is the primary database configuration.
# Format: postgresql://username:password@host:port/database
DATABASE_URL=postgresql://screenshothis:password@localhost:5432/screenshothis
DATABASE_HOST
string
required
Database server hostname or IP address.
DATABASE_HOST=localhost  # Development
DATABASE_HOST=prod-db.example.com  # Production
DATABASE_PORT
integer
default:"5432"
PostgreSQL server port.
DATABASE_NAME
string
required
Name of the Screenshothis database.
DATABASE_NAME=screenshothis
DATABASE_USER
string
required
Database username for connections.
DATABASE_PASSWORD
string
required
Database password for the specified user.
DATABASE_URL=postgresql://screenshothis:password@localhost:5432/screenshothis
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=screenshothis
DATABASE_USER=screenshothis
DATABASE_PASSWORD=password

Redis configuration

Configure Redis for caching and session management:
REDIS_URL
string
required
Complete Redis connection string. This is the primary Redis configuration.
# Development
REDIS_URL=redis://localhost:6379

# Production with authentication
REDIS_URL=redis://user:password@prod-redis.example.com:6379
REDIS_HOST
string
default:"localhost"
Redis server hostname (optional if using REDIS_URL).
REDIS_PORT
integer
default:"6379"
Redis server port (optional if using REDIS_URL).
REDIS_PASSWORD
string
Redis password if authentication is required.

S3-compatible storage

Configure storage for screenshots using any S3-compatible service:
AWS_ACCESS_KEY_ID
string
required
Access key ID for your S3-compatible storage service.
AWS_SECRET_ACCESS_KEY
string
required
Secret access key for your S3-compatible storage service.
AWS_REGION
string
required
Storage region. Use auto for Cloudflare R2, or the appropriate region for your service.
AWS_BUCKET
string
required
Name of the bucket where screenshots will be stored.
AWS_URL
string
required
Complete endpoint URL for your S3-compatible service.
AWS_ENDPOINT
string
S3 endpoint URL (usually same as AWS_URL).
AWS_USE_PATH_STYLE_ENDPOINT
boolean
default:"false"
Use path-style URLs instead of virtual-hosted style. Set to true for MinIO and some other services.

Storage provider examples

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
For production, we recommend AWS S3 for reliability, or DigitalOcean Spaces for cost-effectiveness. Cloudflare R2 offers excellent performance and free egress.

Application settings

Configure basic application behavior:
PORT
integer
default:"3000"
Port number for the server to listen on.
NODE_ENV
string
required
Environment mode. Use development for local work, production for live deployments.
NODE_ENV=development  # Development
NODE_ENV=production   # Production

Authentication and security

Configure authentication and API key generation:
BETTER_AUTH_SECRET
string
required
Secret key for Better Auth authentication system. Must be a strong, random string.Generate a secure secret:
openssl rand -base64 32
DEFAULT_API_KEY_PREFIX
string
default:"ss"
Prefix for generated API keys. Use different prefixes for different environments.
DEFAULT_API_KEY_PREFIX=ss_test   # Development
DEFAULT_API_KEY_PREFIX=ss_live   # Production
Production security: Always use a strong, unique BETTER_AUTH_SECRET for production. Never reuse secrets across environments or share them in version control.

Frontend configuration

Configure the web interface in apps/web/.env:
VITE_SERVER_URL
string
required
URL of your backend API server.
VITE_SERVER_URL=http://localhost:3000      # Development
VITE_SERVER_URL=https://api.yourdomain.com # Production
VITE_GOOGLE_CLIENT_ID
string
Google OAuth client ID for Google authentication (optional).
POLAR_ACCESS_TOKEN
string
Polar access token for billing integration (optional).
POLAR_ENVIRONMENT
string
default:"sandbox"
Polar environment. Use sandbox for testing, production for live billing.
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.

Performance and limits

Configure rate limiting and screenshot performance:
RATE_LIMIT_WINDOW_MS
integer
default:"60000"
Rate limit window duration in milliseconds. Default is 1 minute (60000ms).
RATE_LIMIT_MAX_REQUESTS
integer
default:"100"
Maximum requests allowed per rate limit window.
MAX_CONCURRENT_SCREENSHOTS
integer
default:"10"
Maximum number of screenshots that can be processed simultaneously.
SCREENSHOT_TIMEOUT
integer
default:"30000"
Screenshot generation timeout in milliseconds. Default is 30 seconds.

Screenshot settings

Configure screenshot generation limits and defaults:
MAX_SCREENSHOT_WIDTH
integer
default:"3840"
Maximum allowed screenshot width in pixels.
MAX_SCREENSHOT_HEIGHT
integer
default:"2160"
Maximum allowed screenshot height in pixels.
DEFAULT_VIEWPORT_WIDTH
integer
default:"1280"
Default viewport width when not specified in requests.
DEFAULT_VIEWPORT_HEIGHT
integer
default:"720"
Default viewport height when not specified in requests.
MAX_PAGE_LOAD_TIMEOUT
integer
default:"30000"
Maximum time to wait for page loading in milliseconds.

Built-in security features

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

Complete configuration examples

Minimal production setup

Backend configuration (apps/server/.env):
# 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):
VITE_SERVER_URL=https://api.yourdomain.com
NODE_ENV=production

High-performance production setup

For high-traffic deployments, use these optimized settings:
# ... 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:
# 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:
# 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:
# 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:
1

Check required variables

Ensure all required environment variables are set:
# Test configuration by starting the application
pnpm run dev

# Check for missing variables in the startup logs
2

Test database connection

Verify your database connection:
# Test database connectivity
pnpm run db:studio

# Should open Drizzle Studio if connection is successful
3

Validate storage configuration

Test your S3-compatible storage:
# 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"
4

Verify rate limits

Test rate limiting behavior with multiple requests to ensure limits are working correctly.

Troubleshooting configuration

Next steps