Install with Docker Compose
To fully customize the Waterwheel agent in a Docker environment, you can use Docker Compose to bring up the container using the instructions in this document.
These instructions work on macOS / Linux and Windows (PowerShell). Only
the folder-setup script in step 1 differs between platforms; use the tabs to pick
your shell. All docker compose commands are identical everywhere.
Installation
1. Create the Folder Structure
Run the helper script for your platform to create the local folder structure used for Docker volume mapping. If you omit the path, the current directory is used; if the path does not exist, it is created for you.
- macOS / Linux
- Windows (PowerShell)
Use create-sync-subfolders.sh:
chmod +x create-sync-subfolders.sh
./create-sync-subfolders.sh /path/to/sync
Use create-sync-subfolders.ps1:
./create-sync-subfolders.ps1 C:\path\to\sync
If PowerShell blocks the script, allow it for the current session first:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
This produces the directory layout that Docker Compose maps into the container:
<sync>/
└── agent/
├── instructions/ → /agent/instructions (config files)
├── tasks/ → /agent/tasks (your .md test files)
├── skills/ → /agent/skills (your test skills, read-write)
└── outputs/ → /agent/outputs (results and logs written by the agent)
Because these folders are bind-mounted, anything you place under
agent/instructions on the host becomes the agent's runtime configuration. See
Configuration Files for what each file does.
agent/skills is mounted read-write rather than read-only, so
load-test-skills and
delete-test-skills inside the
container write through to the host — you can author skills in either place and see them
in both. The mount covers user skills only; the image's built-in ww: skills live
elsewhere and are never shadowed by it.
2. Configure Environment Variables
Open dot_env.txt and fill in the following variables.
WATERWHEEL_SYNC_VOLUME_PATH=${to_fill} # The sync folder created in step 1 (e.g. /path/to/sync or C:\path\to\sync)
API_PROVIDER=${to_fill} # AI provider
AI_MODEL=${to_fill} # AI model
AI_API_KEY=${to_fill} # AI API key
3. Place the Environment File
Rename dot_env to .env and place it in the same directory as docker-compose.yml.
4. Copy Instruction Files
Copy the following three files into agent/instructions under /path/to/sync.
You can further tune the run by adding the optional preset-context.json and
extra-instruction.md files to the same folder. See
Configuration Files for details.
5. Copy Task File
Copy test-wikipedia-english.md into /path/to/sync/agent/tasks.
6. Add Test Skills (Optional)
Skip this step if you have no skills yet — the sample task does not need one, and the built-in skills ship inside the image.
To bring your own, give each skill its own subfolder under /path/to/sync/agent/skills,
holding a single SKILL.md:
<sync>/agent/skills/
└── login-test-site/
└── SKILL.md
Because the folder is bind-mounted, skills placed here are available on the next run — no
load-test-skills call and no container restart. See
Create Test Skills for how to write one and how
the agent decides to use it.
Test skills require agent image 1.4.0 or newer — the version dot_env.txt pins. On an
older image the skills/ mount is created and simply ignored.
7. Deploy the Docker Container
From the same directory as docker-compose.yml, run:
docker compose up -d
Verify Installation
To verify the installation, run the following command on your local machine and confirm no errors are reported in /path/to/sync/agent/outputs/agent.log.
docker compose exec waterwheel-agent run-qa --dry-run
Execute Tests
To execute all tests under /path/to/sync/agent/tasks, run the following command on your local machine.
docker compose exec waterwheel-agent run-qa
Once the command completes, check the results at /path/to/sync/agent/outputs/test-results.json.
Configuration Files
The files under agent/instructions (mapped to /agent/instructions in the
container) control how the agent behaves. They are reloaded every time run-qa
is called, so you can edit them on the host and simply start the next run — no
container restart needed.
See Configuration Files for what each file does, its format, and the commands that maintain it.