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, orbundle 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:
agentworkspace-initdocker
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
workspacevolume 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 nonetwork_mode: host,pid: host,ipc: host,uts: host, orcontainer:-style values. - No added capabilities or devices. A service may not use
cap_add,devices,device_cgroup_rules,security_opt,cgroup_parent, orgroup_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
workspacevolume 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.
