Project Configuration

Every project has a small set of configuration that shapes how its agents run: a setup script that prepares the workspace, an optional Docker Compose file for services your code depends on, and an execution target that decides where agents run. You manage all of it from your project's Settings in the dashboard, and the saved values apply to every agent session for that project.

This guide explains each setting and how to use it.

Setup script

The setup script (setup.sh) runs at the start of every agent session, before the agent begins work. Your repository is already checked out at /workspace, and the script runs from there, so it is the place to get the workspace ready: install dependencies, fetch tools, and do any one-time preparation your code needs to build and test.

Typical uses:

  • Install dependencies — for example pnpm install, npm ci, pip install -r requirements.txt, or bundle install.
  • Run a framework or build CLI that prepares the project (code generation, database setup for a local dev server, asset compilation).
  • Any other one-time setup the agent should not have to repeat by hand.

A short example:

#!/bin/bash
set -euo pipefail

pnpm install
pnpm prisma generate

The script is plain shell, so write it the way you would a local setup script. Leave it empty if your project needs no preparation.

Compose file for sibling services

Some projects need other services running alongside the agent — a Postgres database, a Redis cache, or any other dependency your tests and tools talk to. The Docker Compose YAML lets you declare those sibling services. When set, they are brought up alongside the agent on self-hosted runners and torn down when the session ends, so nothing lingers between runs.

The file is standard Docker Compose. Declare each dependency as a service under services:. For example, a Postgres database the agent can connect to:

services:
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: dev
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U dev"]
      interval: 3s
      retries: 30

Reserved service names

A few service names are reserved and cannot be used in your compose file:

  • agent
  • workspace-init
  • docker

If you name a service one of these, the file is rejected. Pick a different name (for example db instead of agent).

Sharing the repository with a sibling

Your repository lives on a volume named workspace. If a sibling service needs to read the checked-out code — say a service that loads fixtures or runs against your source — mount that volume into the service:

services:
  fixtures:
    image: my-loader:latest
    volumes:
      - workspace:/repo

Mounting the named workspace volume is the supported way to give a sibling access to the repository. (See the restrictions below — binding a path from the host machine is not allowed.)

Compose restrictions

Sibling services run next to your agent on the same machine, so the compose file is checked against a few safety rules before it is saved. Within these bounds you can run essentially any service:

  • No privileged containers. A service may not set privileged: true.
  • No host filesystem bind mounts. Services may only use named volumes (like the workspace volume above). A service may not mount a path from the host machine, and a named volume may not be defined as a bind to a host path.
  • No host namespace sharing. A service may not share the host's (or another container's) network, PID, IPC, or UTS namespace, and may not set userns_mode: host. In practice that means no network_mode: host, pid: host, ipc: host, uts: host, or container:-style values.
  • No added capabilities or devices. A service may not use cap_add, devices, device_cgroup_rules, security_opt, cgroup_parent, or group_add.

Fixing a rejected file

If a compose file is rejected when you save it, the dashboard tells you which service and which directive caused the rejection — for example that a service "must not bind-mount the host filesystem" or "must not run privileged." To fix it:

  • Remove the flagged directive from that service.
  • If you were bind-mounting a host path to share files, switch to a named volume instead (such as the workspace volume for your repository).
  • If you used a reserved service name, rename the service.

Most services from public images (databases, caches, message brokers, and the like) work without any of the restricted directives, so a standard service definition usually passes as-is.

Execution target

The execution target decides where your agents run. You choose it per project, and you can change it later.

  • Cloud — agents run in managed, isolated environments that SetForth provisions for you. There is nothing to install or keep online, and on eligible plans an environment is started automatically when a task is ready.
  • Self-hosted — agents run on a runner you operate on your own hardware. This requires a registered, online runner for your organization. See the Self-Hosted Runner guide to set one up. Use this when you need your own toolchain, access to private network resources, or to keep code on machines you control.
  • Auto — either the cloud or one of your online self-hosted runners can run the work, whichever is available. The cloud is used when no self-hosted runner is online. This is a good default if you want managed environments but also want your own runners to handle work whenever they are available.

If you choose self-hosted and have no runner online, agent work waits until a runner is available, so register a runner before relying on it.