Claude-skill-registry admin-infra-digitalocean
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/admin-infra-digitalocean" ~/.claude/skills/majiayu000-claude-skill-registry-admin-infra-digitalocean && rm -rf "$T"
skills/data/admin-infra-digitalocean/SKILL.md- uses sudo
- reads SSH private key
- downloads files (wget)
- references .env files
DigitalOcean Infrastructure
Status: Production Ready | Dependencies: doctl CLI, SSH key pair
Navigation
- Operations, troubleshooting, config, and cost snapshot:
references/OPERATIONS.md
Step 0: Gather Required Information (MANDATORY)
STOP. Before ANY deployment commands, collect ALL parameters from the user.
Copy this checklist and confirm each item:
Required Parameters: - [ ] SERVER_NAME - Unique name for this server - [ ] DO_REGION - Region (nyc1, sfo3, lon1, fra1, sgp1, etc.) - [ ] DO_SIZE - Droplet size (see profiles below) - [ ] SSH_KEY_NAME - Name of SSH key in DigitalOcean - [ ] SSH_KEY_PATH - Path to local SSH private key (default: ~/.ssh/id_rsa) Deployment Purpose (determines recommended profile): - [ ] Purpose: coolify / kasm / both / custom coolify → s-2vcpu-4gb ($24/mo) kasm → s-4vcpu-8gb ($48/mo) both → s-8vcpu-16gb ($96/mo) custom → Ask for specific size
Recommended profiles by purpose:
| Purpose | Size | vCPU | RAM | Monthly |
|---|---|---|---|---|
| coolify | s-2vcpu-4gb | 2 | 4GB | $24 |
| kasm | s-4vcpu-8gb | 4 | 8GB | $48 |
| both | s-8vcpu-16gb | 8 | 16GB | $96 |
DO NOT proceed to Prerequisites until ALL parameters are confirmed.
Prerequisites
Before using this skill, verify the following:
1. DigitalOcean CLI Installed
doctl version
If missing, install with:
# macOS brew install doctl # Linux (snap) sudo snap install doctl # Linux (download binary) cd ~ wget https://github.com/digitalocean/doctl/releases/download/v1.104.0/doctl-1.104.0-linux-amd64.tar.gz tar xf doctl-1.104.0-linux-amd64.tar.gz sudo mv doctl /usr/local/bin # Windows (scoop) scoop install doctl
2. DigitalOcean Account & API Token
If you don't have a DigitalOcean account:
Sign up at: https://m.do.co/c/YOUR_REFERRAL_CODE
Disclosure: This is a referral link. You'll receive $200 in credit for 60 days, and the skill author receives account credit. Using this link helps support the development of these skills.
Get API token: https://cloud.digitalocean.com/account/api/tokens
Create a token with Read & Write scope.
3. doctl CLI Configured
doctl account get
If it shows an error, authenticate with:
doctl auth init # Paste your API token when prompted
Or set via environment variable:
export DIGITALOCEAN_ACCESS_TOKEN="your_token_here" doctl account get
4. SSH Key Pair
ls ~/.ssh/id_rsa.pub
If missing, generate with:
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
5. SSH Key Uploaded to DigitalOcean
doctl compute ssh-key list
If empty, upload with:
doctl compute ssh-key import my-key --public-key-file ~/.ssh/id_rsa.pub
6. Test Authentication
doctl compute region list
If this fails: Token may be invalid or expired. Create a new one.
Server Profiles
Coolify/Kasm Deployments
| Profile | Droplet Type | vCPU | RAM | Disk | Monthly Cost |
|---|---|---|---|---|---|
| s-2vcpu-4gb | 2 | 4GB | 80GB | $24 |
| s-4vcpu-8gb | 4 | 8GB | 160GB | $48 |
| s-8vcpu-16gb | 8 | 16GB | 320GB | $96 |
Premium CPU (Higher Performance)
| Profile | Droplet Type | vCPU | RAM | Disk | Monthly Cost |
|---|---|---|---|---|---|
| c-4-8gib | 4 | 8GB | 50GB | $84 |
| c-8-16gib | 8 | 16GB | 100GB | $168 |
| c-16-32gib | 16 | 32GB | 200GB | $336 |
| Droplet Type | vCPU | RAM | Disk | Monthly Cost |
|---|---|---|---|---|
| g-2vcpu-8gb | 2 | 8GB | 25GB | $63 |
| g-4vcpu-16gb | 4 | 16GB | 50GB | $126 |
| g-8vcpu-32gb | 8 | 32GB | 100GB | $252 |
Deployment Steps
Step 1: Set Environment Variables
<details> <summary><strong>Region options</strong></summary>export DO_REGION="nyc1" # See regions below export DO_SIZE="s-2vcpu-4gb" # See profiles above export DO_IMAGE="ubuntu-22-04-x64" export SERVER_NAME="my-server" export SSH_KEY_NAME="my-key"
| Code | Location | Region |
|---|---|---|
| New York 1 | US East |
| New York 3 | US East |
| San Francisco 2 | US West |
| San Francisco 3 | US West |
| Toronto | Canada |
| London | UK |
| Amsterdam | Netherlands |
| Frankfurt | Germany |
| Bangalore | India |
| Singapore | Asia |
| Sydney | Australia |
Step 2: Get SSH Key ID
SSH_KEY_ID=$(doctl compute ssh-key list --format ID,Name --no-header | grep "$SSH_KEY_NAME" | awk '{print $1}') echo "SSH Key ID: $SSH_KEY_ID" # Verify if [ -z "$SSH_KEY_ID" ]; then echo "ERROR: SSH key '$SSH_KEY_NAME' not found. Upload it first." exit 1 fi
Step 3: Create Firewall
# Create firewall doctl compute firewall create \ --name my-firewall \ --inbound-rules "protocol:tcp,ports:22,address:0.0.0.0/0,address:::/0" \ --inbound-rules "protocol:tcp,ports:80,address:0.0.0.0/0,address:::/0" \ --inbound-rules "protocol:tcp,ports:443,address:0.0.0.0/0,address:::/0" \ --inbound-rules "protocol:tcp,ports:8000,address:0.0.0.0/0,address:::/0" \ --inbound-rules "protocol:tcp,ports:6001-6002,address:0.0.0.0/0,address:::/0" \ --inbound-rules "protocol:tcp,ports:8443,address:0.0.0.0/0,address:::/0" \ --inbound-rules "protocol:tcp,ports:3389,address:0.0.0.0/0,address:::/0" \ --inbound-rules "protocol:tcp,ports:3000-4000,address:0.0.0.0/0,address:::/0" \ --outbound-rules "protocol:tcp,ports:all,address:0.0.0.0/0,address:::/0" \ --outbound-rules "protocol:udp,ports:all,address:0.0.0.0/0,address:::/0" \ --outbound-rules "protocol:icmp,address:0.0.0.0/0,address:::/0"
Step 4: Create Droplet
doctl compute droplet create "$SERVER_NAME" \ --region "$DO_REGION" \ --size "$DO_SIZE" \ --image "$DO_IMAGE" \ --ssh-keys "$SSH_KEY_ID" \ --tag-names "myproject" \ --wait
Step 5: Get Droplet IP
SERVER_IP=$(doctl compute droplet get "$SERVER_NAME" --format PublicIPv4 --no-header) echo "SERVER_IP=$SERVER_IP"
Step 6: Apply Firewall to Droplet
FIREWALL_ID=$(doctl compute firewall list --format ID,Name --no-header | grep "my-firewall" | awk '{print $1}') DROPLET_ID=$(doctl compute droplet get "$SERVER_NAME" --format ID --no-header) doctl compute firewall add-droplets "$FIREWALL_ID" --droplet-ids "$DROPLET_ID"
Step 7: Wait for Server Ready
# Wait for SSH to be available (typically 30-60 seconds) echo "Waiting for server to be ready..." until ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@$SERVER_IP "echo connected" 2>/dev/null; do sleep 5 done echo "Server is ready!"
Step 8: Verify Connection
ssh root@$SERVER_IP "uname -a && free -h && df -h /"
Step 9: Output for Downstream Skills
# DigitalOcean only offers x86 architecture SERVER_ARCH="amd64" # Save to .env.local for downstream skills echo "SERVER_IP=$SERVER_IP" >> .env.local echo "SSH_USER=root" >> .env.local echo "SSH_KEY_PATH=~/.ssh/id_rsa" >> .env.local echo "SERVER_ARCH=$SERVER_ARCH" >> .env.local echo "COOLIFY_SERVER_IP=$SERVER_IP" >> .env.local echo "KASM_SERVER_IP=$SERVER_IP" >> .env.local echo "" echo "Droplet deployed successfully!" echo " IP: $SERVER_IP" echo " Arch: $SERVER_ARCH" echo " SSH: ssh root@$SERVER_IP"
Verify Deployment
ssh root@$SERVER_IP "echo 'DigitalOcean Droplet connected successfully'"
Kasm Workspaces Auto-Scaling
DigitalOcean has native integration with Kasm Workspaces for automatic agent provisioning.
Enable in Kasm Admin
- Go to Infrastructure → Pools → Edit Pool
- Enable Digital Ocean Scaling Enabled
- Configure:
- DO API Key: Your DigitalOcean API token
- DO Region: Region for new agents
- DO Droplet Size: Size for auto-provisioned droplets
- DO SSH Key ID: Your SSH key ID
How It Works
- Kasm automatically provisions new Droplets when user demand increases
- Droplets are destroyed when no longer needed
- Ensures resource utilization and cost efficiency
Cleanup
Warning: This is destructive and cannot be undone.
# Delete droplet doctl compute droplet delete "$SERVER_NAME" --force # Delete firewall FIREWALL_ID=$(doctl compute firewall list --format ID,Name --no-header | grep "my-firewall" | awk '{print $1}') doctl compute firewall delete "$FIREWALL_ID" --force # Optionally delete SSH key # doctl compute ssh-key delete "$SSH_KEY_ID" --force
Operations
Troubleshooting, best practices, configuration variables, and cost snapshots are in
references/OPERATIONS.md.
Logging Integration
When performing infrastructure operations, log to the centralized system:
# After provisioning log_admin "SUCCESS" "operation" "Provisioned DigitalOcean droplet" "id=$DROPLET_ID provider=DigitalOcean" # After destroying log_admin "SUCCESS" "operation" "Deleted DigitalOcean droplet" "id=$DROPLET_ID" # On error log_admin "ERROR" "operation" "DigitalOcean deployment failed" "error=$ERROR_MSG"
See
admin skill's references/logging.md for full logging documentation.