Home/Docs/Configuration

Configuration

One YAML file defines the deployment graph.

TurboCI stores the deployment model in `.turboci/config.yaml`: provider selection, service shapes, runtime hooks, health checks, and balancer relationships all live in the same file.


1 config

holds the provider, service, runtime, and rollout model

Instances x clusters

determines total fleet size and rollout boundaries


.turboci/config.yaml
yaml
- deployment_name: my_deployment provider: hetzner location: ash description: My first deployment services: web: instances: 2 clusters: 1 server_type: cpx21 dir_mappings: - src: . dst: /app run: start: work_dir: /app cmds: - npm start

Deployment fields

Top-level deployment properties

These fields shape the cloud target and define how a deployment relates to other deployments.


deployment_name

Unique identifier for the deployment. Use lowercase letters and underscores so the deployment can be referenced consistently by the CLI.

field
yaml
deployment_name: web_production

provider

The target cloud provider. TurboCI accepts `hetzner`, `aws`, `gcp`, and `azure` and resolves the matching environment variables automatically.

field
yaml
provider: hetzner

location

Provider-specific region or location. Use `turboci spec` to list the supported values before choosing one.

field
yaml
location: ash

availability_zone

For providers that support availability zones (e.g., AWS), specify the zone within the region.

field
yaml
availability_zone: us-east-1a

description

Optional human-readable context for operators who need to distinguish deployments quickly.

field
yaml
description: Production deployment on Hetzner

duplicate_deployment_name

Clone the full configuration of another deployment and override only the fields that differ in the new target.

field
yaml
duplicate_deployment_name: web_production

relay_server_options

Options for the relay server provisioned for this deployment. Use `server_type` to control the relay machine size.

field
yaml
relay_server_options: server_type: cpx21

pre_deployment

Commands to run on your local machine before the deployment starts — not on the remote server. Useful for local builds that must complete before code is synced.

field
yaml
pre_deployment: work_dir: ./frontend cmds: - bun install - bun run build

env / env_file

Environment variables applied to all services in this deployment. Use `env` for inline key-value pairs or `env_file` to load from a file.

field
yaml
env: NODE_ENV: production DATABASE_URL: postgres://... # or env_file: ./secrets/prod.env

Service fields

Per-service controls

Each service inside a deployment can tune image choice, instance sizing, rollout shape, and inheritance.


type

Service type. Use `default`, `load_balancer`, or `docker`. If omitted, TurboCI treats the service as a standard VPS workload.

field
yaml
type: load_balancer

os

Operating system image. On Hetzner this defaults to `debian_12`, with provider-appropriate equivalents on other clouds.

field
yaml
os: debian_12

server_type

Instance size as defined by the provider. Use `turboci spec` to inspect the valid shapes.

field
yaml
server_type: cpx21

enable_public_ip

Public IP addresses are disabled by default except on load balancer services. Set this explicitly when a service must be exposed.

field
yaml
enable_public_ip: true

instances

The number of servers created inside each cluster.

field
yaml
instances: 3

clusters

The number of rollout groups. Total servers equals `instances * clusters`, and clusters update one at a time.

field
yaml
clusters: 2

init

Commands to run once on first initialization of a server, before any other run commands. Useful for one-time setup like seeding a database.

field
yaml
init: - cp /setup/init.sh /usr/local/bin/init - chmod +x /usr/local/bin/init - /init

logs

An array of commands used to stream or collect logs from the service in the admin panel. Each entry is either a plain string or an object with a `cmd` key.

field
yaml
logs: - journalctl -u myapp -f - cmd: tail -f /var/log/myapp/error.log

duplicate_service_name

Clone another service definition and override only the settings that differ for the new service.

field
yaml
duplicate_service_name: web_prod

Runtime assets

How files, dependencies, and commands are modeled


Directory mappings

Map local files or directories onto the server filesystem. The files sync to the relay first, then out to the service servers.

dir_mappings
yaml
dir_mappings: - src: . dst: /app - src: ./secrets/prod.env dst: /app/.env ignore_file: .gitignore use_gitignore: true relay_ignore: - node_modules - .git

Dependencies

Install packages with the underlying OS package manager or through TurboCI's cross-platform dependency helpers.

dependencies
yaml
dependencies: apt: - rsync - neofetch turboci: - docker - bun - node

Run commands

Attach preflight, start, and postflight command groups to each service. TurboCI executes them in order during the rollout.

run
yaml
run: preflight: work_dir: /app cmds: - bun add -g pm2 - bun install - bunx next build start: work_dir: /app cmds: - pm2 start "bunx next start" postflight: cmds: - pm2 list

Health checks

Gate promotion on a passing command

TurboCI runs the health check up to five times with five-second delays. If the expected string never appears in the output, the rollout stops.

healthcheck
yaml
healthcheck: cmd: curl http://localhost:3000/api/healthcheck test: Server Running

The cmd runs on the target server, and test must appear in the command output for the cluster to be promoted.

Load balancing

Attach a reverse proxy with target services and SSL

Use `type: load_balancer` to provision an NGINX reverse proxy and connect it to upstream services.

load_balancer
yaml
services: web: instances: 2 clusters: 2 load_balancer: type: load_balancer ssl: email: admin@example.com target_services: - service_name: web port: 3000 domains: - example.com - www.example.com - service_name: web_dev port: 3000 domains: - dev.example.com

Domains must already point at the balancer's public IP before running turboci up so Certbot can provision and renew the certificates.


Complete example

A production deployment with a load balancer and a cloud duplicate


complete-config
yaml
- deployment_name: test provider: hetzner location: ash description: Production deployment on Hetzner services: web: instances: 2 clusters: 2 server_type: cpx21 dir_mappings: - src: . dst: /app - src: ./secrets/prod.env dst: /app/.env dependencies: apt: - rsync turboci: - bun - node run: preflight: work_dir: /app cmds: - bun add -g pm2 - pm2 kill - bun install - bunx next build start: work_dir: /app cmds: - pm2 start "bunx next start" postflight: cmds: - pm2 list healthcheck: cmd: curl http://localhost:3000/api/healthcheck test: Server Running logs: - pm2 logs web load_balancer: type: load_balancer target_services: - service_name: web port: 3000 - deployment_name: test_aws provider: aws location: us-east-1 duplicate_deployment_name: test

TypeScript config

Write configuration in TypeScript instead of YAML

As an alternative to `config.yaml`, you can write `config.ts` for type safety, code reuse, and dynamic generation. Import the `TCIConfig` type from `@moduletrace/turboci`.


Array format

Simple deployment list

The simplest format — a plain array of deployment objects exported as the default export.

.turboci/config.ts
typescript
import type { TCIConfig } from "@moduletrace/turboci"; const config: TCIConfig = [ { deployment_name: "my_app", provider: "hetzner", location: "ash", services: { web: { instances: 2, clusters: 2, server_type: "cpx21", dir_mappings: [{ src: ".", dst: "/app" }], dependencies: { apt: ["rsync"], turboci: ["bun"] }, run: { preflight: { work_dir: "/app", cmds: ["bun install", "bun run build"] }, start: { work_dir: "/app", cmds: ['pm2 start "bunx next start"'] }, postflight: { cmds: ["pm2 list"] }, }, healthcheck: { cmd: "curl http://localhost:3000/api/healthcheck", test: "Server Running", }, }, }, }, ]; export default config;

Object format

With global environment variables

Use the object format to define global environment strings that apply across all deployments.

.turboci/config.ts
typescript
import type { TCIConfig } from "@moduletrace/turboci"; const config: TCIConfig = { envs: ["NODE_ENV=production", "REGION=us-east"], deployments: [ { deployment_name: "my_app", provider: "hetzner", location: "ash", services: { web: { instances: 2, server_type: "cpx21", dir_mappings: [{ src: ".", dst: "/app" }], run: { start: { work_dir: "/app", cmds: ['pm2 start "bun server.ts"'] }, }, }, }, }, ], }; export default config;

Next step

Put the configuration behind the CLI

Once the deployment file is modeled, the CLI becomes the control surface for bootstrapping, pushing, targeting, and tearing it down.

Continue to CLI commands