Search & Analytics

    Self-Hosted Elasticsearch

    Deploy Elasticsearch, the distributed search and analytics engine, on RamNode VPS. Power your log analytics, full-text search, and business intelligence applications.

    Ubuntu 22.04/24.04 LTS
    Elasticsearch 8.x
    ⏱️ 30-45 minutes

    Why Elasticsearch on RamNode?

    Elasticsearch is a distributed, RESTful search and analytics engine built on Apache Lucene. It provides near real-time search capabilities, making it ideal for log analytics, full-text search, security intelligence, and business analytics applications.

    Near real-time search capabilities
    RESTful API for easy integration
    Distributed and scalable architecture
    Built-in security with TLS/SSL
    Powerful aggregation framework
    NVMe storage for low-latency I/O

    Prerequisites

    ComponentMinimumRecommended
    CPU Cores2 vCPU4+ vCPU
    RAM4 GB8+ GB
    Storage50 GB SSD100+ GB NVMe
    OSUbuntu 22.04 LTSUbuntu 24.04 LTS
    JavaJDK 17+OpenJDK 21

    Memory Matters: Elasticsearch is memory-intensive. The JVM heap should be set to 50% of available RAM (max 32GB). A 4GB VPS allows for a 2GB heap, suitable for small datasets. For production workloads, 8GB+ RAM is strongly recommended.

    RamNode VPS Recommendations

    • Premium KVM VPS (4GB+ RAM) for development/testing
    • Premium KVM VPS (8GB+ RAM) for production single-node deployments
    • Multiple VPS instances across locations for high-availability clusters

    Installation

    Step 1: System Preparation

    Connect to your RamNode VPS via SSH and update the system:

    Update System
    ssh root@your-vps-ip
    apt update && apt upgrade -y
    apt install -y apt-transport-https gnupg2 curl

    Step 2: Install Java (OpenJDK)

    Elasticsearch 8.x bundles its own JDK, but installing OpenJDK provides flexibility:

    Install Java
    apt install -y openjdk-17-jdk
    java -version

    Step 3: Add Elasticsearch Repository

    Import the Elasticsearch GPG key and add the official repository:

    Add Repository
    curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | \
      gpg --dearmor -o /usr/share/keyrings/elastic.gpg
    
    echo "deb [signed-by=/usr/share/keyrings/elastic.gpg] \
      https://artifacts.elastic.co/packages/8.x/apt stable main" | \
      tee /etc/apt/sources.list.d/elastic-8.x.list

    Step 4: Install Elasticsearch

    Install Elasticsearch and save the auto-generated security credentials:

    Install Elasticsearch
    apt update
    apt install -y elasticsearch

    Important: During installation, Elasticsearch 8.x automatically generates a password for the 'elastic' superuser and an enrollment token. Copy and securely store these credentials immediately - they are only displayed once!

    Configuration

    Main Configuration File

    Edit the primary Elasticsearch configuration:

    Edit Configuration
    nano /etc/elasticsearch/elasticsearch.yml

    Apply these essential settings for a single-node deployment:

    /etc/elasticsearch/elasticsearch.yml
    # Cluster Settings
    cluster.name: ramnode-elasticsearch
    node.name: es-node-1
    
    # Network Settings
    network.host: 0.0.0.0
    http.port: 9200
    
    # Discovery (single-node mode)
    discovery.type: single-node
    
    # Paths
    path.data: /var/lib/elasticsearch
    path.logs: /var/log/elasticsearch
    
    # Security (enabled by default in 8.x)
    xpack.security.enabled: true
    xpack.security.enrollment.enabled: true
    
    # TLS/SSL for HTTP
    xpack.security.http.ssl:
      enabled: true
      keystore.path: certs/http.p12
    
    # TLS/SSL for Transport
    xpack.security.transport.ssl:
      enabled: true
      verification_mode: certificate
      keystore.path: certs/transport.p12
      truststore.path: certs/transport.p12

    JVM Heap Configuration

    Configure JVM heap size based on your VPS RAM (50% of total, max 32GB):

    Create Heap Options
    nano /etc/elasticsearch/jvm.options.d/heap.options

    For a 4GB VPS

    heap.options
    -Xms2g
    -Xmx2g

    For an 8GB VPS

    heap.options
    -Xms4g
    -Xmx4g

    System Limits

    Elasticsearch requires specific system limits. Create a limits configuration:

    Edit Limits
    nano /etc/security/limits.conf

    Add these lines:

    limits.conf
    elasticsearch soft nofile 65535
    elasticsearch hard nofile 65535
    elasticsearch soft memlock unlimited
    elasticsearch hard memlock unlimited

    Configure virtual memory:

    Configure Virtual Memory
    echo 'vm.max_map_count=262144' >> /etc/sysctl.conf
    sysctl -p

    Security Hardening

    Firewall Configuration

    Configure UFW to restrict access to Elasticsearch:

    Configure UFW
    # Enable UFW
    ufw enable
    
    # Allow SSH
    ufw allow 22/tcp
    
    # Allow Elasticsearch from specific IPs only
    ufw allow from YOUR_APP_SERVER_IP to any port 9200
    
    # For cluster nodes (if applicable)
    ufw allow from CLUSTER_NODE_IP to any port 9300
    
    # Check status
    ufw status verbose
    PortProtocolPurpose
    9200TCPREST API / HTTP interface
    9300TCPNode-to-node communication
    22TCPSSH (admin access only)

    Security Best Practice: Never expose port 9200 to the public internet without authentication. Use a reverse proxy (nginx) with additional authentication, or restrict access to specific application server IPs via firewall rules.

    Reset Elastic User Password

    If you need to reset the elastic superuser password:

    Reset Password
    /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic

    Create Application User

    Create a dedicated user for your application with limited privileges:

    Create Role
    # Create a role with specific index permissions
    curl -k -X POST 'https://localhost:9200/_security/role/app_writer' \
      -u elastic:YOUR_PASSWORD \
      -H 'Content-Type: application/json' \
      -d '{
        "indices": [{
          "names": ["app-*"],
          "privileges": ["read", "write", "create_index"]
        }]
      }'
    Create User
    # Create user with that role
    curl -k -X POST 'https://localhost:9200/_security/user/app_user' \
      -u elastic:YOUR_PASSWORD \
      -H 'Content-Type: application/json' \
      -d '{
        "password": "secure_app_password",
        "roles": ["app_writer"]
      }'

    Starting Elasticsearch

    Enable and Start Service

    Configure Elasticsearch to start automatically and launch the service:

    Start Elasticsearch
    systemctl daemon-reload
    systemctl enable elasticsearch
    systemctl start elasticsearch

    Verify Installation

    Check that Elasticsearch is running and responding:

    Verify Installation
    # Check service status
    systemctl status elasticsearch
    
    # Test API response (with SSL)
    curl -k -u elastic:YOUR_PASSWORD https://localhost:9200
    
    # Check cluster health
    curl -k -u elastic:YOUR_PASSWORD https://localhost:9200/_cluster/health?pretty

    Expected healthy response:

    Expected Response
    {
      "cluster_name" : "ramnode-elasticsearch",
      "status" : "green",
      "timed_out" : false,
      "number_of_nodes" : 1,
      "number_of_data_nodes" : 1,
      "active_primary_shards" : 0,
      "active_shards" : 0,
      ...
    }

    Basic Operations

    Index Management

    Create an index with custom mappings:

    Create Index
    curl -k -X PUT 'https://localhost:9200/products' \
      -u elastic:YOUR_PASSWORD \
      -H 'Content-Type: application/json' \
      -d '{
        "settings": {
          "number_of_shards": 1,
          "number_of_replicas": 0
        },
        "mappings": {
          "properties": {
            "name": { "type": "text" },
            "price": { "type": "float" },
            "category": { "type": "keyword" },
            "created_at": { "type": "date" }
          }
        }
      }'

    Document Operations

    Index a document:

    Index Document
    curl -k -X POST 'https://localhost:9200/products/_doc' \
      -u elastic:YOUR_PASSWORD \
      -H 'Content-Type: application/json' \
      -d '{
        "name": "RamNode VPS",
        "price": 5.00,
        "category": "hosting",
        "created_at": "2025-01-01"
      }'

    Search documents:

    Search Documents
    curl -k -X GET 'https://localhost:9200/products/_search' \
      -u elastic:YOUR_PASSWORD \
      -H 'Content-Type: application/json' \
      -d '{
        "query": {
          "match": { "name": "VPS" }
        }
      }'

    Performance Tuning

    Index Settings for Write-Heavy Workloads

    Optimize for log ingestion or high write throughput:

    Write Optimization
    curl -k -X PUT 'https://localhost:9200/logs/_settings' \
      -u elastic:YOUR_PASSWORD \
      -H 'Content-Type: application/json' \
      -d '{
        "index": {
          "refresh_interval": "30s",
          "number_of_replicas": 0
        }
      }'

    Memory and Cache Settings

    For search-heavy workloads, add to elasticsearch.yml:

    Cache Settings
    # Field data cache (for aggregations)
    indices.fielddata.cache.size: 20%
    
    # Query cache
    indices.queries.cache.size: 10%
    
    # Request circuit breaker
    indices.breaker.request.limit: 40%

    Disk I/O Optimization

    RamNode NVMe storage provides excellent I/O, but you can further optimize:

    • • Use SSDs/NVMe for data paths (default on RamNode Premium VPS)
    • • Avoid swap usage: set vm.swappiness=1 in sysctl.conf
    • • Schedule force merges during low-traffic periods for read-heavy indices

    Monitoring & Maintenance

    Health Monitoring Script

    Create a simple health check script:

    /opt/scripts/es-health-check.sh
    #!/bin/bash
    # /opt/scripts/es-health-check.sh
    
    HEALTH=$(curl -sk -u elastic:YOUR_PASSWORD \
      https://localhost:9200/_cluster/health | jq -r '.status')
    
    if [ "$HEALTH" != "green" ]; then
      echo "WARNING: Elasticsearch cluster status is $HEALTH"
      # Add alerting logic here
    fi

    Key Metrics to Monitor

    • • Cluster health status (green/yellow/red)
    • • JVM heap usage (keep under 75%)
    • • Disk usage (alert at 80%, critical at 90%)
    • • Search latency and indexing rate
    • • CPU utilization during queries

    Useful Monitoring Endpoints

    Monitoring Endpoints
    # Cluster stats
    curl -k -u elastic:YOUR_PASSWORD https://localhost:9200/_cluster/stats
    
    # Node stats
    curl -k -u elastic:YOUR_PASSWORD https://localhost:9200/_nodes/stats
    
    # Index stats
    curl -k -u elastic:YOUR_PASSWORD https://localhost:9200/_stats
    
    # Pending tasks
    curl -k -u elastic:YOUR_PASSWORD https://localhost:9200/_cluster/pending_tasks

    Backup with Snapshots

    Configure a snapshot repository for backups:

    Configure Backups
    # Add to elasticsearch.yml
    # path.repo: ["/var/backups/elasticsearch"]
    
    # Create backup directory
    mkdir -p /var/backups/elasticsearch
    chown elasticsearch:elasticsearch /var/backups/elasticsearch
    
    # Restart Elasticsearch
    systemctl restart elasticsearch
    
    # Register repository
    curl -k -X PUT 'https://localhost:9200/_snapshot/backup' \
      -u elastic:YOUR_PASSWORD \
      -H 'Content-Type: application/json' \
      -d '{
        "type": "fs",
        "settings": { "location": "/var/backups/elasticsearch" }
      }'
    
    # Create snapshot
    curl -k -X PUT 'https://localhost:9200/_snapshot/backup/snapshot_1' \
      -u elastic:YOUR_PASSWORD

    Troubleshooting

    Elasticsearch won't start

    Check logs for specific errors:

    Check Logs
    journalctl -u elasticsearch -f
    cat /var/log/elasticsearch/ramnode-elasticsearch.log

    Out of memory errors

    Reduce heap size or upgrade VPS RAM:

    Check Memory
    # Check current memory usage
    curl -k -u elastic:YOUR_PASSWORD \
      'https://localhost:9200/_nodes/stats/jvm?pretty' | grep heap

    Max virtual memory too low

    Apply the vm.max_map_count setting:

    Fix VM Settings
    sysctl -w vm.max_map_count=262144
    echo 'vm.max_map_count=262144' >> /etc/sysctl.conf

    Bootstrap checks failed

    Ensure all system limits are set:

    Verify Limits
    # Verify limits
    ulimit -n  # Should be 65535+
    ulimit -l  # Should be unlimited

    Cluster status yellow/red

    Check shard allocation:

    Check Shards
    curl -k -u elastic:YOUR_PASSWORD \
      'https://localhost:9200/_cluster/allocation/explain?pretty'

    Next Steps

    • Install Kibana for visualization and management UI
    • Set up Logstash or Beats for data ingestion pipelines
    • Configure Index Lifecycle Management (ILM) for automatic data retention
    • Deploy additional nodes for high availability clustering
    • Implement automated snapshot backups to remote storage

    Deployment Complete!

    Your Elasticsearch instance is now deployed and secured on RamNode. Start indexing data and building powerful search and analytics applications!

    Ready to power your search infrastructure?

    Get started with a RamNode VPS and deploy Elasticsearch in minutes.