Skip to content

Scaling

br\u016bhi Cloud is designed to scale from a single Docker Compose deployment up to thousands of stations on Kubernetes. This page outlines the three scaling tiers and when to use each.

StationsRecommended approachNotes
1–10Docker Compose (single host)Default; zero additional complexity
10–100Docker Compose + vertical scalingIncrease CPU/RAM on the host
100–1,000Docker SwarmHorizontal scaling with built-in orchestration
1,000+KubernetesFull autoscaling, multi-region failover

The default deployment. All stations run in a single container on one machine.

Scale up by upgrading your server hardware:

StationsRecommended CPURAM
1–52 cores2 GB
5–204 cores4 GB
20–508 cores8 GB
50–10016 cores16 GB

Each active Liquidsoap process uses approximately 50–150 MB RAM and 0.1–0.3 CPU cores at 192 kbps output.

Tier 2: Docker Swarm (100–1,000 stations)

Section titled “Tier 2: Docker Swarm (100–1,000 stations)”

Docker Swarm distributes station containers across a cluster of machines. br\u016bhi Cloud’s station engine creates one Swarm service per station.

Terminal window
# On the manager node
docker swarm init
# On worker nodes
docker swarm join --token <token> <manager-ip>:2377
Terminal window
docker stack deploy -c docker-compose.prod.yml bruhi

The station manager dynamically creates and removes Swarm services as stations are added or removed via the API.

RoleCPURAM
Manager4 cores8 GB
Worker8 cores16 GB

With 3 workers at 8 cores / 16 GB each, you can comfortably run 200–300 concurrent stations.

For very large deployments, Kubernetes provides:

  • Automatic pod scheduling
  • Horizontal pod autoscaling based on CPU/memory
  • Rolling updates without downtime
  • Multi-region failover

Each station runs as a Kubernetes Deployment with one pod:

apiVersion: apps/v1
kind: Deployment
metadata:
name: station-{{ station_id }}
namespace: bruhi
spec:
replicas: 1
selector:
matchLabels:
app: bruhi-station
station: "{{ station_id }}"
template:
spec:
containers:
- name: liquidsoap
image: savonet/liquidsoap:latest
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
volumeMounts:
- name: station-config
mountPath: /config/station.liq

At scale, local volume storage becomes a bottleneck. Recommendations:

TierStorage approach
Docker ComposeLocal disk or NFS volume
SwarmShared NFS volume or S3 for media
KubernetesS3 (AWS, R2, MinIO) for all media

Use S3 Storage to decouple media from the container lifecycle.

  • Configure a load balancer for the API/dashboard (ports 8000 and 8005)
  • Move media to S3 — do not rely on local disk for production
  • Set up monitoring: CPU/memory per node, stream health per station (listener count, connection drops)
  • Enable Icecast stats endpoint for listener tracking
  • Set up log aggregation (Loki, ELK, Datadog) — container logs are ephemeral
  • Plan for Liquidsoap process crashes: auto-restart policy (restart: always in Compose, restartPolicy: Always in K8s)