Run a coding agent 24/7
Label a GitHub issue, get a pull request. Your own Anthropic key, your review, always on.
This template runs Claude Code, Anthropic's coding agent, headless on Dockhold with your own Anthropic API key. You put a label on a GitHub issue in one repository; the agent works on the issue and opens a pull request with its change. You review and merge. It keeps running when your laptop is closed.
Claude Code is made by Anthropic. The template installs it unmodified when the image is built, and you use it under Anthropic's terms (legal and compliance). The template is Dockhold's, not Anthropic's.
1. Make two keys
- Anthropic API key. Create one in the Claude Console, for this app alone, so you can see its spend and revoke it on its own.
- GitHub token. On GitHub, open Settings, Developer settings, Personal access tokens, Fine-grained tokens, and generate a new token. Under Repository access pick Only select repositories and choose the one repository the agent works on. Under Permissions set Contents, Issues and Pull requests to Read and write.
2. Open the deploy link
Start from the coding-agent-starter template. Open the deploy link and sign in if asked.
3. Size it, add App storage, make it private
Under App size, pick 1 GB ($10 a month, a paid size). Under App storage, turn it on and pick 10 GB: it holds the checkout, the agent's home folder and the task log. Under Visibility, pick Private. The agent only calls out to GitHub and Anthropic, so nothing needs to reach it, and its status page, which shows your repository and issue titles, stays yours. If you don't see Visibility yet, make the app private on its Access tab once it is deployed.
4. Add your secrets and the repository
Under Environment, in the Secrets list, click New secret for each value, tick it, and set its Env var name as below. Give the entries names that belong to this app, because secrets are shared across your apps by name and two apps that share an entry would share a key.
| Secret (your name) | Env var name | Value |
|---|---|---|
coding-agent-anthropic-key | ANTHROPIC_API_KEY | Your Anthropic API key |
coding-agent-github-token | GITHUB_TOKEN | The fine-grained GitHub token |
coding-agent-dockhold-token (optional) | DOCKHOLD_API_TOKEN | A Dockhold API token, see Security below |
Then add a plain variable AGENT_REPO with the repository as
owner/name, for example octo-org/website.
5. Deploy
Click Deploy and wait until the app shows as running. Its address shows a status page with the repository, the label and the next poll. A private app asks you to sign in first: create a token on the app's Access tab and paste it into the password field.
6. Hand it an issue
In the repository on GitHub, create a label named agent.
Open an issue that describes one change, and add the label. Within 10
minutes the agent picks it up, removes the label and works on it.
Follow it on the app's Activity tab. When it is done, a
pull request is open and the issue has a comment with its link and the
run's cost.
If the app refuses to start, its page shows one line saying what is missing. App storage is on the app's Size tab; secrets are attached on its Variables tab and their values are edited under Secrets in the dashboard sidebar. Fix it and click Restart.
How it works
- Every 10 minutes the app lists the open issues that carry the label, oldest first, and claims one by removing the label.
- It fetches your default branch into App storage, makes the branch
agent/issue-<number>and runs Claude Code on it. The prompt is the issue's title and body, plus your repository'sCLAUDE.mdif it has one. - When the agent is done, the app commits the change, pushes that branch and opens a pull request with the agent's summary,
Closes #<number>and the cost. It never pushes any other branch and cannot merge; you do. - One task runs at a time. A task cut short by a restart goes back in the queue on its own.
Security
An agent does what an issue says. An issue runs only when its author has write access to the repository, and issue comments are never read. Review every pull request the agent opens the way you would review a stranger's.
The agent never sees the GitHub token. It is limited to one repository and stays in the app's own program; the agent's processes cannot read it. The agent can read your Anthropic key, since it needs it to work, so use a key for this app alone.
The Dockhold token is optional. With it, the agent gets the Dockhold MCP server and can deploy what it builds to your account. Create it under API tokens in the dashboard sidebar as Read & deploy, or Read-only if the agent only needs to look. It works on every app in your account, not only this one.
Pin what runs. Build again on the app page rebuilds from the template's latest commit. To control exactly what code holds your keys, click Use this template on GitHub and deploy your own copy.
Settings
| Variable | Default | What it does |
|---|---|---|
AGENT_REPO | (required) | The repository, as owner/name |
AGENT_LABEL | agent | The label that hands an issue to the agent |
AGENT_POLL_MINUTES | 10 | Minutes between polls, 1 to 1440 |
AGENT_MODEL | sonnet | A model alias such as sonnet or opus, or a full model name |
AGENT_ALLOWED_TOOLS | Read,Edit,Write,Glob,Grep,Bash | Tools the agent may use without asking, for example Read,Edit,Bash(npm test *) |
AGENT_MAX_BUDGET_USD | 2 | Spend cap per task, in US dollars |
AGENT_TASK_MINUTES | 60 | Time cap per task, 1 to 1440 |
Change one on the app's Variables tab and click Restart.
Costs
- The app: 1 GB is two 512 MB units, $10 a month. See pricing. If a task runs out of memory while it installs or tests your repository, raise the size on the app's Size tab.
- The model: you pay Anthropic directly with your own API key. Dockhold never pays for it, resells it or adds to it. Each task stops at
AGENT_MAX_BUDGET_USD, and each pull request shows the run's cost. - Use an API key, not a Claude subscription: Anthropic's terms say subscription limits assume ordinary individual use. The template reads only
ANTHROPIC_API_KEY.
The full reference (what App storage holds, every limit, upgrading) is in the template's README.