Redash remains one of the most approachable open-source tools for building dashboards, sharing SQL queries, and collaborating on data.

While the project is no longer actively maintained upstream, the community builds (10.x) are still widely used for internal analytics.

In this article, I’ll show how to bring up Redash quickly on Debian 12 using Docker Compose. We’ll focus on the two files that matter most: the .env and the docker-compose.yaml.

This assumes you already have Docker Engine and Docker Compose v2 installed.

1. Directory Layout

Create a workspace for your Redash stack:

sudo mkdir -p /var/app/docker/redash-example
cd /var/app/docker/redash-example
mkdir -p data/postgres data/redis logs

This folder will hold:

  • data/postgres → PostgreSQL data files
  • data/redis → Redis persistence
  • logs → container logs if needed
  • .env and docker-compose.yaml

2. Environment File (.env)

The .env file holds all credentials and configuration. Redash services will consume these automatically.

# =========================
# Redash on Docker (.env)
# =========================

# ---- Postgres
POSTGRES_USER=redash
POSTGRES_PASSWORD=change_me_strong_pw
POSTGRES_DB=redash

# ---- Redis
REDIS_PASSWORD=another_strong_pw

# ---- Redash image
REDASH_IMAGE=redash/redash:10.1.0.b50633

# ---- Core secrets
REDASH_SECRET_KEY=REPLACE_WITH_64B_BASE64
REDASH_COOKIE_SECRET=REPLACE_WITH_32B_BASE64

# ---- App behavior
REDASH_RATELIMIT_ENABLED=true
REDASH_LOG_LEVEL=INFO
REDASH_MULTI_ORG=false
REDASH_WEB_WORKERS=4
REDASH_SCHEDULED_QUEUE_NAME=scheduled
REDASH_ADHOC_QUERY_TIME_LIMIT=600
REDASH_QUERY_TIME_LIMIT=1800
REDASH_CORS_ACCESS_CONTROL_ALLOW_ORIGIN=*

# ---- External URL
REDASH_HOST=http://localhost:50001

# ---- SMTP / Email
REDASH_MAIL_SERVER=smtp-relay.local
REDASH_MAIL_PORT=587
REDASH_MAIL_USE_TLS=true
REDASH_MAIL_USE_SSL=false
[email protected]
REDASH_MAIL_PASSWORD=supersecret
REDASH_MAIL_DEFAULT_SENDER="Redash <[email protected]>"

# =========================
# NOTE:
# Do NOT put REDASH_DATABASE_URL or REDASH_REDIS_URL here.
# They are built dynamically in docker-compose.yaml.
# =========================

Tip, generate strong random secrets with:

openssl rand -base64 64   # for REDASH_SECRET_KEY
openssl rand -base64 32   # for REDASH_COOKIE_SECRET

3. Docker Compose File (docker-compose.yaml)

This Compose file brings up five containers: PostgreSQL, Redis, the Redash server, a worker, and a scheduler.
Since the host already has Nginx, we don’t run Nginx inside the stack — instead we bind the server on localhost:50001.

name: redash-example

services:
  postgres:
    image: postgres:14-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 10

  redis:
    image: redis:7-alpine
    command: ["redis-server", "--appendonly", "yes", "--requirepass", "${REDIS_PASSWORD}"]
    restart: unless-stopped
    volumes:
      - ./data/redis:/data
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "PING"]
      interval: 10s
      timeout: 5s
      retries: 10

  server:
    image: ${REDASH_IMAGE}
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: unless-stopped
    env_file: .env
    environment:
      REDASH_DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}"
      REDASH_REDIS_URL: "redis://:${REDIS_PASSWORD}@redis:6379/0"
      REDASH_SECRET_KEY: ${REDASH_SECRET_KEY}
      REDASH_COOKIE_SECRET: ${REDASH_COOKIE_SECRET}
      REDASH_LOG_LEVEL: ${REDASH_LOG_LEVEL:-INFO}
      REDASH_HOST: ${REDASH_HOST}
      GUNICORN_CMD_ARGS: "--timeout 120 --graceful-timeout 120 --workers ${REDASH_WEB_WORKERS:-2}"
    command: server
    ports:
      - "127.0.0.1:50001:5000"
    healthcheck:
      test: ["CMD", "wget", "-q", "-O-", "http://localhost:5000/healthcheck"]
      interval: 10s
      timeout: 5s
      retries: 30

  worker:
    image: ${REDASH_IMAGE}
    depends_on:
      server:
        condition: service_started
    restart: unless-stopped
    env_file: .env
    environment:
      REDASH_DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}"
      REDASH_REDIS_URL: "redis://:${REDIS_PASSWORD}@redis:6379/0"
      REDASH_SECRET_KEY: ${REDASH_SECRET_KEY}
      QUEUES: "queries,scheduled,celery,schemas,periodic,emails,default"
      WORKERS_COUNT: "2"
    command: worker

  scheduler:
    image: ${REDASH_IMAGE}
    depends_on:
      server:
        condition: service_started
    restart: unless-stopped
    env_file: .env
    environment:
      REDASH_DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}"
      REDASH_REDIS_URL: "redis://:${REDIS_PASSWORD}@redis:6379/0"
      REDASH_SECRET_KEY: ${REDASH_SECRET_KEY}
      QUEUES: "scheduled,celery"
    command: scheduler

4. Initialize Redash

Bring the services up:

docker compose pull
docker compose up -d postgres redis
docker compose run --rm server create_db
docker compose up -d

Check logs:

docker compose logs -f server

Visit: http://localhost:50001

5. Integrate with Host Nginx

If your Debian host already runs Nginx for other sites, just add a vhost:

server {
  listen 443 ssl http2;
  server_name analytics.example.com;

  ssl_certificate /etc/letsencrypt/live/analytics.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/analytics.example.com/privkey.pem;

  location / {
    proxy_pass         http://127.0.0.1:50001;
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
  }
}

Reload:

sudo nginx -t && sudo systemctl reload nginx

Now Redash is available at https://analytics.example.com.

6. Sending Email

Test SMTP from inside the container:

docker compose run --rm server manage send_test_mail

If configured correctly, Redash will send a test message from the REDASH_MAIL_DEFAULT_SENDER.

Closing Notes

That’s all it takes: a .env for configuration, and a docker-compose.yaml for orchestration.

This pattern keeps the stack self-contained while leaving room for scaling or migrating later (for example, moving Postgres to RDS, or Redis to a managed service).

If you already run Nginx on your host, exposing Redash only to 127.0.0.1:50001 is the cleanest way to avoid conflicts and keep your surface minimal.

Happy dashing!!

Leave A Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.