Eric Radman : a Journal

Redash on Kubernetes

A production deployment of Redash involves five components:

For this example PostgreSQL is configured as an external service.

This deployment also sets up a worker dedicated to the periodic queue, which is required under heavy load to prevent Redis keys from incorrectly expiring.

Deployment

 ---
apiVersion: v1
kind: Service
metadata:
  name: redash
spec:
  ports:
  - port: 80
    targetPort: 5000
  selector:
    app: redash
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redash
  labels:
    app: redash
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redash
  template:
    metadata:
      labels:
        app: redash
    spec:
      containers:

        - name: redash-web
          image: redash/preview:25.01.0-dev
          resources:
            requests:
              memory: 512Mi
          ports:
            - name: redash-server
              containerPort: 5000
          envFrom:
            - configMapRef:
                name: redash-env
          args: ["server"]

        - name: redash-worker
          image: redash/preview:25.01.0-dev
          resources:
            requests:
              memory: 256Mi
          envFrom:
            - configMapRef:
                name: redash-env
          env:
            - name: WORKERS_COUNT
              value: "3"
          args: ["worker"]

        - name: redash-worker-periodic
          image: redash/preview:25.01.0-dev
          resources:
            requests:
              memory: 256Mi
          envFrom:
            - configMapRef:
                name: redash-env
          env:
            - name: WORKERS_COUNT
              value: "1"
            - name: QUEUES
              value: "periodic"
          args: ["worker"]

        - name: redash-scheduler
          image: redash/preview:25.01.0-dev
          resources:
            requests:
              memory: 256Mi
          envFrom:
            - configMapRef:
                name: redash-env
          args: ["scheduler"]

        - name: redis
          image: redis:7-alpine
          ports:
            - name: redis
              containerPort: 6379
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: redash-env
data:
  PYTHONUNBUFFERED: "0"
  REDASH_COOKIE_SECRET: "******"
  REDASH_DATABASE_URL: "postgresql://redash:******@192.168.2.30:5432/redash"
  REDASH_REDIS_URL: "redis://localhost:6379/0"
  REDASH_FEATURE_ALLOW_CUSTOM_JS_VISUALIZATIONS: "true"

Database Initialization and Upgrade

We can define an alias for executing commands

alias redash-exec='kubectl exec -ti $(kubectl get pods -l app=redash -o name)'

To create a new Redash database

redash-exec -- ./manage.py database create_tables

After updating to a new version, update the schema

redash-exec -- ./manage.py db upgrade

Create users

redash-exec -- ./manage.py users create_root eradman@eradman.com Redash --password '******'

Create a datasource

OPTIONS='{"dbname": "mydb", "host": "192.168.2.30", "port": 5432, "user": "reports_user", "password": "******"}'
redash-exec -- ./manage.py ds new --type pg --options "$OPTIONS" mydb