Kubernetes
This guide provides instructions for deploying Broadcast Suite on Kubernetes. The assumption is that Kubernetes is already installed and configured.
Overview
The Broadcast Suite Kubernetes deployment consists of the following components:
- PostgreSQL Database: A non-persistent PostgreSQL database for development/testing purposes
- Broadcast Suite Core: Handles the business logic and connections
- Broadcast Suite GUI: The web-based user interface
- Broadcast Suite API: The REST and gRPC API services
- Ingress: NGINX ingress controller for external access
Prerequisites
Before deploying, ensure you have the following:
- A running Kubernetes cluster
kubectlconfigured to communicate with your cluster- NGINX Ingress Controller installed in your cluster
- A valid TLS certificate (referenced as
tls-ingressin the example)
Deployment Configuration
The deployment is defined in a single YAML file containing all necessary Kubernetes resources.
PostgreSQL Database
The PostgreSQL database is deployed as a non-persistent deployment for development and testing purposes.
The PostgreSQL deployment uses non-persistent storage. All data will be lost when the pod is restarted. For production use, configure persistent volumes or use an external database.
Key configuration parameters:
- Database Name:
postgres - Username:
postgres - Password:
postgres(change for production!) - Port:
5432 - Service Name:
db(used for internal cluster communication)
Broadcast Suite
Broadcast Suite is deployed with three containers in a single pod:
Core Container
- Image:
git.broadcastsuite.com/broadcastsuite/broadcastsuite-core:2025.9.2 - Ports: 8085 (HTTP), 8086 (gRPC), 9000 (Ember+)
GUI Container
- Image:
git.broadcastsuite.com/broadcastsuite/broadcastsuite-gui:2025.9.2 - Port: 5000 (HTTP)
- Configuration: Connects to API on ports 8091 (REST), 8092 (gRPC)
API Container
- Image:
git.broadcastsuite.com/broadcastsuite/broadcastsuite-api:2025.9.2 - Ports: 8091 (REST API), 8092 (gRPC)
The image tags correspond to the version number. The current version used in this documentation is 2025.9.2.
All containers share the following environment variables:
ASPNETCORE_ENVIRONMENT: Set toProductionASPNETCORE_FORWARDEDHEADERS_ENABLED: Set totruefor proper proxy handlingDatabase__ConnectionString: Connection string to the PostgreSQL database
Ingress Configuration
The Ingress resource provides external access to the GUI through HTTPS.
- Ingress Class:
nginx - SSL/TLS: Enabled with automatic redirect from HTTP to HTTPS
- Upload Size: Maximum request body size set to 50MB
- Host: Configure your domain (example:
helloworld.broadcastsuite.cloud)
Update the host and secretName fields in the Ingress configuration to match your domain and TLS certificate.
Deployment Steps
Step 1: Create the Deployment Configuration
Create a file named broadcastsuite.yaml with the following content:
# PostgreSQL Database (Non-Persistent)
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
labels:
app: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16-alpine
env:
- name: POSTGRES_DB
value: "postgres"
- name: POSTGRES_USER
value: "postgres"
- name: POSTGRES_PASSWORD
value: "postgres"
ports:
- containerPort: 5432
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: db
labels:
app: postgres
spec:
type: ClusterIP
selector:
app: postgres
ports:
- name: postgres
port: 5432
targetPort: 5432
protocol: TCP
---
# Broadcast Suite
apiVersion: apps/v1
kind: Deployment
metadata:
name: broadcastsuite
labels:
app: broadcastsuite
spec:
replicas: 1
selector:
matchLabels:
app: broadcastsuite
template:
metadata:
labels:
app: broadcastsuite
spec:
containers:
- name: core
image: git.broadcastsuite.com/broadcastsuite/broadcastsuite-core:2025.9.2
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: ASPNETCORE_FORWARDEDHEADERS_ENABLED
value: "true"
- name: Database__ConnectionString
value: "Host=db;Database=broadcastsuite;Username=postgres;Password=postgres;"
ports:
- containerPort: 8085
protocol: TCP
- containerPort: 8086
protocol: TCP
- containerPort: 9000
protocol: TCP
- name: gui
image: git.broadcastsuite.com/broadcastsuite/broadcastsuite-gui:2025.9.2
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: ASPNETCORE_FORWARDEDHEADERS_ENABLED
value: "true"
- name: Database__ConnectionString
value: "Host=db;Database=broadcastsuite;Username=postgres;Password=postgres;"
- name: Api__BaseUrl
value: "http://localhost"
- name: Kestrel__ListenPort
value: "5000"
- name: Api__Port
value: "8091"
- name: Api__GrpcPort
value: "8092"
ports:
- containerPort: 5000
protocol: TCP
- name: api
image: git.broadcastsuite.com/broadcastsuite/broadcastsuite-api:2025.9.2
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: ASPNETCORE_FORWARDEDHEADERS_ENABLED
value: "true"
- name: Database__ConnectionString
value: "Host=db;Database=broadcastsuite;Username=postgres;Password=postgres;"
- name: Api__Port
value: "8091"
- name: Api__GrpcPort
value: "8092"
ports:
- containerPort: 8091
protocol: TCP
- containerPort: 8092
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: broadcastsuite
labels:
app: broadcastsuite
spec:
type: ClusterIP
selector:
app: broadcastsuite
ports:
- name: core-8085
port: 8085
targetPort: 8085
protocol: TCP
- name: core-8086
port: 8086
targetPort: 8086
protocol: TCP
- name: core-9000
port: 9000
targetPort: 9000
protocol: TCP
- name: gui-5000
port: 5000
targetPort: 5000
protocol: TCP
- name: api-8091
port: 8091
targetPort: 8091
protocol: TCP
- name: api-8092
port: 8092
targetPort: 8092
protocol: TCP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: broadcastsuite-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
spec:
ingressClassName: nginx
tls:
- hosts:
- helloworld.broadcastsuite.cloud
secretName: tls-ingress
rules:
- host: helloworld.broadcastsuite.cloud
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: broadcastsuite
port:
number: 5000
Update the following values in the configuration:
- Database credentials (replace default
postgres/postgreswith secure values) - Ingress host name (replace
helloworld.broadcastsuite.cloudwith your domain) - TLS secret name (replace
tls-ingresswith your certificate secret)
Step 2: Deploy to Kubernetes
Apply the configuration to your cluster:
kubectl apply -f broadcastsuite.yaml
Step 3: Verify the Deployment
Check the status of the pods:
kubectl get pods
Check the services:
kubectl get services
Check the ingress:
kubectl get ingress
Wait for all pods to be in Running status. You can monitor the logs:
kubectl logs -f deployment/broadcastsuite -c gui
kubectl logs -f deployment/broadcastsuite -c core
kubectl logs -f deployment/broadcastsuite -c api
Accessing the Application
Once all pods are running, you can access the application:
- External access:
https://your-domain.com(as configured in the Ingress) - Internal access (from within the cluster):
http://broadcastsuite:5000
Configuration
You can customize the deployment by modifying environment variables or using ConfigMaps and Secrets.
Using ConfigMaps
For non-sensitive configuration, create a ConfigMap:
kubectl create configmap broadcastsuite-config \
--from-literal=Api__BaseUrl=http://localhost \
--from-literal=Api__Port=8091
Using Secrets
For sensitive information like database credentials:
kubectl create secret generic broadcastsuite-db \
--from-literal=connection-string='Host=db;Database=broadcastsuite;Username=postgres;Password=<secure-password>'
Reference these in your deployment:
env:
- name: Database__ConnectionString
valueFrom:
secretKeyRef:
name: broadcastsuite-db
key: connection-string
Persistent Storage
The provided configuration uses non-persistent storage for the database. For production deployments, configure persistent volumes:
Create a PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
Mount the Volume
Add the volume to the PostgreSQL deployment:
spec:
template:
spec:
containers:
- name: postgres
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
For production environments, consider using an external managed database service instead of running PostgreSQL in the cluster.
Scaling
You can scale the GUI and API components by adjusting the replica count.
Only the GUI and API components support scaling. The Core component should always run as a single instance (replicas=1).
To scale the GUI and API, you need to create separate deployments for each component instead of running all three in a single pod.
Troubleshooting
Pods Not Starting
- Check pod status:
kubectl describe pod <pod-name> - Check logs:
kubectl logs <pod-name> -c <container-name> - Ensure sufficient cluster resources (CPU, memory)
Database Connection Issues
- Verify the database pod is running:
kubectl get pods - Check database logs:
kubectl logs deployment/postgres - Verify the connection string in the application environment variables
- Test connectivity:
kubectl exec -it deployment/broadcastsuite -c api -- ping db
Ingress Not Working
- Verify NGINX Ingress Controller is installed:
kubectl get pods -n ingress-nginx - Check ingress status:
kubectl describe ingress broadcastsuite-ingress - Verify DNS is pointing to the ingress controller's external IP
- Check TLS certificate:
kubectl get secret tls-ingress
Application Errors
- Check application logs for all containers
- Verify environment variables are correctly set
- Ensure database migrations have completed successfully
- Check for version compatibility between Core, GUI, and API components