Apache Superset on a VPS: Self-Hosted BI and Data Visualization Dashboards
Apache Superset is a modern, open-source business intelligence platform — connect to databases (PostgreSQL, MySQL, ClickHouse, BigQuery, Snowflake, 30+ more), build charts with a no-code drag-and-drop interface, assemble dashboards, write SQL in a built-in editor, set up scheduled email reports, and control access with row-level security. Tableau costs $75/user/month. Superset runs on your VPS for free.
Step 1: Docker Compose Setup
<code">mkdir -p /opt/superset && cd /opt/superset
# Download official docker-compose files
wget https://raw.githubusercontent.com/apache/superset/master/docker-compose-image-tag.yml \
-O docker-compose.yml
wget https://raw.githubusercontent.com/apache/superset/master/docker/.env-non-dev \
-O .env
nano .env
<code"># Update in .env: SUPERSET_SECRET_KEY=$(openssl rand -hex 32) SUPERSET_ADMIN_USERNAME=admin SUPERSET_ADMIN_FIRSTNAME=Admin SUPERSET_ADMIN_LASTNAME=User [email protected] SUPERSET_ADMIN_PASSWORD=StrongSupersetPassword! POSTGRES_DB=superset POSTGRES_USER=superset POSTGRES_PASSWORD=StrongSupersetDbPassword!
<code">chmod 600 .env docker compose up -d # First-time initialization (runs migrations, creates admin user): docker compose exec superset_app superset db upgrade docker compose exec superset_app superset init # Check all services are healthy: docker compose ps
Step 2: Nginx Reverse Proxy
<code">sudo nano /etc/nginx/sites-available/superset
<code">server {
listen 443 ssl http2;
server_name bi.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/bi.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bi.yourdomain.com/privkey.pem;
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:8088;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_read_timeout 300s;
}
}
<code">sudo certbot --nginx -d bi.yourdomain.com sudo systemctl reload nginx
Step 3: Connect Databases
<code"># In Superset UI → Settings → Database Connections → + Database # PostgreSQL connection: # Display Name: Production Postgres # SQLAlchemy URI: postgresql://username:password@localhost/dbname # Test Connection → Save # ClickHouse connection: # Install driver first: docker compose exec superset_app pip install clickhouse-sqlalchemy # URI: clickhouse://user:password@host:8123/database # MySQL/MariaDB: # URI: mysql://user:password@host/database # SQLite: # URI: sqlite:////path/to/db.sqlite3
Step 4: Build Charts
<code"># Create a chart:
# Charts → + Chart → select dataset → choose chart type
# Chart types available:
# - Bar chart, Line chart, Area chart, Scatter plot
# - Pie chart, Donut chart
# - Heatmap, Bubble chart
# - Table, Pivot table
# - Big Number (KPI card)
# - Maps (choropleth, scatter)
# - Time-series forecasting
# Example: Monthly revenue bar chart
# Dataset: orders table
# Metric: SUM(amount)
# Dimension (X axis): DATE_TRUNC('month', created_at)
# Filters: status = 'completed'
# Sort: time ascending
# No SQL needed — but SQL Lab is available for complex queries
Step 5: SQL Lab for Ad-Hoc Queries
<code"># SQL Lab → select database → write queries:
SELECT
DATE_TRUNC('month', created_at) AS month,
COUNT(DISTINCT user_id) AS active_users,
SUM(revenue) AS total_revenue,
AVG(revenue) AS avg_revenue_per_user
FROM orders
WHERE status = 'completed'
AND created_at >= NOW() - INTERVAL '12 months'
GROUP BY 1
ORDER BY 1;
# Features in SQL Lab:
# - Auto-complete table and column names
# - Query history
# - Save queries for reuse
# - Export results as CSV
# - Create chart directly from query results
Step 6: Scheduled Email Reports
<code"># Superset can send dashboard screenshots via email on schedule: # Settings → Dashboard → Schedule → Email Recipients # Frequency: Daily at 9 AM # Recipients: [email protected] # Configure email in superset_config.py: SMTP_HOST = "smtp.mailgun.org" SMTP_STARTTLS = True SMTP_SSL = False SMTP_USER = "[email protected]" SMTP_PORT = 587 SMTP_PASSWORD = "your_smtp_password" SMTP_MAIL_FROM = "[email protected]" # Configure Celery worker for async tasks (required for email reports): # Already included in the official docker-compose
Step 7: Row-Level Security
<code"># Restrict users to see only their own data:
# Security → Row Level Security Filters
# Example: Sales reps only see their region's data
# Table: orders
# Clause: region = '{{ current_username() }}'
# Roles: Sales Rep role
# More complex example using role tables:
# Clause: store_id IN (SELECT store_id FROM user_stores WHERE username = '{{ current_username() }}')
Getting Started
Superset’s Docker stack uses 1–2 GB RAM (Flask app + Celery workers + Redis + PostgreSQL). A 4 GB Ubuntu VPS at VPS.DO runs Superset comfortably. NVMe storage improves PostgreSQL metadata query performance. For teams replacing Tableau ($75/user/month) or Looker ($3,000/year), Superset’s self-hosted deployment on a VPS saves thousands annually while keeping business data within your infrastructure.
Conclusion
Apache Superset provides enterprise-grade BI — connecting to 30+ databases, building charts with a no-code interface, assembling dashboards, running SQL ad-hoc queries, scheduling email reports, and enforcing row-level security. Self-hosted on a VPS, it replaces Tableau, Looker, and Metabase Cloud at infrastructure cost. For data-driven teams, Superset’s SQL Lab and chart builder provide the analytical power that previously required expensive BI tools.