Writing Skills
writing-skills
效率与协作技能,来自 obra/superpowers,查看原文获取完整用途和操作说明。
digitalocean【部署与运维】Use this skill when the user says 'DigitalOcean', 'DO', 'Droplet', 'DOKS', 'App Platform', 'Spaces', 'Managed Database', 'Floating IP', 'Cloud Firewall', 'doctl', 'Terraform DigitalOcean', 'VPC', 'Load Balancer', 'DNS', 'Container Registry', 'Functions'. Covers: core DO services, Droplets, networking, managed databases, Kubernetes, App Platform, infr…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Design, deploy, and manage DigitalOcean infrastructure using Terraform, doctl, and best practices for Droplets, Kubernetes, managed databases, and App Platform.
Exact user phrases: "DigitalOcean", "DO", "Droplet", "DOKS", "App Platform", "Spaces", "Managed Database", "Floating IP", "Cloud Firewall", "doctl", "Terraform DigitalOcean", "VPC", "Load Balancer", "Container Registry".
Writes to Terraform HCL, doctl CLI commands, YAML manifests, configuration files.
HCL, YAML, or CLI commands with no extraneous explanation.
No preamble. No postamble. No explanations. No filler/hedging/transitions.
resource "digitalocean_vpc" "main" {
name = "production-vpc"
region = "nyc3"
ip_range = "10.10.0.0/16"
}
resource "digitalocean_firewall" "web" {
name = "web-firewall"
droplet_ids = [for d in digitalocean_droplet.app : d.id]
inbound_rule {
protocol = "tcp"
port_range = "80"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "443"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "22"
source_addresses = ["10.10.0.0/16"]
}
outbound_rule {
protocol = "tcp"
port_range = "1-65535"
destination_addresses = ["0.0.0.0/0", "::/0"]
}
outbound_rule {
protocol = "udp"
port_range = "1-65535"
destination_addresses = ["0.0.0.0/0", "::/0"]
}
}
resource "digitalocean_droplet" "app" {
count = 3
name = "app-${count.index}"
region = "nyc3"
size = "s-4vcpu-8gb"
image = "ubuntu-24-04-x64"
vpc_uuid = digitalocean_vpc.main.id
ssh_keys = [data.digitalocean_ssh_key.terraform.id]
monitoring = true
backups = true
user_data = <<-EOF
#!/bin/bash
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
EOF
tags = ["production", "web"]
}
resource "digitalocean_loadbalancer" "public" {
name = "public-lb"
region = "nyc3"
vpc_uuid = digitalocean_vpc.main.id
forwarding_rule {
entry_port = 443
entry_protocol = "https"
target_port = 80
target_protocol = "http"
certificate_name = digitalocean_certificate.main.name
}
healthcheck {
port = 80
protocol = "http"
path = "/health"
}
droplet_tag = "web"
}
resource "digitalocean_kubernetes_cluster" "main" {
name = "production-doks"
region = "nyc3"
version = "1.30.5"
node_pool {
name = "worker-pool"
size = "s-4vcpu-8gb"
node_count = 3
auto_scale = true
min_nodes = 1
max_nodes = 5
tags = ["production"]
}
maintenance_policy {
day = "sunday"
start_time = "04:00"
}
}
resource "digitalocean_container_registry" "main" {
name = "app-registry"
subscription_tier_slug = "professional"
region = "nyc3"
}
resource "digitalocean_database_cluster" "postgres" {
name = "production-pg"
engine = "pg"
version = "16"
size = "db-s-4vcpu-8gb"
region = "nyc3"
node_count = 3
vpc_uuid = digitalocean_vpc.main.id
maintenance_window {
day = "sunday"
hour = "03:00:00"
}
backup_restore {
database_name = "production-pg-backup"
backup_created_at = "2024-01-01T00:00:00Z"
}
}
resource "digitalocean_database_db" "app" {
cluster_id = digitalocean_database_cluster.postgres.id
name = "appdb"
}
resource "digitalocean_database_user" "app" {
cluster_id = digitalocean_database_cluster.postgres.id
name = "appuser"
}
resource "digitalocean_database_connection_pool" "default" {
cluster_id = digitalocean_database_cluster.postgres.id
name = "pool-default"
mode = "transaction"
size = 20
db_name = "appdb"
user = "appuser"
}
resource "digitalocean_database_firewall" "main" {
cluster_id = digitalocean_database_cluster.postgres.id
rule {
type = "droplet"
value = digitalocean_droplet.app[0].id
}
rule {
type = "k8s"
value = digitalocean_kubernetes_cluster.main.id
}
}
alerts:
- rule: DEPLOYMENT_FAILED
- rule: DOMAIN_FAILED
databases:
- engine: PG
name: appdb
num_nodes: 3
production: true
version: "16"
envs:
- key: APP_ENV
value: production
scope: RUN_TIME
features:
- buildpack
ingress:
rules:
- component:
name: api
match:
path:
prefix: "/api"
name: app-tutorial
region: nyc
services:
- build_command: npm run build
environment_slug: node-js
github:
branch: main
deploy_on_push: true
repo: your-org/app-repo
health_check:
http_path: /health
http_port: 3000
instance_count: 3
instance_size_slug: professional-s
name: api
run_command: npm start
static_sites:
- build_command: npm run build
environment_slug: node-js
github:
branch: main
deploy_on_push: true
repo: your-org/app-frontend
name: web
output_dir: [dist]
routes:
- path: /
resource "digitalocean_domain" "main" {
name = "example.com"
}
resource "digitalocean_record" "www" {
domain = digitalocean_domain.main.name
type = "A"
name = "www"
value = digitalocean_loadbalancer.public.ip
}
resource "digitalocean_certificate" "main" {
name = "wildcard-cert"
type = "lets_encrypt"
domains = ["example.com", "*.example.com"]
}
resource "digitalocean_cdn" "spaces" {
origin = digitalocean_spaces_bucket.assets.bucket_domain_name
ttl = 3600
certificate_name = digitalocean_certificate.main.name
custom_domain = "assets.example.com"
}
resource "digitalocean_spaces_bucket" "assets" {
name = "app-assets-prod"
region = "nyc3"
acl = "public-read"
versioning {
enabled = true
}
cors_rule {
allowed_headers = ["*"]
allowed_methods = ["GET"]
allowed_origins = ["https://example.com"]
max_age_seconds = 3600
}
lifecycle_rule {
enabled = true
expiration {
days = 365
}
noncurrent_version_expiration {
days = 90
}
}
}
resource "digitalocean_spaces_bucket" "backups" {
name = "app-backups-prod"
region = "nyc3"
acl = "private"
}
resource "digitalocean_monitor_alert" "cpu" {
type = "v1/insights/droplet/cpu"
value = 90
window = "5m"
compare = "GreaterThan"
entities = [for d in digitalocean_droplet.app : d.id]
alerts {
email = ["ops@example.com"]
slack {
url = "https://hooks.slack.com/services/..."
}
}
}
resource "digitalocean_monitor_alert" "disk" {
type = "v1/insights/droplet/disk"
value = 85
window = "5m"
compare = "GreaterThan"
entities = [for d in digitalocean_droplet.app : d.id]
alerts {
email = ["ops@example.com"]
}
}
| DO Service | AWS Equivalent | Azure Equivalent | GCP Equivalent |
|---|---|---|---|
| Droplet | EC2 | VM | Compute Engine |
| DOKS | EKS | AKS | GKE |
| Spaces | S3 | Blob Storage | Cloud Storage |
| Managed PostgreSQL | RDS | Database for PostgreSQL | Cloud SQL |
| Managed Redis | ElastiCache | Cache for Redis | Memorystore |
| App Platform | Elastic Beanstalk / App Runner | App Service | Cloud Run |
| Container Registry | ECR | ACR | Artifact Registry |
| Cloud Firewall | Security Groups | NSG | VPC Firewall Rules |
| Load Balancer | ALB/NLB | Load Balancer | Cloud LB |
| VPC | VPC | VNet | VPC |
| Floating IP | Elastic IP | Public IP | Static IP |
| Functions | Lambda | Functions | Cloud Functions |
| Spaces CDN | CloudFront | CDN | Cloud CDN |
| Monitoring | CloudWatch | Monitor | Cloud Monitoring |
| DNS | Route 53 | DNS | Cloud DNS |
| Plan | vCPU | RAM | SSD | Price/hr | Use Case |
|---|---|---|---|---|---|
| s-2vcpu-4gb | 2 | 4GB | 80GB | $0.059 | Small web apps |
| s-4vcpu-8gb | 4 | 8GB | 160GB | $0.119 | Medium apps |
| s-8vcpu-16gb | 8 | 16GB | 320GB | $0.238 | Large apps |
| c-2 | 2 | 4GB | 50GB | $0.060 | CPU-optimized |
| c-4 | 4 | 8GB | 100GB | $0.119 | CPU-optimized |
| m-6vcpu-32gb | 6 | 32GB | 200GB | $0.238 | Memory-optimized |
| g-2vcpu-8gb | 2 | 8GB | 25GB | $0.090 | GPU inference |
Placing Droplets outside a VPC exposes them to the public internet by default. Attackers can probe SSH, databases, and application ports. Always place Droplets and DOKS inside a VPC. Use Cloud Firewall for centralized egress/ingress rules.
A single-node managed database has no failover capability. If the node goes down, the database is unavailable until recovery is complete. Always use at least 2 nodes (standby) for production databases. 3 nodes with automatic failover for HA.
Direct database connections from application code exhaust database connection limits under load. Each Droplet or DOKS pod opens N connections to the database. Use PgBouncer (built-in connection pooling for DO Managed PostgreSQL).
Without automated backups, data loss from accidental deletion, corruption, or failed migration is permanent. Enable backups on all Droplets, databases, and Spaces. Test backup restoration quarterly.
Choosing oversized Droplets without monitoring leads to wasted spend. Start with s-2vcpu-4gb, monitor CPU/memory/disk, right-size based on 14-day utilization. Enable DO monitoring for all resources.
Without tags (environment, project, team), cost allocation and resource management become manual and error-prone. Tag all resources. Use tags in monitoring and cost reports.
After completing this skill: