Repository Configuration (preview-config.yml)
Place this file in your repository root to configure preview deployments. The orchestrator reads it after cloning the repo; any values you set here override defaults and auto-detection (e.g. framework is taken from this file when present, otherwise detected from the repo).
Required Fields
Optional Fields
Repo-owned preview Compose (docker-compose.preview.yml)
You can provide your own Docker Compose file strictly for preview by placing docker-compose.preview.yml or docker-compose.preview.yaml in your repository root (exact names only; no fuzzy matching). When present, the orchestrator uses it instead of generating one from framework templates (same idea as using your own Dockerfile).
- File names:
docker-compose.preview.ymlordocker-compose.preview.yaml(in repo root). Only these two exact filenames are accepted. If you use.yaml, the orchestrator renames it to.ymlso one standard path is used everywhere. - When used: If either file exists after clone/checkout, the orchestrator parses it, injects host port mappings (see Ports), and writes
docker-compose.preview.generated.ymlin the deployment directory. That generated file is used fordocker compose up/down. Otherwise the orchestrator generatesdocker-compose.preview.ymlfrom templates. - Ports: Do not specify host ports for the
appordbservices in your compose file. The orchestrator injects them at runtime so each preview gets unique ports and nginx can route correctly. Use service namesappanddb. Container ports are inferred from framework (NestJS 3000, Go 8080, Laravel 8000) and database type (Postgres 5432, MySQL 3306, MongoDB 27017). If you omitportsforapp/db, we add them; if you had host ports, we override them. - Project name: The orchestrator always runs with
-p <deploymentId>(e.g.myorg-myapp-12). Do not rely on a fixed project name in your file. - Rebuild/cleanup: Update and cleanup use the same generated file:
docker-compose.preview.generated.ymlwhen you provide repo compose, otherwisedocker-compose.preview.yml(orchestrator-generated).
CLI Configuration (~/.preview-deployer/config.yml)
Generated by preview init. Sensitive values are stored in OS keychain.
Environment Variables
Orchestrator Service
Set in Ansible or systemd service file:Terraform Variables
Set interraform/terraform.tfvars:
Available Regions
nyc1,nyc3: New Yorksfo3: San Franciscoams3: Amsterdamsgp1: Singaporelon1: Londonfra1: Frankfurttor1: Torontoblr1: Bangalore
Available Droplet Sizes
s-1vcpu-2gb: $12/months-2vcpu-4gb: $24/month (default)s-4vcpu-8gb: $48/months-8vcpu-16gb: $96/month
Ansible Variables
Set via-e flag or in playbook:
Optional SSL (Let’s Encrypt)
When you have a domain pointing at the server, set these so the nginx role obtains a certificate and serves HTTPS:preview_base_url (and orchestrator env) to https://preview.example.com so PR comments get HTTPS preview links. Certbot runs via the nginx role (webroot); HTTP is redirected to HTTPS and ACME challenges are served on port 80 for renewal.
Docker Compose Templates
Templates are located inorchestrator/templates/:
docker-compose.nestjs.yml.hbs: NestJS application templatedocker-compose.go.yml.hbs: Go application template
Template Variables
{{prNumber}}: PR number{{appPort}}: Allocated app port{{dbPort}}: Allocated database port
Container Resources
Default limits (configurable in templates):Nginx Configuration
The nginx role installs nginx and a default server block (port 80, or 80+443 when SSL is enabled). Optional SSL is handled inside the same role: whenpreview_domain and ssl_email are set, it installs certbot, obtains a certificate (webroot), and re-deploys nginx with listen 443 and HTTP→HTTPS redirect.
Preview configs are generated in /etc/nginx/preview-configs/. That directory is owned by the deployment user (e.g. preview-deployer) so the orchestrator can create and remove config files without root. After writing a config, the orchestrator runs nginx -t and nginx -s reload via sudo; Ansible deploys a sudoers fragment at /etc/sudoers.d/preview-deployer-nginx so the deployment user can run only those two nginx commands without a password. The orchestrator systemd unit has NoNewPrivileges=false so that sudo can be used for this limited reload, and ReadWritePaths includes /var/log/nginx and /run so the nginx child process can write its error log and pid file when testing/reloading.
Health Check Configuration
Your application must expose a health check endpoint:NestJS Example
Go Example
Framework detection and Dockerfiles
The orchestrator detects the app framework (NestJS, Go, or Laravel) from the cloned repo and uses the matching docker-compose template. If the repo has no Dockerfile, the orchestrator injects a default one for that framework fromorchestrator/templates/ (e.g. Dockerfile.nestjs, Dockerfile.go, Dockerfile.laravel). Repos can override by providing their own Dockerfile at the repo root.
Detection order: NestJS (nest-cli.json or @nestjs/core in package.json) → Go (go.mod) → Laravel (laravel/framework in composer.json). If none match, NestJS is assumed.
Custom Dockerfiles
If your repository has a custom Dockerfile, ensure it:- Exposes the correct port (3000 NestJS, 8080 Go, 8000 Laravel)
- Includes a health check endpoint (or
/healthfor orchestrator polling) - Runs as non-root user (recommended)
- Handles SIGTERM gracefully
Example Dockerfile (NestJS)
Database Configuration
PostgreSQL (Default)
MySQL
MongoDB
GitHub Webhook Configuration
Webhooks are automatically created by the CLI. Manual configuration:- Go to repository Settings > Webhooks
- Add webhook:
- Payload URL:
http://YOUR_SERVER_IP/webhook/github - Content type:
application/json - Secret: From
~/.preview-deployer/config.yml - Events: Select “Pull requests”
- Active: Checked
- Payload URL:
Logging Configuration
Orchestrator Logs
Location:/opt/preview-deployer/logs/
orchestrator.log: Application logsorchestrator-error.log: Error logs
Docker Logs
View container logs:Nginx Logs
Location:/var/log/nginx/
access.log: Access logserror.log: Error logs