Skip to content

Instantly share code, notes, and snippets.

@benjsicam
Last active October 19, 2022 07:53
Show Gist options
  • Save benjsicam/7a52efd0bdeaf7cba4f926999a896064 to your computer and use it in GitHub Desktop.
Save benjsicam/7a52efd0bdeaf7cba4f926999a896064 to your computer and use it in GitHub Desktop.
Metabase Horizontal Scaling

Overview

Below is a Docker Compose file with 3 instances of Metabase connecting to the same PostgreSQL database and a shared volume mount.

version: "3"

services:
  metabase-instance1:
    image: "metabase/metabase:v0.32.9"
    container_name: "metabase-instance1"
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1024M
        reservations:
          cpus: '0.25'
          memory: 256M
    volumes:
      - metabase-data:/tmp
    networks:
      - "frontend"
      - "backend"
    expose: 
      - "3000"
    depends_on:
      - "metabase-db"
    environment:
      MB_DB_TYPE: "postgres"
      MB_DB_HOST: "metabase-db"
      MB_DB_PORT: "5432"
      MB_DB_USER: "postgres"
      MB_DB_PASS: "postgres"
      MB_DB_DBNAME: "postgres"
      MB_DB_FILE: "/tmp/metabase.db"
    restart: "on-failure"
  
  metabase-instance2:
    image: "metabase/metabase:v0.32.9"
    container_name: "metabase-instance2"
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1024M
        reservations:
          cpus: '0.25'
          memory: 256M
    volumes:
      - metabase-data:/tmp
    networks:
      - "frontend"
      - "backend"
    expose: 
      - "3000"
    depends_on:
      - "metabase-db"
    environment:
      MB_DB_TYPE: "postgres"
      MB_DB_HOST: "metabase-db"
      MB_DB_PORT: "5432"
      MB_DB_USER: "postgres"
      MB_DB_PASS: "postgres"
      MB_DB_DBNAME: "postgres"
      MB_DB_FILE: "/tmp/metabase.db"
    restart: "on-failure"
  
  metabase-instance3:
    image: "metabase/metabase:v0.32.9"
    container_name: "metabase-instance3"
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1024M
        reservations:
          cpus: '0.25'
          memory: 256M
    volumes:
      - metabase-data:/tmp
    networks:
      - "frontend"
      - "backend"
    expose: 
      - "3000"
    depends_on:
      - "metabase-db"
    environment:
      MB_DB_TYPE: "postgres"
      MB_DB_HOST: "metabase-db"
      MB_DB_PORT: "5432"
      MB_DB_USER: "postgres"
      MB_DB_PASS: "postgres"
      MB_DB_DBNAME: "postgres"
      MB_DB_FILE: "/tmp/metabase.db"
    restart: "on-failure"

  metabase-lb:
    image: "nginx:1.16.0"
    container_name: "metabase-lb"
    networks:
      - "frontend"
    ports:
      - "8000:8000"
    depends_on:
      - "metabase-instance1"
      - "metabase-instance2"
      - "metabase-instance3"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    restart: "on-failure"

  metabase-db:
    image: "postgres:11.4-alpine"
    container_name: "metabase-db"
    volumes:
      - metabase-db-data:/var/lib/postgresql/data
    networks:
      - "backend"
    expose:
      - "5432"
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "postgres"
    restart: "on-failure"

networks:
  frontend:
  backend:

volumes: 
  metabase-data:
  metabase-db-data:

To serve requests from the same back-end per client, we used NGINX and setup upstream servers to use ip_hash load balancing method. Sample configuration below:

user  nginx;

events {
  worker_connections 1024;
}

http {
  upstream metabase {
    ip_hash;
    server metabase-instance1:3000;
    server metabase-instance2:3000;
    server metabase-instance3:3000;
  }

  server {
    listen 8000;
    location / {
      proxy_pass http://metabase;
    }
  }
}

Related metabase issues

  1. metabase/metabase#2754
  2. metabase/metabase#6891
  3. metabase/metabase#5736

See it in action (Youtube video)

Metabase Horizontal Scaling

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment