Reference
forkdeploy.yaml
A single config file at the root of your repo that tells ForkDeploy how your monorepo is structured: which services exist, how they wire together, and what order to deploy them.
What is it?
Drop forkdeploy.yaml at the repo root alongside your package.json (or go.mod, composer.json, etc.) and ForkDeploy will:
- Know which services your project contains
- Build or pull each service's container image
- Wire services together using stable internal URLs
- Deploy them in the right order based on their dependencies
The file is optional. You can also manage services through the dashboard or the REST API directly. But the yaml is the fastest way to define a full project from scratch.
Minimal example
One service, one file. Push the repo and ForkDeploy builds it.
# forkdeploy.yaml
project: my-app
services:
web:
build: .
port: 3000 Full schema
project: <string> # required, becomes the project slug
services:
<service-name>: # required, one entry per service
image: <string> # Docker image to pull. Mutually exclusive with build.
build: <path> # Relative path to build context (must contain Dockerfile).
port: <number> # Port the container listens on.
replicas: <number> # Running instances. Default: 1.
depends_on: # Services that must be running first.
- <service-name>
env: # Environment variables injected at runtime.
KEY: value
OTHER: "{{ <service-name>.url }}" # service discovery | Field | Type | Required | Description |
|---|---|---|---|
| project | string | yes | Project name. Becomes the URL slug. Use lowercase and hyphens. |
| services | map | yes | Map of service name to config. At least one entry required. |
| services.*.image | string | one of | Pre-built Docker image (e.g. postgres:16). Cannot be used with build. |
| services.*.build | string | one of | Relative path to the build context. A Dockerfile must exist there. |
| services.*.port | number | no | Port the container process listens on. Used for internal routing. |
| services.*.replicas | number | no | Number of instances to run. Defaults to 1. |
| services.*.depends_on | string[] | no | Service names this service waits for before starting. |
| services.*.env | map | no | Key/value env vars. Values may use {{ service.url }} templates. |
Service discovery
Services in the same project can reference each other using template variables in
env values:
{{ <service-name>.url }} ForkDeploy resolves this at deploy time to:
http://<service-name>.<project-slug>.internal shop, writing {{ database.url }} in your env becomes http://database.shop.internal at runtime. If a service restarts or moves, the DNS stays the same. No hard-coded IPs.
Examples
Three-service monorepo
Database, API that needs it, frontend that needs the API.
project: shop
services:
database:
image: postgres:16
port: 5432
env:
POSTGRES_DB: shop
POSTGRES_USER: shop
POSTGRES_PASSWORD: shop
api:
build: ./apps/api
port: 8080
depends_on: [database]
env:
DATABASE_URL: "{{ database.url }}"
NODE_ENV: production
web:
build: ./apps/web
port: 3000
depends_on: [api]
env:
API_URL: "{{ api.url }}" With replicas and a worker
Scale individual services independently.
project: saas-prod
services:
cache:
image: redis:7-alpine
port: 6379
worker:
build: ./apps/worker
replicas: 3
depends_on: [cache]
env:
REDIS_URL: "{{ cache.url }}"
api:
build: ./apps/api
port: 8080
replicas: 2
depends_on: [cache, worker]
env:
REDIS_URL: "{{ cache.url }}" forkdeploy.yaml. Add them through the dashboard (Projects, then Secrets) and they'll be injected at runtime
without appearing in your repo. More on this on the
security page.
Deploy order
ForkDeploy reads all depends_on fields, builds a dependency graph, and deploys services in topological order.
- ✓ Services with no depends_on deploy first, in parallel.
- ✓ A service only starts after all its dependencies reach running state.
- ✓ Two services with no relationship between them deploy in parallel.
- ✓ Circular dependencies (A needs B needs A) are rejected and the deploy fails immediately.
Where to put it
Always at the repo root. The file must be named exactly
forkdeploy.yaml
or
forkdeploy.yml.
my-monorepo/
├── forkdeploy.yaml ← here, at the root
├── package.json
├── apps/
│ ├── api/
│ │ └── Dockerfile
│ └── web/
│ └── Dockerfile
└── packages/
└── ... Relationship to the API
Every field in forkdeploy.yaml maps directly to a field in the ForkDeploy data model. You can manage the same resources
through the dashboard or REST API if you prefer not to use the file at all.
| YAML field | API resource |
|---|---|
| project | Project.name / Project.slug |
| services.<name> | Service.name |
| build | Service.buildContext |
| image | Service.image |
| port | Service.port |
| replicas | Service.replicas |
| depends_on | Service.dependsOn |
| env | Service.env |