65cf6ce5d20dfb3c18a48718c64ec4541e17d54e
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
-
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'))" -
Start services:
docker compose up -d -
Open the web UI at
http://localhost:5000(or your configured PP_BASE_URL) -
Create your admin account on first login — you'll be prompted for a username and password.
-
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
Description
Languages
TypeScript
97.8%
HTML
1.1%
Dockerfile
0.7%
CSS
0.3%
JavaScript
0.1%