Self Host Ploy
Deploy Ploy on your own infrastructure using Docker.
Self Host Ploy
Ploy is an open-source serverless cloud you can run on your own infrastructure. This guide will help you deploy Ploy yourself, giving you complete control over your deployments, code, and data.
Prerequisites
- Docker (latest version) and Docker Compose
- GitHub OAuth App (for authentication)
- Domain (optional, but recommended for production)
- 2GB+ RAM (4GB+ recommended for production)
- 10GB+ disk space (more for storing deployments)
Quick Start
The fastest way to get started is with Docker Compose:
# Clone the repository
git clone https://github.com/meetploy/ploy.git
cd ploy
# Copy environment variables
cp .env.example .env
# Edit .env with your configuration (see below)
nano .env
# Start all services
docker compose up -dAfter starting, access:
- Web Dashboard: http://localhost:3002
- Documentation: http://localhost:3005
- API: http://localhost:4002
- Handler (serves deployments): http://localhost:4001
Option 1: Unified Docker Image (Simplest)
This option uses a single Docker container with all services bundled together. Perfect for testing or small deployments.
# Run the unified container
docker run -d \
--name ploy \
--restart unless-stopped \
-p 3002:3002 \
-p 3005:3005 \
-p 4001:4001 \
-p 4002:4002 \
-v ~/ploy_data:/var/lib/postgresql/data \
-v ~/ploy_fs:/app/fs \
-e AUTH_SECRET=your-secret-key-here \
-e GITHUB_CLIENT_ID=your-github-client-id \
-e GITHUB_CLIENT_SECRET=your-github-client-secret \
-e GITHUB_WEBHOOK_SECRET=your-webhook-secret \
ghcr.io/meetploy/ploy-unified:latestNote: Replace latest with a specific version from releases.
Using Docker Compose (Unified)
# Download the compose file
curl -O https://raw.githubusercontent.com/meetploy/ploy/main/infra/docker-compose.unified.yml
# Copy and configure environment
curl -O https://raw.githubusercontent.com/meetploy/ploy/main/.env.example
cp .env.example .env
# Edit .env with your configuration
# Start the service
docker compose -f docker-compose.unified.yml up -dOption 2: Separate Services (Recommended for Production)
This option runs each service in its own container, providing better scalability and resource management.
# Clone the repository
git clone https://github.com/meetploy/ploy.git
cd ploy
# Configure environment
cp .env.example .env
# Edit .env with your configuration
# Start all services
docker compose -f infra/docker-compose.split.yml up -dServices in Split Mode
The split deployment includes:
- postgres - PostgreSQL database
- redis - Redis cache and session store
- api - REST API server
- ui - Web dashboard (Next.js)
- builder - Background job processor
- handler - Deployment handler (serves deployed apps)
- docs - Documentation site
Private service network
Only the API, UI, and deployment handler should accept traffic from outside the
service network. Keep the internal API, database service, broker, sandbox
control plane, and handler internal-delivery port private. The production
and local Compose files do this by omitting host port mappings for those
services. Direct development runs bind the internal API, database service, and
broker to 127.0.0.1 by default. Set HOST=0.0.0.0 only when the
process is already protected by a private container or host network.
To inspect a private service, run the probe inside its container instead of publishing its port. For example:
docker compose -f infra/docker-compose.split.local.yml exec internal \
wget --spider http://localhost:80/For Kubernetes or another orchestrator, enforce the same boundary with firewall
rules or NetworkPolicies: only platform services may reach the private service
ports, and only the API, broker, and cron worker may reach the handler's
internal delivery port (8081).
Required Configuration
1. GitHub OAuth App
Create a GitHub OAuth App for authentication:
- Go to GitHub Settings → Developer settings → OAuth Apps
- Click New OAuth App
- Fill in:
- Application name: Ploy
- Homepage URL:
http://localhost:3002(or your domain) - Authorization callback URL:
http://localhost:3002/api/auth/callback/github
- Click Register application
- Copy the Client ID and generate a Client Secret
2. GitHub App (for Repository Access)
Create a GitHub App for repository access and webhooks:
- Go to GitHub Settings → Developer settings → GitHub Apps
- Click New GitHub App
- Fill in:
- GitHub App name: Ploy Deployments
- Homepage URL:
http://localhost:3002 - Webhook URL:
http://localhost:4002/webhooks/github - Webhook secret: Generate a random string
- Set permissions:
- Repository permissions:
- Contents: Read
- Metadata: Read
- Webhooks: Read & Write
- Repository permissions:
- Subscribe to events:
- Push
- Repository
- Click Create GitHub App
- Generate and download a private key
- Note the App ID
3. Environment Variables
Edit your .env file with the following required variables:
# Database
POSTGRES_PASSWORD=your_secure_password_here
DATABASE_URL=postgresql://postgres:your_secure_password_here@postgres:5432/ploy
# Redis
REDIS_URL=redis://redis:6379
# Authentication
AUTH_SECRET=your-secret-key-here
BETTER_AUTH_URL=http://localhost:3002
# GitHub OAuth (for user authentication)
GITHUB_CLIENT_ID=your-github-oauth-client-id
GITHUB_CLIENT_SECRET=your-github-oauth-client-secret
# GitHub App (for repository access)
GITHUB_APP_ID=your-github-app-id
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
GITHUB_WEBHOOK_SECRET=your-webhook-secret
# API URLs
NEXT_PUBLIC_API_URL=http://localhost:4002
API_HANDLER_URL=http://handler:4001
# Deployment Storage
FS_PATH=/app/fs4. Generate Secrets
Generate secure random strings for secrets:
# Generate AUTH_SECRET
openssl rand -hex 32
# Generate GITHUB_WEBHOOK_SECRET
openssl rand -hex 32Database Storage Modes
Ploy supports two storage modes for project databases:
basicis the default. It keeps each project database as a local SQLite file insideDB_STORAGE_DIR.turso-cloudis opt-in. It provisions databases in Turso Cloud and uses Turso-managed replication and point-in-time restore.
Basic Mode
basic matches the simplest self-hosted setup and is what the bundled compose
files use by default.
Required environment variables:
DB_STORAGE_MODE=basic
DB_STORAGE_DIR=/data/db-storageUse this mode when:
- you are running Ploy on a single machine
- you want the fewest moving pieces
- you are okay with local SQLite files and handling their durability yourself
Turso Cloud Mode
Set DB_STORAGE_MODE=turso-cloud to place worker databases in Turso Cloud.
When enabled, Ploy creates Turso databases on demand and routes all worker
database traffic there.
Required environment variables:
DB_STORAGE_MODE=turso-cloud
TURSO_ORGANIZATION=your-turso-organization
TURSO_GROUP_NAME=default
TURSO_PRIMARY_LOCATION=ord
TURSO_DATABASE_PREFIX=ploy
TURSO_API_TOKEN=your_turso_platform_api_token
TURSO_GROUP_AUTH_TOKEN=your_turso_group_auth_tokenOptional:
TURSO_API_URL=https://api.turso.tech
TURSO_PITR_RETENTION_DAYS=30Use this mode when:
- you want managed replicas and failover from Turso
- you want Turso-backed point-in-time recovery
- you do not want to run your own libSQL cluster
Compose Defaults
The compose files in this repository default to:
DB_STORAGE_MODE=basic
DB_STORAGE_DIR=/data/db-storageThe older libSQL containers remain available only behind an optional
legacy-libsql compose profile and are no longer started by default.
Sandbox Provider
Sandboxes (the long-lived compute a worker drives via env.<binding>.get(id))
run on a pluggable backend, selected with SANDBOX_PROVIDER:
dockeris the default and the runtime Ploy ships. Each sandbox is a Docker container on the sandbox host, with per-project network isolation. This requires the sandbox service to have access to a Docker daemon.boatruns sandboxes on the hosted Boat provider instead. No local Docker daemon or network-isolation setup is needed — Boat manages the machines. SetBOAT_API_KEY(from the Boat dashboard; a paid Boat plan is required to create sandboxes).
To use the hosted provider, layer docker-compose.sandbox-boat.yml on top of
your split compose file. It selects boat and removes the sandbox service's
access to the host Docker daemon, which the hosted provider does not need:
docker compose -f docker-compose.split.yml -f docker-compose.sandbox-boat.yml up -dOutside Docker Compose, set SANDBOX_PROVIDER=boat on the sandbox service and
don't give it a Docker socket.
Switching an existing installation from docker to boat: Boat can't reach the
Docker host, so it can't remove sandboxes the Docker provider created. Destroy
them first (or remove their ploy-sbx-* containers and volumes on the old host
afterwards); otherwise their files and credentials stay there. The sandbox
service warns at startup while such sandboxes exist.
Boat account and API key
Use a dedicated Boat account or organization per environment, with no human
members: everyone in a Boat organization can open, SSH into, fork and download
its sandboxes. Set BOAT_ORG to create sandboxes in that organization.
Give the sandbox service a scoped, expiring key, never an admin key:
boat api-key create ploy-sandbox --ttl 365d \
--actions sandbox.create,sandbox.read,sandbox.update,sandbox.resume,sandbox.stop,sandbox.delete,exec,file.read,file.write,account.readAdd snapshot.read only if you use a template (BOAT_TEMPLATE); it also lets
the key read the saved disks of the sandboxes it can access. The key cannot
write snapshots, so it can't change your templates. Rotate it before it
expires. The sandbox service logs a warning at startup when the key is
unrestricted; set BOAT_REQUIRE_SCOPED_KEY=true to refuse to start instead.
Boat may temporarily answer scoped-key creation with a 503 while it rolls out
credential changes; retry later.
Configuration
BOAT_API_KEY=your-scoped-boat-api-key
# Public https URL of the AI gateway (the API's /ai route). Boat machines run
# outside your network, so the compose default (http://internal:80/ai) can't
# work; the service refuses to start with an http:// or internal URL.
SANDBOX_AI_URL=https://api.your-domain.com/ai
# Optional:
# BOAT_ORG=ploy-production # organization to create sandboxes in
# BOAT_TEMPLATE=ploy-sandbox # start sandboxes from a template
# BOAT_TEMPLATE_SNAPSHOT_ID=... # refuse launches if the template changed
# BOAT_MACHINE_TYPE=small # small | default | large
# BOAT_TTL_SECONDS=86400 # auto-archive backstop (0 disables)
# BOAT_BASE_URL=https://boat.dev/api/v1 # API endpoint (must be https)
# BOAT_REQUIRE_SCOPED_KEY=true # refuse an unrestricted key
# SANDBOX_RETENTION_DAYS=30 # destroy sandboxes idle this long
# SANDBOX_LOG_EXEC=1 # log command output (customer data)Ploy's idle sweeper suspends and resumes sandboxes the same way on both
providers, and a single command is capped at 10 minutes on both (use background
processes for longer work). Boat counts BOAT_TTL_SECONDS from when a sandbox
starts or resumes, not from its last activity, so it is only a backstop for
sandboxes Ploy lost track of.
What Boat stores, and for how long
- Disks. A stopped sandbox is archived with its whole filesystem, which includes your customers' code and anything their commands wrote. Boat runs machines in the EU.
- Environment and commands. Boat keeps each sandbox's launch environment and the text of the commands it runs. Ploy keeps credentials out of both: per-command environment variables and git tokens go through short-lived files inside the sandbox, and the AI token (valid for one hour, refreshed while the sandbox runs) lives in a private file rather than the launch environment.
- Retention. Sandboxes suspended or stopped for longer than
SANDBOX_RETENTION_DAYS(default 30;0keeps them) are destroyed, as are all sandboxes of a deleted project. Destroying deletes the machine and its snapshots; Boat erases the data in the background, which can take up to a few hours. The service also deletes Boat sandboxes it created but no longer tracks. - Network. Sandboxes have unrestricted outbound internet access; Ploy's
per-project egress filtering applies only to the Docker provider. The sandbox
image (
SANDBOX_DEFAULT_IMAGE) is ignored.
Sandboxes never receive your Boat account's own GitHub token, secrets, or agent
logins. Where your setup allows it, give the sandbox service a database role
that can read and write only the sandbox table and read the project table.
Preinstalled tooling on Boat
Boat sandboxes start from Boat's stock Ubuntu machine, which already includes
Node.js, Python, Go, Rust, Docker, the GitHub CLI, Claude Code, Codex, and
OpenCode. To add more, build a template (a Boat named snapshot) and point
BOAT_TEMPLATE at it. The bundled template adds the Empryo agent and pins the
other agents' versions:
pnpm turbo run build --filter=sandbox
BOAT_API_KEY=your-template-builder-key pnpm --filter sandbox boat:template ploy-sandboxFrom a running sandbox service container, run
node dist/boat-template.js ploy-sandbox instead.
This creates a sandbox, installs the tooling, saves it as the ploy-sandbox
template, deletes the build sandbox, and prints the template's snapshot id. Set
BOAT_TEMPLATE_SNAPSHOT_ID to it: the sandbox service then refuses to launch if
the template is replaced by anything else. Building a template needs a key that
may write snapshots (for example the ci preset); use it only for this and
keep it out of the sandbox service. Code running inside a sandbox cannot save or
replace templates. Re-run the build to refresh the tooling, then update the
pinned id; sandboxes already running are unaffected.
Production Configuration
For production deployments, consider these additional settings:
Domain Setup
- Point your domain to your server's IP
- Update environment variables:
# Frontend URL
BETTER_AUTH_URL=https://ploy.yourdomain.com
NEXT_PUBLIC_API_URL=https://api.yourdomain.com
# Update GitHub OAuth callback
# In GitHub OAuth App settings, set callback to:
# https://ploy.yourdomain.com/api/auth/callback/github
# Update GitHub App webhook URL
# In GitHub App settings, set webhook to:
# https://api.yourdomain.com/webhooks/githubSSL/TLS Certificates
Use a reverse proxy like Nginx or Caddy for SSL:
Caddy Example
Create a Caddyfile:
(ploy_upstream) {
transport http {
keepalive 3s
}
}
ploy.yourdomain.com {
reverse_proxy localhost:3002 {
import ploy_upstream
}
}
api.yourdomain.com {
reverse_proxy localhost:4002 {
import ploy_upstream
}
}
*.ploy-deployments.yourdomain.com {
reverse_proxy localhost:4001 {
import ploy_upstream
}
}Run Caddy:
caddy runThe reverse proxy terminates TLS and forwards plain HTTP to the handler, so the
handler cannot tell how the client connected. Tell it with PUBLIC_PROTOCOL,
which is the protocol worker code sees in request.url:
# Deployments are served over https by the reverse proxy
PUBLIC_PROTOCOL=httpsIt defaults to https when NODE_ENV=production and http otherwise. Set
PUBLIC_PROTOCOL=http if your deployments are served without TLS.
Keep the proxy's idle upstream timeout below 5 seconds.
Every Ploy service closes an idle keep-alive connection after 5 seconds, and the
deployment runtime resets rather than cleanly closes it. Proxies pool upstream
connections for much longer by default (Caddy 2m, Nginx 60s), so a pooled
connection can be reused at the same instant the upstream tears it down. A
request with a body is never replayed, so the caller gets a 502 with an empty
body while the upstream — reset before it read the request — never runs or logs
it. If passive health checks are enabled, that reset also pulls the upstream out
of rotation and every host behind the proxy serves 503 for a few seconds
before recovering on its own.
Retiring idle connections first (keepalive 3s in the ploy_upstream snippet
above, or keepalive_timeout 3s in an Nginx upstream block) closes the race.
Resource Limits
Add resource limits to your docker-compose.yml:
services:
api:
deploy:
resources:
limits:
cpus: "1"
memory: 1G
reservations:
cpus: "0.5"
memory: 512MWorker CPU Limits
Each invocation of a deployed worker gets a CPU time budget from its
organization's plan. Organizations on a self-hosted instance use the
Free limits unless you assign a plan or override them. Set these on the
internal service (or the unified container); 0 turns a limit off:
| Variable | Default (Free / Pro / Enterprise) |
|---|---|
WORKER_CPU_LIMIT_MS_<PLAN> | 1000 / 5000 / 30000 |
WORKER_CPU_LIMIT_MS_QUEUE_<PLAN> | 5000 / 30000 / 60000 |
WORKER_CPU_LIMIT_MS_TIMER_<PLAN> | 5000 / 30000 / 60000 |
WORKER_CPU_LIMIT_MS_CRON_<PLAN> | 10000 / 60000 / 120000 |
WORKER_CPU_LIMIT_MS_WORKFLOW_<PLAN> | 15000 / 120000 / 300000 |
<PLAN> is FREE, PRO, or ENTERPRISE, for example
WORKER_CPU_LIMIT_MS_CRON_FREE=60000. The first row applies to HTTP requests.
The startup limit for a worker's top-level code is set on the handler
service with WORKER_STARTUP_CPU_LIMIT_MS (default 5000, 0 turns it off).
All deployments on a handler share one JavaScript thread, so these limits are what stop one runaway deployment from stalling the others. Raise them rather than turning them off.
Monitoring
Enable logging and monitoring:
# View logs for all services
docker compose logs -f
# View logs for specific service
docker compose logs -f api
# View resource usage
docker statsManagement Commands
Docker Compose (Unified)
# Start services
docker compose -f docker-compose.unified.yml up -d
# View logs
docker compose -f docker-compose.unified.yml logs -f
# Restart services
docker compose -f docker-compose.unified.yml restart
# Stop services
docker compose -f docker-compose.unified.yml down
# Stop and remove volumes
docker compose -f docker-compose.unified.yml down -vDocker Compose (Split)
# Start all services
docker compose -f infra/docker-compose.split.yml up -d
# Start specific service
docker compose -f infra/docker-compose.split.yml up -d api
# View logs
docker compose -f infra/docker-compose.split.yml logs -f
# Restart services
docker compose -f infra/docker-compose.split.yml restart
# Stop services
docker compose -f infra/docker-compose.split.yml downDatabase Operations
# Backup database
docker exec ploy-postgres pg_dump -U postgres ploy > backup.sql
# Restore database
docker exec -i ploy-postgres psql -U postgres ploy < backup.sql
# Access database shell
docker exec -it ploy-postgres psql -U postgres ployTroubleshooting
Common Issues
Services won't start:
# Check logs
docker compose logs -f
# Verify environment variables
docker compose config
# Ensure ports are not in use
lsof -i :3002
lsof -i :4002Database connection errors:
# Check PostgreSQL is running
docker compose ps postgres
# Verify DATABASE_URL in .env
# Ensure POSTGRES_PASSWORD matches in DATABASE_URLGitHub webhook not working:
- Check webhook URL is publicly accessible
- Verify GITHUB_WEBHOOK_SECRET matches GitHub App
- Check API logs:
docker compose logs -f api - Test webhook delivery in GitHub App settings
Deployments failing:
# Check worker logs
docker compose logs -f builder
# Check handler logs
docker compose logs -f handler
# Verify FS_PATH volume is writable
docker exec ploy-builder ls -la /app/fsDebug Mode
Enable debug logging:
# Add to .env
LOG_LEVEL=debug
# Restart services
docker compose restartUpdating Ploy
To update to the latest version:
# Pull latest changes
git pull origin main
# Pull latest images
docker compose pull
# Restart services
docker compose down
docker compose up -d
# Check logs for any issues
docker compose logs -fBuild from Source
To build Ploy from source:
# Clone repository
git clone https://github.com/meetploy/ploy.git
cd ploy
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Start services with local build
docker compose -f infra/docker-compose.local.yml up -dPerformance Tuning
PostgreSQL
Optimize PostgreSQL for your workload:
# Add to docker-compose.yml postgres service
environment:
- POSTGRES_SHARED_BUFFERS=256MB
- POSTGRES_EFFECTIVE_CACHE_SIZE=1GB
- POSTGRES_MAX_CONNECTIONS=100Redis
Configure Redis memory limits:
# Add to docker-compose.yml redis service
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lruWorker Concurrency
Adjust worker concurrency:
# Add to .env
WORKER_CONCURRENCY=5Security Best Practices
- Use strong passwords for database and secrets
- Enable HTTPS in production with valid SSL certificates
- Keep secrets secure - never commit
.envfiles - Regular backups of database and deployment files
- Update regularly to get security patches
- Firewall rules - only expose necessary ports
- Limit GitHub App permissions to minimum required
Next Steps
Once Ploy is running:
- Sign in at http://localhost:3002 (or your domain)
- Create an organization and project
- Connect a repository and deploy your first app
- Configure custom domains for production deployments
- Explore the API at http://localhost:4002/docs
Support
- Documentation: https://docs.meetploy.com
- GitHub Issues: https://github.com/meetploy/ploy/issues
- Community: Join our Discord or discussions
Happy self-hosting! ✨
Sandboxed builds
Operators can run deployment builds in isolated sandboxes while keeping deployment orchestration, database migrations, and artifact uploads in the builder. Customers continue using the same deployments and build logs.
Set these variables on the builder:
BUILD_EXECUTOR=sandbox
SANDBOX_URL=http://sandbox:80
SANDBOX_AUTH_TOKEN=replace-with-your-control-plane-token
# Optional rollout: comma-separated organization IDs; empty enables all.
BUILD_EXECUTOR_ORGANIZATIONS=The sandbox service selects Docker or Boat through SANDBOX_PROVIDER. A failed
sandbox build never falls back to executing customer code inside the builder.
Sandbox builds require a GitHub App installation that can issue repository-scoped,
read-only clone credentials.
For Docker, use BUILD_SANDBOX_IMAGE to select a pinned build runtime image. The
published image is ghcr.io/meetploy/ploy-build-runtime. For local development,
build it with pnpm sandbox:build-image and set
BUILD_SANDBOX_IMAGE=ploy-build-runtime. The sandbox service must have
SANDBOX_NETWORK_ISOLATION=true. Build sandboxes use a separate network and egress
proxy, without the private-service exceptions of regular customer sandboxes.
For Boat, create the build template from the repository root after building the sandbox service:
pnpm turbo run build --filter=sandbox
pnpm --filter sandbox boat:template ploy-buildSet BUILD_SANDBOX_TEMPLATE=ploy-build and the printed
BUILD_SANDBOX_TEMPLATE_SNAPSHOT_ID on the builder. Set
BUILD_SANDBOX_MACHINE_TYPE when an explicit machine size is needed. Organization
owners and admins can override the size under Settings → Preferences → Build
Machine (small, default, large or xlarge; Boat's xlarge needs its
$100 plan or higher). On Docker the override sets the CPU and memory limits to
the same sizes, so the sandbox host needs that capacity. Changing the size keeps
each branch's build cache; the next build resumes on the new size. The template
contains the build toolchain, without Ploy AI credentials or bindings. Regular
customer sandboxes retain their existing AI functionality.
Each project and branch reuses its own sandbox. Different branches compile in parallel within the builder's concurrency limit; shared project updates and migrations remain serialized. Sandboxes stop after each attempt. Clearing a build's cache destroys that branch's sandbox before rebuilding.
Stopped sandboxes expire according to SANDBOX_RETENTION_DAYS on the sandbox
service (30 days by default; zero disables inactivity expiry). Deleted projects
also have their sandboxes removed. Deleting a Git branch does not cancel builds
or immediately remove its cache. Branch caches use automatic provider snapshots,
not named templates. Keep the active platform templates; remove superseded
snapshots only after no deployment configuration references them.
| Builder variable | Default | Purpose |
|---|---|---|
BUILD_EXECUTOR | local | Select local or sandbox execution. |
BUILD_SANDBOX_MEMORY_MB | 8192 | Docker memory limit. |
BUILD_SANDBOX_CPUS | 2 | Docker CPU limit. |
BUILD_SANDBOX_PIDS | 512 | Docker process limit. |
BUILD_ARTIFACT_MAX_BYTES | 2147483648 | Maximum extracted artifact bytes. |
BUILD_ARTIFACT_MAX_FILES | 100000 | Maximum artifact entries. |
The builder sends project environment variables to the build job, never its own platform credentials. Platform-created job and credential files are removed before archival. Customer build commands can still write their own environment values into generated output or caches.
Isolated database migrations
By default the builder applies customer migrations from the build output. To keep
customer database access out of the process that orchestrates untrusted builds,
run the migrator and set DB_MIGRATIONS_EXECUTOR=migrator on the builder:
# Same image as the builder, different command.
node --no-warnings --enable-source-maps dist/migrator.jsThe builder then only records a request per deployment and waits for the result.
The migrator verifies that the deployment's commit is on the repository's default
branch, checks out only ploy.yaml and .sql files at that commit (no hooks,
filters, submodules, or symlinks), applies pending migrations, prepares Ploy Auth
databases, and writes an audit row per applied migration to
database_migration_audit. It needs DATABASE_URL, ENCRYPTION_KEY, the
GitHub App credentials, Redis (for build logs), and DB_URL; once it runs, the
builder no longer needs DB_URL, so restrict the DB service to the platform
services that use it.
| Migrator variable | Default | Purpose |
|---|---|---|
DB_URL | — | DB service URL (required). |
MIGRATOR_CONCURRENCY | 4 | Deployments processed in parallel per replica. |
MIGRATOR_LEASE_MS | 60000 | Lease after which another replica takes over. |
MIGRATOR_MAX_ATTEMPTS | 3 | Interrupted attempts before a run fails. |
MIGRATOR_WORK_DIR | tmpdir | Parent directory for temporary checkouts. |
How is this guide?
Last updated on