production-agentic-rag-course Docker & Self-Hosted Deployment

GitHub

Python repository by @jamwithai. AI agent rules & system prompts with 10k stars.

10,003 stars Python Python 1 file ยท ~23,318 tokens
RAW Compose
1. Pull Image (DOCKERHUB) docker pull library/redis
2. Docker Run (1-Click Launch) docker run -d --name production-agentic-rag-course -p 8000:8000 --restart always redis:7-alpine
3. Podman Run podman run -d --name production-agentic-rag-course -p 8000:8000 --restart always redis:7-alpine
4. Skopeo Inspect (Zero-Pull Manifest) skopeo inspect docker://docker.io/library/redis:7-alpine
5. ORAS Pull (OCI Artifact) oras pull redis:7-alpine
6. Compose Deployment docker compose up -d
compose.yml
Download .yml
services:
  # API service
  api:
    build: .
    container_name: rag-api
    ports:
      - "8000:8000"
    depends_on:
      postgres:
        condition: service_healthy
      opensearch:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/api/v1/health')\""]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    env_file:
      - .env
    environment:
      # Container-specific overrides
      - OPENSEARCH_HOST=http://opensearch:9200
      - OPENSEARCH__HOST=http://opensearch:9200
      - OLLAMA_HOST=http://ollama:11434
      - POSTGRES_DATABASE_URL=postgresql+psycopg2://rag_user:rag_password@postgres:5432/rag_db
      - LANGFUSE_HOST=http://langfuse-web:3000 
      - LANGFUSE_DEBUG=true
      - REDIS__HOST=redis
    networks:
      - rag-network

  redis:
    image: redis:7-alpine
    container_name: rag-redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3
      start_period: 10s
    restart: unless-stopped
    networks:
      - rag-network

  opensearch:
    image: opensearchproject/opensearch:2.19.0
    container_name: rag-opensearch
    environment:
      - discovery.type=single-node
      - OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m
      - DISABLE_SECURITY_PLUGIN=true
      - bootstrap.memory_lock=true
    ports:
      - "9200:9200"
      - "9600:9600"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - opensearch_data:/usr/share/opensearch/data
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:9200/_cluster/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s
    restart: unless-stopped
    networks:
      - rag-network

  opensearch-dashboards:
    image: opensearchproject/opensearch-dashboards:2.19.0
    container_name: rag-dashboards
    ports:
      - "5601:5601"
    environment:
      - OPENSEARCH_HOSTS=http://opensearch:9200
      - DISABLE_SECURITY_DASHBOARDS_PLUGIN=true
    depends_on:
      - opensearch
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:5601/api/status || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s
    networks:
      - rag-network

  airflow:
    build: 
      context: ./airflow
      dockerfile: Dockerfile
    container_name: rag-airflow
    # user: "50000:0"  # Uncomment for WSL/Ubuntu, comment out for Mac
    depends_on:
      postgres:
        condition: service_healthy
    env_file:
      - .env
    environment:
      # Airflow-specific environment setup
      - AIRFLOW_HOME=/opt/airflow
      - PYTHONPATH=/opt/airflow/src
      # Container hostnames for Airflow
      - POSTGRES_DATABASE_URL=postgresql+psycopg2://rag_user:rag_password@postgres:5432/rag_db
      - OPENSEARCH_HOST=http://opensearch:9200
      - OPENSEARCH__HOST=http://opensearch:9200
      - OLLAMA_HOST=http://ollama:11434
      - REDIS__HOST=redis
    volumes:
      - ./airflow/dags:/opt/airflow/dags
      - airflow_logs:/opt/airflow/logs
      - ./airflow/plugins:/opt/airflow/plugins
      - ./src:/opt/airflow/src
    ports:
      - "8080:8080"
    # Command handled by entrypoint.sh
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 120s
    networks:
      - rag-network

  ollama:
    image: ollama/ollama:0.11.2
    container_name: rag-ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    healthcheck:
      test: ["CMD", "ollama", "list"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - rag-network

  postgres:
    image: postgres:16-alpine
    container_name: rag-postgres
    environment:
      - POSTGRES_DB=rag_db
      - POSTGRES_USER=rag_user
      - POSTGRES_PASSWORD=rag_password
      - POSTGRES_HOST_AUTH_METHOD=password
      - PGDATA=/var/lib/postgresql/data/pgdata
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U rag_user -d rag_db"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 30s
    restart: unless-stopped
    networks:
      - rag-network

  # ClickHouse for Langfuse analytics
  clickhouse:
    image: clickhouse/clickhouse-server:24.8-alpine
    container_name: rag-clickhouse
    environment:
      - CLICKHOUSE_DB=langfuse
      - CLICKHOUSE_USER=langfuse
      - CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1
      - CLICKHOUSE_PASSWORD=langfuse
    volumes:
      - clickhouse_data:/var/lib/clickhouse
    healthcheck:
      test: ["CMD", "clickhouse-client", "--query", "SELECT 1"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s
    restart: unless-stopped
    networks:
      - rag-network

  langfuse-worker:
    image: docker.io/langfuse/langfuse-worker:3
    container_name: rag-langfuse-worker
    restart: unless-stopped
    depends_on:
      langfuse-postgres:
        condition: service_healthy
      langfuse-minio:
        condition: service_healthy
      langfuse-redis:
        condition: service_healthy
      clickhouse:
        condition: service_healthy
    ports:
      - "3030:3030"
    environment:
      NEXTAUTH_URL: http://localhost:3001
      DATABASE_URL: postgresql://langfuse:langfuse@langfuse-postgres:5432/langfuse
      # Security: Load sensitive values from .env file
      SALT: ${LANGFUSE_SALT}
      ENCRYPTION_KEY: ${LANGFUSE_ENCRYPTION_KEY}
      TELEMETRY_ENABLED: "false"
      LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES: "true"
      CLICKHOUSE_MIGRATION_URL: clickhouse://clickhouse:9000
      CLICKHOUSE_URL: http://clickhouse:8123
      CLICKHOUSE_USER: langfuse
      CLICKHOUSE_PASSWORD: langfuse
      CLICKHOUSE_CLUSTER_ENABLED: "false"
      LANGFUSE_USE_AZURE_BLOB: "false"
      LANGFUSE_S3_EVENT_UPLOAD_BUCKET: langfuse
      LANGFUSE_S3_EVENT_UPLOAD_REGION: auto
      LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID: ${LANGFUSE_MINIO_ACCESS_KEY}
      LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY: ${LANGFUSE_MINIO_SECRET_KEY}
      LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT: http://langfuse-minio:9000
      LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE: "true"
      LANGFUSE_S3_EVENT_UPLOAD_PREFIX: events/
      LANGFUSE_S3_MEDIA_UPLOAD_BUCKET: langfuse
      LANGFUSE_S3_MEDIA_UPLOAD_REGION: auto
      LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID: ${LANGFUSE_MINIO_ACCESS_KEY}
      LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY: ${LANGFUSE_MINIO_SECRET_KEY}
      LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT: http://localhost:9090
      LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE: "true"
      LANGFUSE_S3_MEDIA_UPLOAD_PREFIX: media/
      REDIS_HOST: langfuse-redis
      REDIS_PORT: 6379
      REDIS_AUTH: ${LANGFUSE_REDIS_PASSWORD}
      REDIS_TLS_ENABLED: "false"
    networks:
      - rag-network

  langfuse-web:
    image: docker.io/langfuse/langfuse:3
    container_name: rag-langfuse-web
    restart: unless-stopped
    depends_on:
      langfuse-postgres:
        condition: service_healthy
      langfuse-minio:
        condition: service_healthy
      langfuse-redis:
        condition: service_healthy
      clickhouse:
        condition: service_healthy
    ports:
      - "3001:3000"
    environment:
      NEXTAUTH_URL: http://localhost:3001
      # Security: Load sensitive values from .env file
      NEXTAUTH_SECRET: ${LANGFUSE_NEXTAUTH_SECRET}
      DATABASE_URL: postgresql://langfuse:langfuse@langfuse-postgres:5432/langfuse
      SALT: ${LANGFUSE_SALT}
      ENCRYPTION_KEY: ${LANGFUSE_ENCRYPTION_KEY}
      TELEMETRY_ENABLED: "false"
      LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES: "true"
      CLICKHOUSE_MIGRATION_URL: clickhouse://clickhouse:9000
      CLICKHOUSE_URL: http://clickhouse:8123
      CLICKHOUSE_USER: langfuse
      CLICKHOUSE_PASSWORD: langfuse
      CLICKHOUSE_CLUSTER_ENABLED: "false"
      LANGFUSE_USE_AZURE_BLOB: "false"
      LANGFUSE_S3_EVENT_UPLOAD_BUCKET: langfuse
      LANGFUSE_S3_EVENT_UPLOAD_REGION: auto
      LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID: ${LANGFUSE_MINIO_ACCESS_KEY}
      LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY: ${LANGFUSE_MINIO_SECRET_KEY}
      LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT: http://langfuse-minio:9000
      LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE: "true"
      LANGFUSE_S3_EVENT_UPLOAD_PREFIX: events/
      LANGFUSE_S3_MEDIA_UPLOAD_BUCKET: langfuse
      LANGFUSE_S3_MEDIA_UPLOAD_REGION: auto
      LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID: ${LANGFUSE_MINIO_ACCESS_KEY}
      LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY: ${LANGFUSE_MINIO_SECRET_KEY}
      LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT: http://localhost:9090
      LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE: "true"
      LANGFUSE_S3_MEDIA_UPLOAD_PREFIX: media/
      REDIS_HOST: langfuse-redis
      REDIS_PORT: 6379
      REDIS_AUTH: ${LANGFUSE_REDIS_PASSWORD}
      REDIS_TLS_ENABLED: "false"
      LANGFUSE_INIT_ORG_ID: "default-org"
      LANGFUSE_INIT_ORG_NAME: "RAG Organization"
      LANGFUSE_INIT_PROJECT_NAME: "Agentic RAG"
      LANGFUSE_INIT_USER_EMAIL: "[email protected]"
      LANGFUSE_INIT_USER_NAME: "Admin User"
      LANGFUSE_INIT_USER_PASSWORD: "admin123"
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:3000/api/public/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s
    networks:
      - rag-network

  langfuse-postgres:
    image: postgres:17
    container_name: rag-langfuse-postgres
    restart: unless-stopped
    environment:
      - POSTGRES_USER=langfuse
      - POSTGRES_PASSWORD=langfuse
      - POSTGRES_DB=langfuse
      - POSTGRES_HOST_AUTH_METHOD=password
      - TZ=UTC
      - PGTZ=UTC
    ports:
      - "5433:5432"
    volumes:
      - langfuse_v3_postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U langfuse -d langfuse"]
      interval: 3s
      timeout: 3s
      retries: 10
      start_period: 30s
    networks:
      - rag-network

  langfuse-redis:
    image: docker.io/redis:7
    container_name: rag-langfuse-redis
    restart: unless-stopped
    command: --requirepass langfuse_redis_password
    ports:
      - "6380:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "langfuse_redis_password", "ping"]
      interval: 3s
      timeout: 10s
      retries: 10
    networks:
      - rag-network

  langfuse-minio:
    image: docker.io/minio/minio
    container_name: rag-langfuse-minio
    restart: unless-stopped
    entrypoint: sh
    command: -c 'mkdir -p /data/langfuse && minio server --address ":9000" --console-address ":9001" /data'
    environment:
      - MINIO_ROOT_USER=langfuse_minio
      - MINIO_ROOT_PASSWORD=langfuse_minio_secret
    ports:
      - "9090:9000"
      - "9091:9001"
    volumes:
      - langfuse_v3_minio_data:/data
    healthcheck:
      test: ["CMD", "mc", "ready", "local"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 5s
    networks:
      - rag-network


volumes:
  postgres_data:
  opensearch_data:
  ollama_data:
  airflow_logs:
  clickhouse_data:
  redis_data:
  langfuse_v3_postgres_data:
  langfuse_v3_minio_data:

networks:
  rag-network:
    driver: bridge