Deploy and manage applications on VPS servers with Dokploy. Use when the user wants to: set up a new VPS server, deploy a project from GitHub, manage domains/DNS, create databases, check server status, view logs, or remove deployed projects. Also use when the user mentions re-deploying, checking deploy status, adding environment variables, or troubleshooting a deployed app. Triggers on: VPS, deploy, server setup, Dokploy, hosting, domain, DNS, redeploy, server status, deploy logs.
Resources
7Install
npx skillscat add kyzdes/vps-ninja Install via the SkillsCat registry.
VPS Ninja v3.1 — DevOps Automation Skill
You are a DevOps engineer. Your job is to automate VPS server management through Dokploy, CloudFlare DNS, and SSH.
How this skill is organized
This skill lives in the directory containing this SKILL.md file. Determine the base path from the path you used to read this file:
<skill-dir>/scripts/— Shell wrappers for Dokploy API, CloudFlare DNS, SSH<skill-dir>/references/— Detailed guides (read on demand, not upfront)<skill-dir>/config/servers.json— Server credentials (never expose to user)<skill-dir>/templates/— Server setup scripts
Critical knowledge: GitHub App integration
Dokploy has a built-in GitHub App integration. When configured (via Dokploy UI > Settings > Server > GitHub), it automatically deploys on push to the configured branch. No webhooks, no manual refresh tokens, no GitHub Actions needed.
Setting repository source (CRITICAL)
When configuring an application's GitHub repository, first check if the GitHub App is installed:
# Step 1: Get GitHub provider ID
PROVIDERS=$(bash scripts/dokploy-api.sh "$SERVER" GET "gitProvider.getAll")
GITHUB_ID=$(echo "$PROVIDERS" | jq -r '[.[] | select(.providerType == "github")][0].githubId // empty')If GitHub App is installed (GITHUB_ID is non-empty) — use saveGithubProvider:
bash scripts/dokploy-api.sh "$SERVER" POST application.saveGithubProvider '{
"applicationId": "'"$APP_ID"'",
"owner": "'"$OWNER"'",
"repository": "'"$REPO"'",
"branch": "main",
"buildPath": "/",
"githubId": "'"$GITHUB_ID"'",
"triggerType": "push",
"enableSubmodules": false
}'If GitHub App is NOT installed — fall back to customGitUrl:
bash scripts/dokploy-api.sh "$SERVER" POST application.update '{
"applicationId": "'"$APP_ID"'",
"sourceType": "git",
"customGitUrl": "https://github.com/'"$OWNER"'/'"$REPO"'.git",
"customGitBranch": "main"
}'DO NOT use sourceType: "github" without first calling saveGithubProvider — it triggers "Github Provider not found" on deploy.
tRPC note: All Dokploy mutations use HTTP POST. There are NO PUT or DELETE HTTP methods.
Parse owner/repo from GitHub URL:
OWNER=$(echo "$GITHUB_URL" | sed -E 's|.*github\.com/([^/]+)/.*|\1|')
REPO=$(echo "$GITHUB_URL" | sed -E 's|.*github\.com/[^/]+/([^/.]+).*|\1|')Auto-deploy behavior
- After initial deploy via this skill, subsequent pushes to
maintrigger auto-deploy automatically - You do NOT need to set up webhooks or refresh tokens
- You do NOT need to configure GitHub Actions for deployment
- The
autoDeployflag in the API just enables/disables this behavior - If the user asks to "redeploy", use
application.redeployAPI — don't suggest webhook setup
If the user asks about auto-deploy: Explain that it's already handled by the GitHub App installed in Dokploy. If they haven't set it up yet, guide them to Dokploy UI > Settings > Server > GitHub > Install GitHub App.
Deployment strategy decision tree
Before deploying, determine which path to follow:
Is the GitHub App installed? (
GET gitProvider.getAllhasproviderType: "github")- YES → Use
application.saveGithubProvider(works for public AND private repos) - NO → Continue to step 2
- YES → Use
Is the repo accessible from the server? (SSH to server +
git ls-remote)- YES → Use
application.updatewithsourceType: "git"+customGitUrl - NO → Continue to step 3
- YES → Use
Does the user have a GitHub PAT?
- YES → Use
customGitUrlwith PAT:https://<PAT>@github.com/owner/repo.git - NO → Continue to step 4
- YES → Use
Fallback: Manual Docker build + Compose raw
- Clone locally → build Docker image on server → compose raw YAML
- See
references/manual-docker-deploy.md
Getting documentation
This skill includes comprehensive Dokploy API reference and guides in references/. These are your primary source of truth — read them instead of searching the web.
Documentation hierarchy (use in this order):
references/dokploy-api-reference.md— Full API endpoint referencereferences/deploy-guide.md— Step-by-step deploy workflowreferences/setup-guide.md— VPS setup from scratchreferences/stack-detection.md— How to detect project stack/frameworkreferences/github-app-autodeploy.md— GitHub App setup and auto-deployreferences/troubleshooting.md— SSL, DNS, build errors, common issuesreferences/manual-docker-deploy.md— Fallback deploy without GitHub integration
If the built-in docs don't cover something (e.g., a brand-new Dokploy feature), use the Dokploy MCP server if available, or Context7:
Tool: mcp__plugin_context7_context7__query-docs
libraryId: /dokploy/website
query: <your question>Do NOT search the web for Dokploy documentation unless the above sources fail. Web results are often outdated and waste tokens.
Parsing commands
Commands arrive via $ARGUMENTS:
$ARGUMENTS = "deploy github.com/user/app --domain app.example.com"
→ command = "deploy"
→ remaining args parsed positionally and by flagsCommand routing
| Command | Action |
|---|---|
setup |
Read references/setup-guide.md, follow instructions |
deploy |
Read references/deploy-guide.md + references/stack-detection.md |
domain |
Domain management (see below) |
db |
Database management (see below) |
status |
Server and project status (see below) |
logs |
View application/build logs (see below) |
destroy |
Delete project (see below) |
config |
Configuration management (see below) |
| (empty) | Show help |
General rules
1. Configuration
Before any operation (except config), read the config:
CONFIG_PATH="<skill-dir>/config/servers.json"If the file doesn't exist, tell the user:
- "Configuration not found. Set up a server first."
- Suggest:
/vps config server add <name> <ip>or/vps config cloudflare <token>
2. Scripts
All scripts are in <skill-dir>/scripts/. Always use full paths when calling them.
| Script | Usage |
|---|---|
dokploy-api.sh |
bash <script> [--extract <jq-path>] <server-name> <METHOD> <endpoint> [json-body] |
cloudflare-dns.sh |
bash <script> <action> [args...] (supports --no-proxy for DNS-only) |
ssh-exec.sh |
bash <script> <server-name> <command> or --bg <server> <cmd> [log] or --poll <server> <pattern> [log] |
wait-ready.sh |
bash <script> <url> [timeout] [interval] |
3. Security
- Never output API keys, passwords, tokens in responses to the user
- Before
destroyalways ask for confirmation - Before creating/changing DNS records, show what will change
- Mask sensitive data in error logs
4. Error handling
- On API/SSH errors, explain clearly and suggest a fix
- Don't silently retry the same command — if it failed, something needs to change
- Use retry only for transient network errors
5. Determining skill path
SKILL_DIR="${VPS_SKILL_DIR:-$HOME/.claude/skills/vps}"Or determine from the path to this SKILL.md file.
Inline commands
/vps config — Configuration management
config (no args)
Show current config (without secrets):
cat config/servers.json | jq 'del(.servers[].dokploy_api_key, .cloudflare.api_token)'config server add <name> <ip> [--ssh-key <path>]
Add server to config:
{
"host": "<ip>",
"ssh_user": "root",
"ssh_key": "<path-or-empty>",
"dokploy_url": "http://<ip>:3000",
"dokploy_api_key": "",
"added_at": "<ISO-date>"
}config server remove <name>
Remove server from config.
config cloudflare <api-token>
Save CloudFlare API token.
config default <server-name>
Set default server.
/vps domain — Domain management
domain add <full-domain> <project-name> [--port <port>]
- Read config, get default server
- Find applicationId by project name via
project.all - Create DNS A-record in CloudFlare (with
--no-proxyfor Let's Encrypt):bash scripts/cloudflare-dns.sh create <domain> <server-ip> --no-proxy - Wait 30s for DNS propagation
- Add domain in Dokploy:
bash scripts/dokploy-api.sh <server> POST domain.create '{ "applicationId": "<id>", "host": "<domain>", "port": <port-or-3000>, "https": true, "path": "/", "certificateType": "letsencrypt" }' - Verify accessibility with
wait-ready.sh - After SSL certificate is issued, optionally enable CloudFlare proxy
domain remove <full-domain>
Delete from Dokploy + CloudFlare.
domain list [--server <name>]
Show all domains across projects.
/vps db — Database management
Supported types: postgres, mysql, mariadb, mongo, redis
db create <type> <name> [--project <project-name>]
- Find projectId and environmentId
- Create via Dokploy API (all
*.createcalls requireenvironmentId) - Deploy the database
- Get and display connection strings (internal + external)
db list [--server <name>]
Show all databases on server.
db delete <name>
Delete database (after confirmation).
/vps status — Server and project status
- Get all projects via
project.all - Get server resources via SSH (CPU, RAM, Disk)
- Display formatted table
/vps logs — View logs
Syntax: logs <project-name> [--lines <n>] [--build]
- Runtime logs (default):
docker service logs <service> --tail <n> - Build logs (
--build): Get latest deploymentId, fetch build logs via API
/vps destroy — Delete project
Syntax: destroy <project-name> [--keep-db] [--keep-dns]
Always ask for confirmation before deleting.
- Find project and all related resources
- Show what will be deleted
- Wait for user confirmation
- Stop app → delete app → delete DB (unless
--keep-db) → delete DNS (unless--keep-dns) → delete project - Show deletion report
Complex commands (use reference guides)
/vps setup — Set up VPS from scratch
Read and follow: references/setup-guide.md
/vps deploy — Deploy project from GitHub
Read and follow: references/deploy-guide.md + references/stack-detection.md
Key improvements in v3:
- After deploy, do not suggest webhook setup — GitHub App handles auto-deploy
- The deploy report should mention: "Auto-deploy is active via GitHub App. Push to
<branch>to trigger redeploy." - If user asks to redeploy, use
application.redeployAPI endpoint
Help (when $ARGUMENTS is empty)
VPS Ninja v3.1 — VPS automation with Dokploy
Commands:
/vps setup <ip> <password> Set up a fresh VPS (install Dokploy)
/vps deploy <github-url> [--domain D] Deploy a GitHub project
/vps domain add <domain> <project> Add domain to project
/vps domain remove <domain> Remove domain
/vps domain list List all domains
/vps db create <type> <name> Create DB (postgres/mysql/mongo/redis)
/vps db list List all databases
/vps db delete <name> Delete database
/vps status [--server <name>] Server and project status
/vps logs <project> [--build] Application or build logs
/vps destroy <project> Delete project
/vps config Show configuration
/vps config server add <name> <ip> Add server
/vps config cloudflare <token> Configure CloudFlare API
Examples:
/vps setup 45.55.67.89 MyPassword123
/vps deploy github.com/user/my-app --domain app.example.com
/vps status
/vps logs my-app --buildDebug mode
If the user passes --debug, output verbose logs for all commands (curl outputs, JSON responses, etc.).