Self-host Screenshothis

Take complete control of your screenshot infrastructure by running Screenshothis on your own servers. This guide walks you through everything from local development setup to production deployment.
Important: Always refer to the official Screenshothis repository for the most up-to-date setup instructions, environment variables, and configuration requirements. The repository README and .env.example files contain the definitive setup information.
Why self-host? While our hosted service provides simplicity and reliability, self-hosting gives you complete data control, unlimited customization options, and eliminates external dependencies.

Project architecture

Screenshothis uses a modern monorepo architecture built with TypeScript:

Backend API

Location: apps/serverHono + tRPC API with TypeScript for fast, type-safe screenshot generation

Frontend Web App

Location: apps/webReact with TanStack Start and TailwindCSS for the dashboard and playground

Shared Packages

Location: packages/*Common schemas, utilities, and types shared across applications

Infrastructure

DependenciesPostgreSQL, Redis, and S3-compatible storage for complete functionality

Technology stack

ComponentTechnologyPurpose
RuntimeNode.js + TypeScriptFast, type-safe execution
API FrameworkHono + tRPCLightweight, type-safe API
FrontendReact + TanStack StartModern, fast web interface
DatabasePostgreSQL + Drizzle ORMReliable data persistence
File StorageS3-compatible storageScreenshot and asset storage
Cache/SessionsRedisFast caching and session management
StylingTailwindCSSUtility-first CSS framework
Linting/FormattingBiomeFast, consistent code formatting
Package ManagerpnpmEfficient dependency management
MonorepoTurborepoFast, scalable build system
ContainerizationDocker + Docker ComposeEasy deployment and scaling

Prerequisites

Before you begin, ensure you have these tools installed:
1

Install Node.js

Download and install Node.js v18 or later from nodejs.org
Verify your installation: node --version should show v18.0.0 or higher
2

Install pnpm

Install the pnpm package manager:
npm install -g pnpm
Verify: pnpm --version should show the installed version
3

Install Docker

Download and install Docker Desktop for your operating system
Verify: docker --version and docker-compose --version should both work
4

Install Git

Ensure Git is installed for cloning the repository
Verify: git --version should show your Git installation

Quick setup

Get Screenshothis running locally in under 10 minutes:
1

Clone the repository

git clone https://github.com/screenshothis/screenshothis.git
cd screenshothis
You should now be in the screenshothis directory with all source code
2

Install dependencies

pnpm install
This installs all dependencies for the entire monorepo using pnpm workspaces.
You should see “Dependencies installed” and no error messages
3

Start supporting services

Launch PostgreSQL, Redis, and MinIO (for local storage):
docker-compose up -d
This starts:
  • PostgreSQL on localhost:5432
  • Redis on localhost:6379
  • MinIO (S3-compatible) on localhost:9000 (API) and localhost:9001 (Console)
Verify services: docker-compose ps should show all services as “Up”
4

Configure environment variables

Copy and customize the environment files:
# Server environment
cp apps/server/.env.example apps/server/.env

# Web environment (optional)
cp apps/web/.env.example apps/web/.env
The default values work for local development with Docker Compose.
You can customize settings later. The defaults are configured to work with the Docker services.
5

Set up the database

Apply the database schema:
pnpm run db:push
This creates all necessary tables in your PostgreSQL database.
You should see “Schema applied successfully” or similar confirmation
6

Configure local storage

Set up MinIO for local screenshot storage:
  1. Open MinIO console at http://localhost:9001
  2. Login with credentials:
    • Username: screenshothis-access-key
    • Password: screenshothis-secret-key
  3. Create a bucket named screenshothis-bucket
  4. Verify access - you should see the empty bucket
MinIO provides S3-compatible storage for local development. For production, use AWS S3, DigitalOcean Spaces, or another S3-compatible service.
7

Start the applications

Launch both the web interface and API server:
pnpm run dev
This starts:
Visit both URLs to verify everything is working. You should see the Screenshothis interface and API health check.

Environment configuration

Server environment (apps/server/.env)

Configure the server with these essential variables:
# Database Configuration
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
REDIS_URL=redis://localhost:6379

# S3-Compatible Storage Configuration
# For local development (MinIO):
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

# For production, replace with your S3-compatible service:
# AWS_ACCESS_KEY_ID=your-actual-access-key
# AWS_SECRET_ACCESS_KEY=your-actual-secret-key
# AWS_REGION=us-east-1
# AWS_BUCKET=your-production-bucket
# AWS_URL=https://your-s3-endpoint.com
# AWS_ENDPOINT=https://your-s3-endpoint.com
# AWS_USE_PATH_STYLE_ENDPOINT=false

# API Configuration
PORT=3000
NODE_ENV=development

# Authentication & Security
BETTER_AUTH_SECRET=your-super-secure-auth-secret-key-here
DEFAULT_API_KEY_PREFIX=ss

# Rate Limiting & Security
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100

# Screenshot Configuration
SCREENSHOT_TIMEOUT=30000
MAX_SCREENSHOT_WIDTH=3840
MAX_SCREENSHOT_HEIGHT=2160

# Request Limits (Security)
MAX_HEADER_SIZE=8192  # 8KB header limit
MAX_COOKIE_SIZE=4096  # 4KB cookie limit

# CSP Bypass Auditing
AUDIT_CSP_BYPASS=true  # Log when bypass_csp=true is used

Web environment (apps/web/.env)

Configure the web interface:
# API Configuration
VITE_API_URL=http://localhost:3000

# Environment
NODE_ENV=development
Production security: Always use strong, unique passwords and secrets for production deployments. Never use the default development values.

Available scripts

Run these commands from the root directory:

Development scripts

CommandDescription
pnpm installInstall all dependencies for the monorepo
pnpm run devStart both web and server in development mode
pnpm run dev:webStart only the web (frontend) application
pnpm run dev:serverStart only the server (backend) application

Build and production scripts

CommandDescription
pnpm run buildBuild all applications for production
pnpm run startStart production builds (after building)

Database management scripts

CommandDescription
pnpm run db:pushApply Drizzle schema changes to the database
pnpm run db:studioOpen Drizzle Studio to view and manage the database
pnpm run db:generateGenerate migration files for schema changes
pnpm run db:migrateApply migrations to the database

Code quality scripts

CommandDescription
pnpm run check-typesRun TypeScript type checking across all packages
pnpm run checkRun Biome linting and formatting checks
pnpm run formatApply Biome formatting to the codebase
pnpm run lintRun Biome linting checks
pnpm run lint:fixRun Biome linting and fix issues automatically

Production deployment

Docker production setup

Build and deploy production-ready Docker images:
1

Build production images

# Build server image
docker build -f apps/server/Dockerfile -t screenshothis-server .

# Build web interface image
docker build -f apps/web/Dockerfile -t screenshothis-web .
2

Set up external services

Configure production-grade external services:
  • PostgreSQL: Use managed PostgreSQL (AWS RDS, DigitalOcean Managed Databases, etc.)
  • Redis: Use managed Redis (AWS ElastiCache, DigitalOcean Managed Redis, etc.)
  • S3 Storage: Use AWS S3, DigitalOcean Spaces, Cloudflare R2, or Backblaze B2
3

Configure production environment

Create production environment files with:
  • Strong, unique passwords and secrets
  • Production database connections
  • Production S3-compatible storage credentials
  • Appropriate rate limits and timeouts
4

Set up infrastructure

Configure your production infrastructure:
  • Reverse proxy: nginx, Traefik, or cloud load balancer
  • SSL certificates: Let’s Encrypt, cloud provider, or custom certificates
  • Container orchestration: Docker Compose, Kubernetes, or cloud container services

Environment variables for production

Ensure these are properly configured for production:
BETTER_AUTH_SECRET
string
required
Strong, unique secret for authentication. Generate with openssl rand -base64 32
DATABASE_URL
string
required
Connection string for your production PostgreSQL database
REDIS_URL
string
required
Connection string for your production Redis instance
AWS_ACCESS_KEY_ID
string
required
Access key for your S3-compatible storage service
AWS_SECRET_ACCESS_KEY
string
required
Secret key for your S3-compatible storage service
AWS_BUCKET
string
required
Name of your production storage bucket

Security considerations

When self-hosting, you’re responsible for security, updates, backups, and monitoring. Ensure you have proper security measures in place.

Built-in security features

Screenshothis includes several security measures:

Additional security recommendations

1

Keep dependencies updated

Regularly update Node.js, dependencies, and base Docker images to get security patches.
2

Secure your database

  • Use strong passwords
  • Enable SSL/TLS connections
  • Restrict network access
  • Regular backups
3

Configure HTTPS

  • Use SSL/TLS certificates for all connections
  • Configure secure headers
  • Enable HSTS (HTTP Strict Transport Security)
4

Monitor and log

  • Set up application logging
  • Monitor resource usage
  • Track API usage patterns
  • Set up alerts for unusual activity

Database management

View and manage data

Use Drizzle Studio for a visual database interface:
pnpm run db:studio
This opens a web interface at http://localhost:4983 where you can:
  • View all tables and data
  • Edit records
  • Run queries
  • Manage relationships

Handle schema changes

For development, use the simple approach:
# Apply schema changes directly (development only)
pnpm run db:push
For production, use migrations:
# Generate migration files when schema changes
pnpm run db:generate

# Apply migrations to database
pnpm run db:migrate
Development vs Production: Use db:push for rapid development iteration, but use migrations (db:generate and db:migrate) for production deployments where you need versioned, reversible database changes.

Troubleshooting

Common issues and solutions

Getting help

Contributing

Screenshothis is an open source project (AGPL-3.0) with an active community. Your contributions help make it better for everyone.

Ways to contribute

1

Report issues

Found a bug or have a feature request? Create an issue with detailed information.
2

Improve documentation

Help others by improving documentation, adding examples, or fixing typos.
3

Submit code changes

Follow our development guidelines:
  • Run pnpm run check before committing
  • Ensure TypeScript types are correct: pnpm run check-types
  • Test your changes locally with pnpm run dev
  • Follow existing code style (Biome handles formatting)
4

Join discussions

Participate in GitHub Discussions to share ideas and help other users.

Development workflow

  1. Fork the repository
  2. Create a feature branch: git checkout -b fix-something
  3. Make your changes
  4. Test locally: pnpm run dev
  5. Submit a pull request

Next steps


License: AGPL-3.0 • Repository: github.com/screenshothis/screenshothis