2fb966542b1276268083408f8c9a4bec2e1a2aaf
- Add workspace-level pnpm install in Dockerfile so pnpm-workspace.yaml supply-chain settings (onlyBuiltDependencies, allowBuilds) apply uniformly - Pin pnpm@11.5.2 via corepack with sha1 hash to prevent future policy drift - Downgrade postcss to ^8.5.22 (8.5.23 was <24h old, violated minimumReleaseAge) - Regenerate frontend/pnpm-lock.yaml and add root pnpm-lock.yaml for full workspace - Add binaryTargets to Prisma schema for linux-musl (Alpine) + debian compatibility - Run pnpm approve-builds to set allowBuilds for esbuild, ssh2, prisma, @prisma/* - Fix docker-compose.yml: postgres:18-alpine volume at /var/lib/postgresql (not /data) - Add .env.docker.example; ignore .env.docker in .gitignore Integration tests (Docker Compose against real Gitea 1.26.2): ✅ Docker image builds cleanly (pnpm frozen-lockfile, no policy violations) ✅ postgres:18-alpine starts healthy ✅ Prisma migrations run on startup ✅ Founder registration and session auth ✅ Gitea connection validated (PAT scope check) ✅ Webhook registered on test repo (Hook ID 11) ✅ PR opened → HMAC verified → preview created → DEPLOY job queued ✅ Gitea PR comment posted (write:issue scope confirmed working) ✅ Deploy fails correctly at AWS step: "Region is missing" (no creds in test env) ✅ PR closed → STOP job created and completed (status DONE) ✅ HMAC rejection: wrong signature → 401 ✅ /pp stop via issue_comment webhook → accepted Blocked (expected): EC2 provisioning requires AWS credentials not present in CI/test env. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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%