Agent rules
Drop one of these into your project so your AI coding tool generates apps that deploy on Dockhold with no edits.
They all say the same thing in each tool's format: how Dockhold deploys,
where config and secrets go, and the one rule that trips up most generated
apps — listen on 0.0.0.0:$PORT. Pick the file your tool reads.
.cursorrules (Cursor)
Save at your repo root as .cursorrules:
# Dockhold deploy rules
Deploy target: Dockhold (https://dockhold.eu).
How deploys work:
- Two deploy paths. Code in a GitHub repo: connect it once at https://app.dockhold.eu, then deploy by pushing to the main branch. Code only local (no git remote): deploy with the Dockhold CLI (see the local-code block below). Never invent another deploy method.
- Dockhold auto-detects the stack (Node, Python, Go, Rust, Ruby, Deno, Bun, Java, PHP). To control the build, add a Dockerfile at the repo root, or a dockhold.json with {"build":{"dockerfile":"path/to/Dockerfile"}}.
App requirements:
- Listen on 0.0.0.0 and the port from the PORT environment variable. Never hardcode a port or bind to localhost.
- Read all configuration from environment variables.
- Do not commit secrets. Set secrets (API keys, tokens, passwords) in the Dockhold dashboard Vault; they are injected at runtime.
- PORT and DATABASE_URL are set by Dockhold — read them, never define or override them.
- For a database, enable the managed Postgres add-on and read DATABASE_URL. Do not run or configure your own database.
- Apps are stateless: the container filesystem is ephemeral and lost on restart. Persist data in the managed database, not on local disk.
- To seed the managed database with existing data (one-time, paid plan): dump it with `pg_dump -Fc --no-owner --no-privileges yourdb > backup.dump` and upload from the app's Database tab. Cap 2 GB after compression; all-or-nothing, so import into an empty database.
Local-only code (no GitHub repo):
- Run `npx dockhold login` (opens a browser once; needs Node 18+), then `npx dockhold deploy` from the project folder. It uploads the folder, builds it (your Dockerfile if present, else auto-detect), and prints the live URL.
- `.env` files are never uploaded. Set variables with `--env KEY=VALUE` (repeatable) or in the dashboard; secrets in the Vault. Add `--db` for a managed database (read `DATABASE_URL`).
- Always excluded from the upload: `.git`, `node_modules`, `.dockhold`, every `.env*` file. `.gitignore` is respected; a `.dockholdignore` file excludes more. Upload cap 500 MB.
- Ship a new version by running `npx dockhold deploy` again from the same folder. These apps have no git auto-deploy.
Multiple services that talk to each other:
- If you generate several services that call each other (e.g. a frontend and an API), do NOT hardcode one service's URL in another. Read it from an environment variable (e.g. API_URL) and call that.
- On Dockhold you deploy them as one "connected app", either in the dashboard (https://app.dockhold.eu/new → "Deploy them together") or via the MCP deploy_group tool (see MCP rules below). Add each service (a GitHub repo URL + port), then link each such variable to the sibling service by setting it to exactly ${services.<sibling>.url}. Dockhold injects that sibling's live URL into the variable.
- A service in a connected app can have its own managed database: tick "Add a managed database" on that service (usually the API, not the frontend) and read DATABASE_URL. Each database belongs to the service that enabled it; a shared database across services and bring-your-own external database are not supported yet.
- First cut: web services only, one GitHub repo per service.
Deploying via MCP (optional):
- Dockhold runs a remote MCP server at https://api.dockhold.eu/mcp. With a dh_mcp_ API token from https://app.dockhold.eu/settings/api-tokens, passed as Authorization: Bearer, an MCP client can deploy and manage apps directly.
- Tools. Read: list_apps, get_app_status, get_app_logs, list_github_repos, get_resource_usage. Read+deploy: deploy_app, redeploy_app, set_app_variable, deploy_group, resize_app, resize_database, resize_database_storage.
- deploy_app takes a GitHub repo URL and a name; poll get_app_status until the URL is live. Public repo: repo_url + name. Private repo: call list_github_repos first (each connected repo comes with its installation_id), then deploy_app with repo_url + name + github_installation_id; this also turns auto-deploy on.
- If an app runs out of memory (OOM), resize it: resize_app(app_id, memory_mb). resize_database(app_id, db_ram_mb) grows a managed DB's memory (it restarts briefly); resize_database_storage(app_id, storage_gb) grows its disk (grow-only). Call get_resource_usage first for valid sizes (its *.steps_* arrays) and to confirm the pool has room; an over-pool size is refused.
- deploy_group deploys several connected services at once: pass a services map (each with source repo URL, port, optional env, optional db:"enable"); link services by setting an env value to exactly ${services.<name>.url}; a service with db:"enable" gets its own database and reads DATABASE_URL. Returns each service's app id; poll get_app_status on each. Public repos only.
- A token only does what its owner could do in the dashboard, scoped to their account. Secrets go in the Vault, not via set_app_variable. AGENTS.md
Save at your repo root as AGENTS.md:
# Deploying on Dockhold
Deploy target: Dockhold (https://dockhold.eu).
How deploys work:
- Two deploy paths. Code in a GitHub repo: connect it once at https://app.dockhold.eu, then deploy by pushing to the main branch. Code only local (no git remote): deploy with the Dockhold CLI (see the local-code block below). Never invent another deploy method.
- Dockhold auto-detects the stack (Node, Python, Go, Rust, Ruby, Deno, Bun, Java, PHP). To control the build, add a Dockerfile at the repo root, or a dockhold.json with {"build":{"dockerfile":"path/to/Dockerfile"}}.
App requirements:
- Listen on 0.0.0.0 and the port from the PORT environment variable. Never hardcode a port or bind to localhost.
- Read all configuration from environment variables.
- Do not commit secrets. Set secrets (API keys, tokens, passwords) in the Dockhold dashboard Vault; they are injected at runtime.
- PORT and DATABASE_URL are set by Dockhold — read them, never define or override them.
- For a database, enable the managed Postgres add-on and read DATABASE_URL. Do not run or configure your own database.
- Apps are stateless: the container filesystem is ephemeral and lost on restart. Persist data in the managed database, not on local disk.
- To seed the managed database with existing data (one-time, paid plan): dump it with `pg_dump -Fc --no-owner --no-privileges yourdb > backup.dump` and upload from the app's Database tab. Cap 2 GB after compression; all-or-nothing, so import into an empty database.
Local-only code (no GitHub repo):
- Run `npx dockhold login` (opens a browser once; needs Node 18+), then `npx dockhold deploy` from the project folder. It uploads the folder, builds it (your Dockerfile if present, else auto-detect), and prints the live URL.
- `.env` files are never uploaded. Set variables with `--env KEY=VALUE` (repeatable) or in the dashboard; secrets in the Vault. Add `--db` for a managed database (read `DATABASE_URL`).
- Always excluded from the upload: `.git`, `node_modules`, `.dockhold`, every `.env*` file. `.gitignore` is respected; a `.dockholdignore` file excludes more. Upload cap 500 MB.
- Ship a new version by running `npx dockhold deploy` again from the same folder. These apps have no git auto-deploy.
Multiple services that talk to each other:
- If you generate several services that call each other (e.g. a frontend and an API), do NOT hardcode one service's URL in another. Read it from an environment variable (e.g. API_URL) and call that.
- On Dockhold you deploy them as one "connected app", either in the dashboard (https://app.dockhold.eu/new → "Deploy them together") or via the MCP deploy_group tool (see MCP rules below). Add each service (a GitHub repo URL + port), then link each such variable to the sibling service by setting it to exactly ${services.<sibling>.url}. Dockhold injects that sibling's live URL into the variable.
- A service in a connected app can have its own managed database: tick "Add a managed database" on that service (usually the API, not the frontend) and read DATABASE_URL. Each database belongs to the service that enabled it; a shared database across services and bring-your-own external database are not supported yet.
- First cut: web services only, one GitHub repo per service.
Deploying via MCP (optional):
- Dockhold runs a remote MCP server at https://api.dockhold.eu/mcp. With a dh_mcp_ API token from https://app.dockhold.eu/settings/api-tokens, passed as Authorization: Bearer, an MCP client can deploy and manage apps directly.
- Tools. Read: list_apps, get_app_status, get_app_logs, list_github_repos, get_resource_usage. Read+deploy: deploy_app, redeploy_app, set_app_variable, deploy_group, resize_app, resize_database, resize_database_storage.
- deploy_app takes a GitHub repo URL and a name; poll get_app_status until the URL is live. Public repo: repo_url + name. Private repo: call list_github_repos first (each connected repo comes with its installation_id), then deploy_app with repo_url + name + github_installation_id; this also turns auto-deploy on.
- If an app runs out of memory (OOM), resize it: resize_app(app_id, memory_mb). resize_database(app_id, db_ram_mb) grows a managed DB's memory (it restarts briefly); resize_database_storage(app_id, storage_gb) grows its disk (grow-only). Call get_resource_usage first for valid sizes (its *.steps_* arrays) and to confirm the pool has room; an over-pool size is refused.
- deploy_group deploys several connected services at once: pass a services map (each with source repo URL, port, optional env, optional db:"enable"); link services by setting an env value to exactly ${services.<name>.url}; a service with db:"enable" gets its own database and reads DATABASE_URL. Returns each service's app id; poll get_app_status on each. Public repos only.
- A token only does what its owner could do in the dashboard, scoped to their account. Secrets go in the Vault, not via set_app_variable. CLAUDE.md (Claude Code)
Save at your repo root as CLAUDE.md:
# Deploying on Dockhold
Deploy target: Dockhold (https://dockhold.eu).
How deploys work:
- Two deploy paths. Code in a GitHub repo: connect it once at https://app.dockhold.eu, then deploy by pushing to the main branch. Code only local (no git remote): deploy with the Dockhold CLI (see the local-code block below). Never invent another deploy method.
- Dockhold auto-detects the stack (Node, Python, Go, Rust, Ruby, Deno, Bun, Java, PHP). To control the build, add a Dockerfile at the repo root, or a dockhold.json with {"build":{"dockerfile":"path/to/Dockerfile"}}.
App requirements:
- Listen on 0.0.0.0 and the port from the PORT environment variable. Never hardcode a port or bind to localhost.
- Read all configuration from environment variables.
- Do not commit secrets. Set secrets (API keys, tokens, passwords) in the Dockhold dashboard Vault; they are injected at runtime.
- PORT and DATABASE_URL are set by Dockhold — read them, never define or override them.
- For a database, enable the managed Postgres add-on and read DATABASE_URL. Do not run or configure your own database.
- Apps are stateless: the container filesystem is ephemeral and lost on restart. Persist data in the managed database, not on local disk.
- To seed the managed database with existing data (one-time, paid plan): dump it with `pg_dump -Fc --no-owner --no-privileges yourdb > backup.dump` and upload from the app's Database tab. Cap 2 GB after compression; all-or-nothing, so import into an empty database.
Local-only code (no GitHub repo):
- Run `npx dockhold login` (opens a browser once; needs Node 18+), then `npx dockhold deploy` from the project folder. It uploads the folder, builds it (your Dockerfile if present, else auto-detect), and prints the live URL.
- `.env` files are never uploaded. Set variables with `--env KEY=VALUE` (repeatable) or in the dashboard; secrets in the Vault. Add `--db` for a managed database (read `DATABASE_URL`).
- Always excluded from the upload: `.git`, `node_modules`, `.dockhold`, every `.env*` file. `.gitignore` is respected; a `.dockholdignore` file excludes more. Upload cap 500 MB.
- Ship a new version by running `npx dockhold deploy` again from the same folder. These apps have no git auto-deploy.
Multiple services that talk to each other:
- If you generate several services that call each other (e.g. a frontend and an API), do NOT hardcode one service's URL in another. Read it from an environment variable (e.g. API_URL) and call that.
- On Dockhold you deploy them as one "connected app", either in the dashboard (https://app.dockhold.eu/new → "Deploy them together") or via the MCP deploy_group tool (see MCP rules below). Add each service (a GitHub repo URL + port), then link each such variable to the sibling service by setting it to exactly ${services.<sibling>.url}. Dockhold injects that sibling's live URL into the variable.
- A service in a connected app can have its own managed database: tick "Add a managed database" on that service (usually the API, not the frontend) and read DATABASE_URL. Each database belongs to the service that enabled it; a shared database across services and bring-your-own external database are not supported yet.
- First cut: web services only, one GitHub repo per service.
Deploying via MCP (optional):
- Dockhold runs a remote MCP server at https://api.dockhold.eu/mcp. With a dh_mcp_ API token from https://app.dockhold.eu/settings/api-tokens, passed as Authorization: Bearer, an MCP client can deploy and manage apps directly.
- Tools. Read: list_apps, get_app_status, get_app_logs, list_github_repos, get_resource_usage. Read+deploy: deploy_app, redeploy_app, set_app_variable, deploy_group, resize_app, resize_database, resize_database_storage.
- deploy_app takes a GitHub repo URL and a name; poll get_app_status until the URL is live. Public repo: repo_url + name. Private repo: call list_github_repos first (each connected repo comes with its installation_id), then deploy_app with repo_url + name + github_installation_id; this also turns auto-deploy on.
- If an app runs out of memory (OOM), resize it: resize_app(app_id, memory_mb). resize_database(app_id, db_ram_mb) grows a managed DB's memory (it restarts briefly); resize_database_storage(app_id, storage_gb) grows its disk (grow-only). Call get_resource_usage first for valid sizes (its *.steps_* arrays) and to confirm the pool has room; an over-pool size is refused.
- deploy_group deploys several connected services at once: pass a services map (each with source repo URL, port, optional env, optional db:"enable"); link services by setting an env value to exactly ${services.<name>.url}; a service with db:"enable" gets its own database and reads DATABASE_URL. Returns each service's app id; poll get_app_status on each. Public repos only.
- A token only does what its owner could do in the dashboard, scoped to their account. Secrets go in the Vault, not via set_app_variable. See also
- Quickstart — the same steps for a human.
- llms.txt — machine-readable map for tools that ingest it.