RAM Docker Setup

Containerized deployment guide for RAM PostgreSQL clustering with Docker Compose.

Single Node Setup

Basic Docker Compose

version: '3.8'

services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./postgresql.conf:/etc/postgresql/postgresql.conf
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

  ramd:
    image: pgelephant/ramd:latest
    ports:
      - "8080:8080"
      - "9090:9090"
    environment:
      RAM_CLUSTER_NAME: "single-cluster"
      RAM_NODE_ID: "node1"
      RAM_POSTGRES_HOST: "postgres"
      RAM_POSTGRES_PORT: "5432"
    depends_on:
      - postgres

volumes:
  postgres_data:

PostgreSQL Configuration

# postgresql.conf
shared_preload_libraries = 'pgraft'
max_connections = 200
listen_addresses = '*'
wal_level = replica
max_wal_senders = 10
hot_standby = on

Initialization Script

-- init.sql
CREATE EXTENSION IF NOT EXISTS pgraft;
SELECT pgraft_init_cluster('single-cluster');
SELECT pgraft_add_member('single-cluster', 'node1', 'host=postgres port=5432');

Multi-Node Cluster

3-Node Cluster Setup

version: '3.8'

services:
  postgres1:
    image: postgres:16
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    ports:
      - "5432:5432"
    volumes:
      - postgres1_data:/var/lib/postgresql/data
    command: ["postgres", "-c", "shared_preload_libraries=pgraft"]

  postgres2:
    image: postgres:16
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    ports:
      - "5433:5432"
    volumes:
      - postgres2_data:/var/lib/postgresql/data
    command: ["postgres", "-c", "shared_preload_libraries=pgraft"]

  postgres3:
    image: postgres:16
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    ports:
      - "5434:5432"
    volumes:
      - postgres3_data:/var/lib/postgresql/data
    command: ["postgres", "-c", "shared_preload_libraries=pgraft"]

volumes:
  postgres1_data:
  postgres2_data:
  postgres3_data:

RAM Daemon Configuration

# ramd.conf for node1
[cluster]
name = "production-cluster"
node_id = "node1"

[postgresql]
host = "postgres1"
port = 5432
user = "postgres"
password = "password"

[raft]
listen_addr = "0.0.0.0:8080"
peers = ["node1:8080", "node2:8080", "node3:8080"]

Production Setup

Production Docker Compose

version: '3.8' services: postgres: image: postgres:16 restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "${POSTGRES_PORT}:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./config/postgresql.conf:/etc/postgresql/postgresql.conf - ./ssl:/etc/ssl/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 30s timeout: 10s retries: 3 ramd: image: pgelephant/ramd:latest restart: unless-stopped ports: - "${RAM_PORT}:8080" - "${METRICS_PORT}:9090" environment: RAM_CLUSTER_NAME: ${CLUSTER_NAME} RAM_NODE_ID: ${NODE_ID} RAM_POSTGRES_HOST: postgres RAM_POSTGRES_PORT: 5432 RAM_LOG_LEVEL: info depends_on: postgres: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/health"] interval: 30s timeout: 10s retries: 3

Environment Variables

# .env file
POSTGRES_DB=production
POSTGRES_USER=postgres
POSTGRES_PASSWORD=secure_password
POSTGRES_PORT=5432

CLUSTER_NAME=production-cluster
NODE_ID=node1
RAM_PORT=8080
METRICS_PORT=9090

Monitoring with Docker

Prometheus & Grafana

  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./config/prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_PASSWORD: admin
    volumes:
      - grafana_data:/var/lib/grafana
      - ./config/grafana/dashboards:/etc/grafana/provisioning/dashboards
      - ./config/grafana/datasources:/etc/grafana/provisioning/datasources

Prometheus Configuration

# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'ram-cluster'
    static_configs:
      - targets: ['ramd:9090']
    scrape_interval: 5s

  - job_name: 'postgresql'
    static_configs:
      - targets: ['postgres:9187']

Deployment Commands

Basic Deployment

# Start the cluster
docker-compose up -d

# Check status
docker-compose ps

# View logs
docker-compose logs -f ramd

# Stop the cluster
docker-compose down

# Stop and remove volumes
docker-compose down -v

Cluster Management

# Check cluster status
docker exec -it ramd_ramd_1 ramctrl status --cluster production-cluster

# Add node to cluster
docker exec -it ramd_ramd_1 ramctrl nodes add --cluster production-cluster --node node2:8080

# Trigger failover
docker exec -it ramd_ramd_1 ramctrl failover --cluster production-cluster

# View metrics
curl http://localhost:9090/metrics

Health Checks

# Check PostgreSQL health
docker exec -it ramd_postgres_1 pg_isready -U postgres

# Check RAM health
curl http://localhost:8080/api/v1/health

# Check cluster health
docker exec -it ramd_ramd_1 ramctrl health --cluster production-cluster