DIGITALOCEAN_DEPLOYMENT_AND_COST.md (4724B)
1 # Bzl on DigitalOcean with a Domain (Setup + Cost Guide) 2 3 Last updated: February 22, 2026 4 5 This guide covers: 6 - starting Bzl on a DigitalOcean droplet 7 - attaching a domain with Caddy HTTPS 8 - running multiple Bzl instances on one droplet 9 - estimating monthly cost based on usage 10 11 --- 12 13 ## 1) Provision the droplet 14 15 Recommended baseline for production: 16 - Ubuntu 24.04 LTS 17 - 2 vCPU / 2 GB RAM (or higher if you run multiple active instances) 18 - Docker + Docker Compose installed 19 20 On first login: 21 22 ```bash 23 apt update && apt upgrade -y 24 apt install -y git curl 25 ``` 26 27 If Docker is not installed yet: 28 29 ```bash 30 curl -fsSL https://get.docker.com | sh 31 ``` 32 33 --- 34 35 ## 2) Deploy a single Bzl instance 36 37 ```bash 38 cd /root 39 git clone https://github.com/bzlapp/Bzl.git 40 cd /root/Bzl 41 cp .env.example .env 42 ``` 43 44 Edit `.env` and set at least: 45 - `PORT=3000` 46 - `HOST=0.0.0.0` 47 - `REGISTRATION_CODE=<your-code>` 48 49 Then start: 50 51 ```bash 52 docker compose up -d --build --remove-orphans 53 curl -fsS http://127.0.0.1:3000/api/health 54 ``` 55 56 --- 57 58 ## 3) Point your domain to the droplet 59 60 Create DNS `A` records: 61 - `chat.example.com -> <droplet_public_ip>` 62 - (optional stream hostname) `stream.chat.example.com -> <droplet_public_ip>` 63 64 If you use Cloudflare: 65 - Keep normal web hostnames proxied if you want Cloudflare proxy features. 66 - For TURN/real-time UDP endpoints, use **DNS only**. 67 68 --- 69 70 ## 4) Configure Caddy HTTPS reverse proxy 71 72 Install Caddy if needed: 73 74 ```bash 75 apt install -y debian-keyring debian-archive-keyring apt-transport-https 76 curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg 77 curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list 78 apt update && apt install -y caddy 79 ``` 80 81 Example `/etc/caddy/Caddyfile`: 82 83 ```caddy 84 chat.example.com { 85 reverse_proxy 127.0.0.1:3000 86 } 87 ``` 88 89 Apply: 90 91 ```bash 92 caddy fmt --overwrite /etc/caddy/Caddyfile 93 systemctl reload caddy 94 ``` 95 96 --- 97 98 ## 5) Add more Bzl instances on the same droplet 99 100 Create each instance: 101 102 ```bash 103 cd /root/Bzl 104 npm run instance:create -- --path=/opt/bzl-community1 --port=3002 --registration-code='community1' --hostname=community1.example.com 105 npm run instance:create -- --path=/opt/bzl-community2 --port=3003 --registration-code='community2' --hostname=community2.example.com 106 ``` 107 108 Then add Caddy routes: 109 110 ```caddy 111 community1.example.com { 112 reverse_proxy 127.0.0.1:3002 113 } 114 115 community2.example.com { 116 reverse_proxy 127.0.0.1:3003 117 } 118 ``` 119 120 Reload Caddy and verify each `/api/health`. 121 122 --- 123 124 ## 6) Update all instance folders at once 125 126 ```bash 127 cd /root/Bzl 128 npm ci --omit=dev 129 npm run instances:update -- --roots=/root,/srv,/opt,/home --max-depth=7 --dry-run 130 npm run instances:update -- --roots=/root,/srv,/opt,/home --max-depth=7 131 ``` 132 133 Fast restart without pull/build: 134 135 ```bash 136 npm run instances:update -- --roots=/root,/srv,/opt,/home --max-depth=7 --skip-git --skip-build 137 ``` 138 139 --- 140 141 ## 7) Monthly cost model (DigitalOcean) 142 143 Use this formula: 144 145 `monthly_total = droplet + backups(optional) + block_storage(optional) + transfer_overage(optional) + domain` 146 147 ### Droplet baseline pricing inputs 148 149 DigitalOcean Basic Droplets are shown at: 150 - `$4/mo` (1 vCPU / 512 MiB / 10 GiB SSD / 500 GiB transfer) 151 - `$6/mo` (1 vCPU / 1 GiB / 25 GiB SSD / 1,000 GiB transfer) 152 - `$12/mo` (1 vCPU / 2 GiB / 50 GiB SSD / 2,000 GiB transfer) 153 154 Bandwidth overage is listed as `$0.01/GiB` after included transfer. 155 156 Optional services: 157 - Droplet backups: `20%` of droplet price 158 - Block Storage: starts at `$10/month` 159 160 ### Example monthly scenarios 161 162 1. Small private community (single instance) 163 - Droplet: `$6` 164 - Backups: `$1.20` 165 - Total infra (before domain): **`$7.20/month`** 166 167 2. Multiple communities on one droplet (3-4 low/medium traffic instances) 168 - Droplet: `$12` 169 - Backups: `$2.40` 170 - Total infra (before domain): **`$14.40/month`** 171 172 3. Heavier usage with extra storage 173 - Droplet: `$24` (or higher tier) 174 - Backups: `$4.80` 175 - Block storage: `$10` 176 - Total infra (before domain/overage): **`$38.80/month`** 177 178 Domain cost depends on registrar + TLD and is billed separately. 179 180 --- 181 182 ## 8) Cost control tips 183 184 - Start at one droplet tier up from your minimum acceptable RAM. 185 - Enable backups only for instances you cannot quickly recreate. 186 - Keep uploads bounded with Bzl upload limits and retention policies. 187 - Watch transfer and disk usage monthly; upgrade before CPU/RAM saturation. 188 189 --- 190 191 ## References 192 193 - DigitalOcean Droplet pricing: https://www.digitalocean.com/pricing/droplets 194 - DigitalOcean pricing calculator: https://www.digitalocean.com/pricing/calculator 195 - DigitalOcean bandwidth overage + backups + storage examples: https://docs.digitalocean.com/products/droplets/details/pricing/