--- name: admin-infra-digitalocean description: | 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 license: MIT --- # 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 ```bash doctl version ``` **If missing**, install with: ```bash # 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 ```bash doctl account get ``` **If it shows an error**, authenticate with: ```bash doctl auth init # Paste your API token when prompted ``` Or set via environment variable: ```bash export DIGITALOCEAN_ACCESS_TOKEN="your_token_here" doctl account get ``` ### 4. SSH Key Pair ```bash ls ~/.ssh/id_rsa.pub ``` **If missing**, generate with: ```bash ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" ``` ### 5. SSH Key Uploaded to DigitalOcean ```bash doctl compute ssh-key list ``` **If empty**, upload with: ```bash doctl compute ssh-key import my-key --public-key-file ~/.ssh/id_rsa.pub ``` ### 6. Test Authentication ```bash 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 | |---------|--------------|------|-----|------|--------------| | `coolify` | s-2vcpu-4gb | 2 | 4GB | 80GB | $24 | | `kasm` | s-4vcpu-8gb | 4 | 8GB | 160GB | $48 | | `both` | s-8vcpu-16gb | 8 | 16GB | 320GB | $96 | ### Premium CPU (Higher Performance) | 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 |
General Purpose (Best for mixed workloads) | 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 ```bash 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" ```
Region options | 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 |
### Step 2: Get SSH Key ID ```bash 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 ```bash # 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 ```bash 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 ```bash SERVER_IP=$(doctl compute droplet get "$SERVER_NAME" --format PublicIPv4 --no-header) echo "SERVER_IP=$SERVER_IP" ``` ### Step 6: Apply Firewall to Droplet ```bash 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 ```bash # 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 ```bash ssh root@$SERVER_IP "uname -a && free -h && df -h /" ``` ### Step 9: Output for Downstream Skills ```bash # 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 ```bash 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 1. Go to **Infrastructure** → **Pools** → **Edit Pool** 2. Enable **Digital Ocean Scaling Enabled** 3. 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. ```bash # 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: ```bash # 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. --- ## References - [DigitalOcean Console](https://cloud.digitalocean.com/) - [doctl CLI Documentation](https://docs.digitalocean.com/reference/doctl/) - [Droplet Pricing](https://www.digitalocean.com/pricing/droplets) - [API Documentation](https://docs.digitalocean.com/reference/api/) - [Kasm Auto-Scaling Docs](https://www.kasmweb.com/docs/latest/guide/zones/aws_autoscaling.html)