Files
pr-preview/README.md
T

2.8 KiB

PR Previews (PP)

Self-hosted service that connects to a Gitea instance via webhook. When a PR is opened or updated, PP automatically provisions an AWS EC2 instance, builds and runs the project, and comments a live preview URL back on the PR.

Quick Start

Prerequisites

  • Docker & Docker Compose
  • Gitea instance with admin access
  • AWS account with EC2 permissions

Setup

  1. Clone and configure:

    cp example.env .env
    # Edit .env — at minimum set SESSION_SECRET, PP_BASE_URL, and ENCRYPTION_KEY
    # Generate ENCRYPTION_KEY: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
    
  2. Start services:

    docker compose up -d
    
  3. Open the web UI at http://localhost:5000 (or your configured PP_BASE_URL)

  4. Create your admin account on first login — you'll be prompted for a username and password.

  5. Complete the setup wizard to configure Gitea and AWS credentials.

Architecture

./backend/             # Node.js backend (rjweb-server + Prisma)
./frontend/            # React + Vite + Tailwind CSS
./prisma/schema.prisma # PostgreSQL schema
./docker-compose.yml   # PP itself (backend + db)
./Dockerfile           # Multi-stage build

Environment Variables

Variable Description
DATABASE_URL PostgreSQL connection string
SESSION_SECRET Cookie signing secret (32+ random chars)
PP_BASE_URL Public URL of this PP instance (no trailing slash)
ENCRYPTION_KEY AES-256 key — 64 hex chars (32 bytes). Generate: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
PORT Backend port (default: 5000)
LOG_LEVEL Logging level: trace/debug/info/warn/error (default: info)

PP Commands (in PR comments)

Command Action
/pp rebuild Re-run build on existing EC2 instance
/pp stop Stop and terminate the preview
/pp start Start or restart a stopped/ignored preview
/pp logs Post last 50 lines of logs as a comment
/pp ignore Ignore all future events for this PR

Required AWS IAM Permissions

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "ec2:RunInstances", "ec2:TerminateInstances", "ec2:DescribeInstances",
      "ec2:CreateSecurityGroup", "ec2:DeleteSecurityGroup",
      "ec2:AuthorizeSecurityGroupIngress", "ec2:DescribeSecurityGroups",
      "ec2:CreateKeyPair", "ec2:DeleteKeyPair", "ec2:CreateTags",
      "sts:GetCallerIdentity"
    ],
    "Resource": "*"
  }]
}

Development

# Database (via Docker)
docker compose up -d pp-db

# Run migrations
cd backend && npx prisma migrate dev --schema=../prisma/schema.prisma

# Backend (port 5000)
cd backend && pnpm install && pnpm dev

# Frontend dev server (port 3000, proxies API to backend)
cd frontend && pnpm install && pnpm dev