Deploys infrastructure on DigitalOcean with Droplets (VMs), Firewalls, and VPCs. Includes Kasm Workspaces auto-scaling integration for dynamic agent provisioning. Use when: setting up DigitalOcean infrastructure, deploying Droplets, configuring firewalls, integrating with Kasm auto-scaling, looking for US/global cloud with good API. Keywords: digitalocean, doctl, droplet, VPS, firewall, VPC, kasm autoscale, cloud infrastructure
This skill inherits all available tools. When active, it can use any tool Claude has access to.
README.mdassets/env-templatereferences/OPERATIONS.mdStatus: Production Ready | Dependencies: doctl CLI, SSH key pair
references/OPERATIONS.mdSTOP. 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.
Before using this skill, verify the following:
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
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.
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
ls ~/.ssh/id_rsa.pub
If missing, generate with:
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
doctl compute ssh-key list
If empty, upload with:
doctl compute ssh-key import my-key --public-key-file ~/.ssh/id_rsa.pub
doctl compute region list
If this fails: Token may be invalid or expired. Create a new one.
| Profile | Droplet Type | vCPU | RAM | Disk | Monthly Cost |
|---|---|---|---|---|---|
coolify | s-2vcpu-4gb | 2 | 4GB | 80GB | $24 |
kasm | s-4vcpu-8gb | 4 | 8GB | 160GB | $48 |
both | s-8vcpu-16gb | 8 | 16GB | 320GB | $96 |
| Profile | Droplet Type | vCPU | RAM | Disk | Monthly Cost |
|---|---|---|---|---|---|
premium-small | c-4-8gib | 4 | 8GB | 50GB | $84 |
premium-medium | c-8-16gib | 8 | 16GB | 100GB | $168 |
premium-large | 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 |
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"
<details>
<summary><strong>Region options</strong></summary>
| Code | Location | Region |
|---|---|---|
nyc1 | New York 1 | US East |
nyc3 | New York 3 | US East |
sfo2 | San Francisco 2 | US West |
sfo3 | San Francisco 3 | US West |
tor1 | Toronto | Canada |
lon1 | London | UK |
ams3 | Amsterdam | Netherlands |
fra1 | Frankfurt | Germany |
blr1 | Bangalore | India |
sgp1 | Singapore | Asia |
syd1 | Sydney | Australia |
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
# 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"
doctl compute droplet create "$SERVER_NAME" \
--region "$DO_REGION" \
--size "$DO_SIZE" \
--image "$DO_IMAGE" \
--ssh-keys "$SSH_KEY_ID" \
--tag-names "myproject" \
--wait
SERVER_IP=$(doctl compute droplet get "$SERVER_NAME" --format PublicIPv4 --no-header)
echo "SERVER_IP=$SERVER_IP"
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"
# 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!"
ssh root@$SERVER_IP "uname -a && free -h && df -h /"
# 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"
ssh root@$SERVER_IP "echo 'DigitalOcean Droplet connected successfully'"
DigitalOcean has native integration with Kasm Workspaces for automatic agent provisioning.
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
Troubleshooting, best practices, configuration variables, and cost snapshots are in references/OPERATIONS.md.
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.