A command-line tool for managing DigitalOcean droplets with automated setup, SSH configuration, and lifecycle management.
- 🚀 Quick droplet creation with cloud-init automation
- 🔑 Automatic SSH configuration - just run
ssh dropkit.<droplet-name> - 🔐 Tailscale VPN - secure access via Tailscale (enabled by default)
- 👤 User management - automatically creates your user account on droplets
- 🏷️ Smart tagging - organizes droplets by owner for easy filtering
- 🔒 Security-first - SSH key validation, confirmation prompts for destructive operations
- 📊 Rich CLI - beautiful tables, progress indicators, and helpful error messages
- 🔄 Complete lifecycle - create, list, resize, destroy droplets with ease
- 💤 Hibernate/Wake - snapshot and destroy to save costs, restore later with one command
- Python 3.11+
- DigitalOcean account with an API token (create one here)
- SSH key pair (usually
~/.ssh/id_ed25519.pubor~/.ssh/id_rsa.pub) - uv package manager (install instructions)
- Tailscale (optional but recommended) - install from tailscale.com/download
# HTTPS or SSH depending on your GitHub setup
uv tool install git+https://github.com/trailofbits/dropkit.git
uv tool install git+ssh://git@github.com/trailofbits/dropkit.git
# Upgrade
uv tool upgrade dropkitRun the initialization wizard:
dropkit initThis will validate your DigitalOcean API token, detect SSH keys, register them with DigitalOcean, and let you choose defaults (type ? for help to see available options).
# Interactive mode - prompts for name, region, size, image (type ? for help)
dropkit create
# Or specify the name and use defaults
dropkit create my-first-droplet
# Assign to a specific project (by name or ID)
dropkit create my-droplet --project "My Project"
# Create without Tailscale VPN
dropkit create my-droplet --no-tailscaleThe tool will:
- Create the droplet and wait for it to become active
- Add SSH configuration automatically
- Wait for cloud-init to complete
- Tailscale setup (enabled by default):
- Display an auth URL for you to authenticate in your browser
- Update SSH config with your Tailscale IP
- Lock down the firewall to only allow Tailscale traffic
ssh dropkit.my-first-dropletYour user account is already set up with your SSH keys.
Usage: dropkit [OPTIONS] COMMAND [ARGS]...
Manage DigitalOcean droplets
Commands:
init Initialize dropkit configuration.
create Create a new DigitalOcean droplet with cloud-init configuration.
list List droplets and hibernated snapshots tagged with owner:<username>.
config-ssh Configure SSH for an existing droplet.
info Show detailed information about a droplet.
rename Rename a droplet (requires confirmation).
destroy Destroy a droplet or hibernated snapshot (DESTRUCTIVE).
resize Resize a droplet (causes downtime - requires power off).
on Power on a droplet.
off Power off a droplet (requires confirmation).
hibernate Hibernate a droplet (snapshot and destroy to save costs).
wake Wake a hibernated droplet (restore from snapshot).
enable-tailscale Enable Tailscale VPN on an existing droplet.
list-ssh-keys List SSH keys registered via dropkit.
add-ssh-key Add or import an SSH public key to DigitalOcean.
delete-ssh-key Delete an SSH key registered via dropkit.
version Show the version of dropkit.
Use dropkit <command> --help for detailed help on any command.
Configuration files are stored in ~/.config/dropkit/:
config.yaml- Main configuration (API token, defaults, SSH keys)cloud-init.yaml- Cloud-init template (customizable)
All droplets are automatically tagged with:
owner:<username>- Your DigitalOcean account username (derived from email)firewall- For security group identification
- Set default project during
dropkit init(type?to see available projects) - Override per-droplet using
--project <name>withdropkit create - Specify by name or UUID; tab completion available
All SSH config entries use the prefix dropkit.<droplet-name>:
- Connect with:
ssh dropkit.my-droplet
Enable tab completion for droplet names in your shell:
Zsh (recommended):
dropkit --install-completion zshBash:
dropkit --install-completion bashAfter installation, restart your shell. Tab completion dynamically fetches your droplets from DigitalOcean:
dropkit info <TAB> # Shows your droplets
dropkit destroy <TAB> # Shows your droplets
dropkit resize <TAB> # Shows your droplets
dropkit on <TAB> # Shows your droplets
dropkit off <TAB> # Shows your dropletsDigitalOcean charges for stopped droplets at the full hourly rate. To avoid this, use hibernate/wake:
# Hibernate: snapshot the droplet and destroy it (stops billing)
dropkit hibernate my-droplet
# Wake: restore the droplet from the snapshot
dropkit wake my-droplet
# Delete a hibernated snapshot without restoring
dropkit destroy my-dropletHow it works:
hibernatepowers off the droplet, creates a snapshot (dropkit-<name>), then destroys the dropletwakecreates a new droplet from the snapshot with the same region and size- Snapshots are tagged with
owner:<username>andsize:<size-slug>for tracking - After waking, you're prompted to delete the snapshot (default: yes)
Note: Snapshots are billed at $0.06/GB/month, which is typically much cheaper than keeping a droplet running.
Edit ~/.config/dropkit/cloud-init.yaml to customize user setup, package installation, firewall rules, and shell configuration. The template uses Jinja2 syntax with variables {{ username }} and {{ ssh_keys }}.
Initialize the configuration:
dropkit initCheck cloud-init status manually:
ssh dropkit.my-droplet 'sudo cloud-init status'
ssh dropkit.my-droplet 'sudo cat /var/log/cloud-init.log'Use --verbose flag to see detailed output:
dropkit create my-droplet --verboseThe droplet might belong to someone else. List your droplets:
dropkit list- CLI Framework: Typer - Modern CLI framework
- UI/Display: Rich - Terminal formatting
- API Client: requests - HTTP library
- Configuration: Pydantic - Data validation
- Templating: Jinja2 - Cloud-init templates
- Package Manager: uv - Fast Python package manager
- Code Quality: Ruff (linter/formatter) + ty (type checker)
- Go to DigitalOcean API Tokens
- Click Generate New Token with name "dropkit-cli"
- Select Custom Scopes (recommended) or Full Access (simpler)
- For custom scopes, enable the 23 scopes listed below
account:read, actions:read, droplet:create, droplet:read, droplet:update, droplet:delete, image:create, image:read, image:update, image:delete, project:read, project:update, regions:read, sizes:read, snapshot:read, snapshot:delete, ssh_key:create, ssh_key:read, ssh_key:update, ssh_key:delete, tag:read, tag:create, vpc:read
| Feature | Required Scopes |
|---|---|
| Initialize config | account:read, regions:read, sizes:read, image:read, ssh_key:read, ssh_key:create, project:read |
| Create droplets | droplet:create, project:update, actions:read, tag:create |
| List droplets | droplet:read, snapshot:read, tag:read |
| Show droplet info | droplet:read |
| Destroy droplets | droplet:delete, snapshot:delete |
| Rename droplets | droplet:update |
| Resize droplets | droplet:update, sizes:read, actions:read |
| Power on/off | droplet:update, actions:read |
| Hibernate | droplet:update, droplet:delete, snapshot:create, actions:read, tag:create |
| Wake | droplet:create, snapshot:read, snapshot:delete |
| Manage SSH keys | ssh_key:read, ssh_key:create, ssh_key:update, ssh_key:delete |
For more information, see the DigitalOcean API Token Scopes documentation.