DO droplet (nyc3 s-2vcpu-4gb + swap) running 3 co-located Forgejo (ct/mc/quinn) + Verdaccio via docker-compose. HTTP+token (built-in SSH disabled). Provisioned 165.227.191.38; state local (gitignored). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
88 lines
2.6 KiB
HCL
88 lines
2.6 KiB
HCL
###############################################################################
|
|
# Shared services droplet — 3 Forgejo instances (ct/mc/quinn) + Verdaccio,
|
|
# co-located. Public-facing (like the current ct-forge). 4GB + swap (tight but
|
|
# fine for low-traffic git + npm). PyPI / SwiftPM / DNS / Caddy are fast-follow.
|
|
###############################################################################
|
|
|
|
resource "digitalocean_droplet" "services" {
|
|
name = var.name
|
|
image = "ubuntu-24-04-x64"
|
|
size = var.droplet_size
|
|
region = var.region
|
|
ssh_keys = var.ssh_key_fingerprints
|
|
tags = ["services", "forge", "quinn-infra"]
|
|
|
|
user_data = file("${path.module}/cloud-init.yaml")
|
|
|
|
lifecycle {
|
|
# Forgejo/Verdaccio data lives in /opt/services volumes; never let a
|
|
# user_data tweak silently rebuild and wipe it.
|
|
ignore_changes = [user_data]
|
|
}
|
|
}
|
|
|
|
resource "digitalocean_firewall" "services" {
|
|
name = "services-fw"
|
|
droplet_ids = [digitalocean_droplet.services.id]
|
|
|
|
inbound_rule {
|
|
protocol = "tcp"
|
|
port_range = "22"
|
|
source_addresses = ["0.0.0.0/0", "::/0"]
|
|
}
|
|
# Forgejo HTTP (ct 3000 / mc 3001 / quinn 3002) + git-SSH (2222/2223/2224) + Verdaccio 4873
|
|
inbound_rule {
|
|
protocol = "tcp"
|
|
port_range = "3000-3002"
|
|
source_addresses = ["0.0.0.0/0", "::/0"]
|
|
}
|
|
inbound_rule {
|
|
protocol = "tcp"
|
|
port_range = "2222-2224"
|
|
source_addresses = ["0.0.0.0/0", "::/0"]
|
|
}
|
|
inbound_rule {
|
|
protocol = "tcp"
|
|
port_range = "4873"
|
|
source_addresses = ["0.0.0.0/0", "::/0"]
|
|
}
|
|
# 80/443 for future Caddy/TLS
|
|
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"]
|
|
}
|
|
|
|
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"]
|
|
}
|
|
outbound_rule {
|
|
protocol = "icmp"
|
|
destination_addresses = ["0.0.0.0/0", "::/0"]
|
|
}
|
|
}
|
|
|
|
output "services_ip" {
|
|
value = digitalocean_droplet.services.ipv4_address
|
|
}
|
|
|
|
output "forge_urls" {
|
|
value = {
|
|
ct = "http://${digitalocean_droplet.services.ipv4_address}:3000"
|
|
mc = "http://${digitalocean_droplet.services.ipv4_address}:3001"
|
|
quinn = "http://${digitalocean_droplet.services.ipv4_address}:3002"
|
|
npm = "http://${digitalocean_droplet.services.ipv4_address}:4873"
|
|
}
|
|
}
|