Skip to content

DigitalOcean Installation

Deploy Broch on a DigitalOcean Droplet with Docker Compose and embedded PostgreSQL. Caddy handles automatic wildcard TLS via DNS-01.

Status: In progress. The Terraform configuration is available in the GitHub repository.

Complete these steps before proceeding:

This deployment uses Caddy with DNS-01 ACME for automatic wildcard TLS — no manual certificate management. You provide your DNS provider’s API token; Caddy handles certificate issuance and renewal.

See TLS Certificates for details.

Initialize Terraform and create your variables file:

Terminal window
terraform init
cat > terraform.tfvars <<'EOF'
do_token = "dop_v1_..."
ssh_key_fingerprint = "aa:bb:cc:..."
deployment_name = "broch"
license_key = "XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX"
wildcard_hostname = "tunnels.company.com"
dns_provider = "cloudflare"
dns_api_token = "your-cloudflare-api-token"
auth_provider = "AzureAd"
auth_client_id = "your-client-id"
auth_client_secret = "your-client-secret"
auth_tenant_id = "your-tenant-id"
auth_admin_roles = "Admin"
admin_email = "[email protected]"
postgres_password = "a-strong-random-password"
EOF
terraform apply

Download the Terraform configuration from the Broch GitHub repository.

After terraform apply, create a wildcard A record pointing to the reserved IP shown in the output:

*.tunnels.company.com → 203.0.113.42 (from terraform output)
DigitalOcean Droplet (Ubuntu 24.04)
├── Docker Compose
│ ├── caddy (automatic wildcard TLS via DNS-01)
│ ├── broch (port 8080)
│ └── postgres:16-alpine
├── Block Storage Volume (/mnt/broch-data)
│ └── postgresql/ (persistent DB data)
└── Reserved IP (stable DNS target)

Update image_tag in terraform.tfvars and re-apply. PostgreSQL data is preserved on the block storage volume.

Terminal window
terraform apply -var="image_tag=1.2.3"
Terminal window
ssh root@<droplet-ip> \
"cd /opt/broch && docker compose exec -T postgres pg_dump -U broch brochdb" \
> backup-$(date +%Y%m%d).sql