[{"data":1,"prerenderedAt":135},["ShallowReactive",2],{"seo-verification":3,"blog-hosting-elasticsearch-on-a-vps-en":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"id":7,"slug":8,"slugs":9,"title":12,"excerpt":13,"readTime":14,"views":15,"isPinned":16,"publishedAt":17,"category":18,"categories":24,"featuredImage":26,"bgImage":27,"posterImage":28,"relatedSolution":26,"intro":29,"sections":30,"ctaTitle":84,"ctaBody":85,"ctaButton":86,"ctaUrl":87,"relatedPosts":88},69,"hosting-elasticsearch-on-a-vps",{"fr":10,"en":8,"ar":11},"heberger-elasticsearch-vps","استضافة-elasticsearch-على-خادم-vps","Hosting Elasticsearch on a VPS: security and troubleshooting","Install and secure Elasticsearch on a VPS: precise JVM prerequisites, Docker deployment, xpack.security, UFW and 5 common errors to avoid.",10,0,false,"2026-04-12T00:00:00+00:00",{"id":19,"name":20,"slug":21,"color":22,"icon":23},6,"Databases","bases-de-donnees","bg-teal-500\u002F10 text-teal-400","database",[25],{"id":19,"name":20,"slug":21,"color":22,"icon":23},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fheberger-elasticsearch-vps-poster.svg","Elasticsearch remains the reference for advanced full-text search, nested aggregations and large-scale log centralization. Managed cloud offerings charge per volume and network egress; on a properly sized VPS, you control the version, analysis plugins and cost. This guide covers step-by-step Docker deployment, xpack security, network hardening and the five failures almost everyone encounters on their first startup.",[31,35,46,49,71,74,78,81],{"type":32,"title":33,"body":34},"h2","Why self-host Elasticsearch on your own VPS","Elasticsearch shines where simple search no longer suffices: configurable BM25 scoring, synonyms, custom linguistic analyzers (French, Arabic ICU), geo-queries, and a full ELK stack to centralize your application logs. Elastic Cloud and OpenSearch Service offerings quickly become costly once indexed volumes exceed a few gigabytes, with egress billing on top. On your VPS, you decide the deployed version, active plugins, retention duration and snapshot policy. It is also the only way to keep sensitive data — application logs, customer indexes — strictly within your own infrastructure, without dependency on a cloud tier.",{"type":36,"title":37,"items":38},"ul","What you gain by self-hosting Elasticsearch",[39,40,41,42,43,44,45],"Advanced full-text search: BM25 scoring, synonyms, custom linguistic analyzers (FR, AR ICU)","Complex aggregations and facets for e-commerce, BI or log centralization","Full ELK stack (Logstash, Beats, Kibana) with no software surcharge","Full control of the version, plugins and index lifecycle policies (ILM)","No billing per indexed volume or network egress fees","Snapshots to your own object storage for controlled disaster recovery","Sensitive data kept within your own infrastructure, under your sole jurisdiction",{"type":32,"title":47,"body":48},"Precise prerequisites before launching the first container","**Minimum RAM: 4 GB** for a test environment, **8 GB (2-4 vCPU)** for a light production instance, **16 GB** as soon as you add Kibana or index several million documents. The key parameter is the JVM heap: set `-Xms` and `-Xmx` to **50% of available RAM, without exceeding 32 GB** (beyond that, the JVM switches to a less efficient pointer compression mode). On an 8 GB RAM VPS, use `-Xms4g -Xmx4g`. On the network side, Elasticsearch uses two ports: **9200** (HTTP, REST API) and **9300** (inter-node transport). **Never** expose port 9200 directly on the public interface — this is the primary source of compromise seen on unsecured instances. On the storage side, an **NVMe SSD is recommended**: Elasticsearch performs many random read operations on Lucene segments; a magnetic disk or low-end SSD will saturate quickly on large indexes. Also plan for Docker and Docker Compose, and an `es.yourdomain.com` subdomain pointed at the VPS.",{"type":50,"title":51,"steps":52},"steps","Step-by-step deployment",[53,56,59,62,65,68],{"title":54,"body":55},"Prepare the Linux kernel","Before launching the container, apply two mandatory system settings. First, increase the memory-mapped zone limit: `sysctl -w vm.max_map_count=262144`. Persist this setting by adding `vm.max_map_count=262144` to `\u002Fetc\u002Fsysctl.conf` — without it, Elasticsearch refuses to start with a `max virtual memory areas vm.max_map_count [65530] is too low` error. Then, disable swap on the VPS (`swapoff -a` and comment out the swap line in `\u002Fetc\u002Ffstab`), or configure `bootstrap.memory_lock=true` in `elasticsearch.yml` so the JVM is never paged to disk, which would catastrophically degrade performance.",{"title":57,"body":58},"Write the docker-compose.yml file","Create a working directory, then a `docker-compose.yml` file with the Elasticsearch service: image `docker.elastic.co\u002Felasticsearch\u002Felasticsearch:8.13.4`, environment variable `ES_JAVA_OPTS=-Xms4g -Xmx4g` (adapt to the VPS), a named volume mounted on `\u002Fusr\u002Fshare\u002Felasticsearch\u002Fdata`, and the port **9200 bound to `127.0.0.1` only** (`127.0.0.1:9200:9200`). Also add `discovery.type=single-node` for a single-node deployment. Never publish `0.0.0.0:9200:9200` in production.",{"title":60,"body":61},"Enable xpack.security and start","In `elasticsearch.yml`, add `xpack.security.enabled: true` and `xpack.security.http.ssl.enabled: true`. Since version 8.x, security is enabled by default, but verify that the configuration file does not explicitly disable it. Start the cluster: `docker compose up -d`. On first startup, wait 2 to 3 minutes — initialization of system indexes (`.security-*`, `.kibana_*`) takes time. Check the logs: `docker compose logs -f elasticsearch`.",{"title":63,"body":64},"Create users and retrieve the elastic password","Once the container is started, reset the `elastic` superuser password: `docker exec -it elasticsearch bin\u002Felasticsearch-reset-password -u elastic`. Store this password in a secrets manager. Then create the `kibana_system` system user if you add Kibana: `docker exec -it elasticsearch bin\u002Felasticsearch-users useradd kibana_system -r kibana_system`. This account must never be used for application queries: create dedicated users per application, with minimum necessary roles.",{"title":66,"body":67},"Verify the cluster with curl","Test the connection from the VPS (not from outside): `curl -u elastic:\u003CPASSWORD> https:\u002F\u002Flocalhost:9200 --cacert \u002Fusr\u002Fshare\u002Felasticsearch\u002Fconfig\u002Fcerts\u002Fhttp_ca.crt`. A JSON response with `cluster_name` and `status: green` or `yellow` confirms the cluster is operational. A `yellow` status on a single-node cluster is normal: shard replicas cannot be allocated without a second node.",{"title":69,"body":70},"Expose via HTTPS reverse proxy with Nginx","Install Nginx on the VPS and configure a virtual host for `es.yourdomain.com`. The reverse proxy forwards requests to `https:\u002F\u002F127.0.0.1:9200` and presents a Let's Encrypt certificate to the client. Add Nginx basic authentication as an additional protection layer if the API must be accessible from outside. Only forward routes necessary for your application — avoid exposing `\u002F_cat\u002F*` or `\u002F_cluster\u002F*` publicly.",{"type":32,"title":72,"body":73},"xpack security: TLS, roles and network isolation","Elasticsearch's xpack security covers three layers. **Inter-node TLS** (`xpack.security.transport.ssl.enabled: true`) encrypts traffic between nodes on port 9300 — essential as soon as a second node joins the cluster. **HTTP TLS** (`xpack.security.http.ssl.enabled: true`) encrypts port 9200; without it, passwords transit in clear even on a private network. **Role control**: Elasticsearch provides predefined roles (`read`, `write`, `monitor`, `kibana_system`, `logstash_writer`). Assign the minimum required role to each application: a service that only reads one index does not need the `superuser` role. Avoid using the `elastic` account in production — reserve it for initial administration. Last point: the `network.host` parameter in `elasticsearch.yml`. Its default value is `_local_` (loopback only). Switching to `0.0.0.0` to listen on all interfaces without having configured xpack security exposes your cluster to the entire internet.",{"type":75,"title":76,"body":77},"tip","Harden network access with UFW","After verifying that Elasticsearch listens only on `127.0.0.1`, lock down the firewall: `ufw deny 9200\u002Ftcp` and `ufw deny 9300\u002Ftcp`. Only the Nginx reverse proxy (port 443) should be accessible. If multiple nodes communicate with each other, explicitly allow node IPs on port 9300 (`ufw allow from \u003CNODE_2_IP> to any port 9300`), and block everything else. A `ufw status` after configuration gives you the exact view of what is open.",{"type":32,"title":79,"body":80},"Troubleshooting: the 5 most common startup errors","**1. OOM Killer kills the Elasticsearch process.** Symptom: the container stops without an error message in logs, `dmesg | grep -i killed` reveals a `Killed process`. Cause: the `-Xmx` heap is too high for available RAM, or other processes are saturating memory. Fix: reduce `-Xmx` to 50% of actual free RAM, and monitor memory consumption with `docker stats`.\n\n**2. `max_map_count` too low.** Symptom: Elasticsearch refuses to start with the error `max virtual memory areas vm.max_map_count [65530] is too low`. Fix: `sysctl -w vm.max_map_count=262144` then add `vm.max_map_count=262144` to `\u002Fetc\u002Fsysctl.conf`.\n\n**3. `Permission denied` on `\u002Fusr\u002Fshare\u002Felasticsearch\u002Fdata`.** Symptom: `AccessDeniedException` error appears in logs when mounting the volume. Cause: the host directory belongs to `root` but the container runs with UID `1000` (user `elasticsearch`). Fix: `chown -R 1000:1000 \u003Chost_volume_path>` before running `docker compose up`.\n\n**4. Connection refused on port 9200.** Symptom: `curl localhost:9200` returns `Connection refused`. Frequent cause: `network.host` is misconfigured in `elasticsearch.yml` (value `_site_` or an IP that does not match the Docker interface). On a single-node Docker cluster, leave `network.host` at its default value (`_local_`) and access via `127.0.0.1:9200` from the container or host. Also check that the container is running: `docker ps`.\n\n**5. Slow startup: normal on first initialization.** Symptom: the cluster takes 2 to 3 minutes to respond on first launch. This is not a failure. Elasticsearch initializes system indexes (`.security-7`, `.kibana_1`, default mappings). Wait until logs show `mode [basic], reason [security is enabled]` or `Cluster health status changed from [RED] to [GREEN]` before sending queries.",{"type":32,"title":82,"body":83},"What if you want a fully open source alternative?","**OpenSearch** is the community fork of Elasticsearch, born in 2021 when Elastic changed its license to SSPL (not OSI-approved). OpenSearch maintains an Apache 2.0 license, offers a largely compatible REST API, and includes advanced security features in its free distribution (role-based access control, audit logging, encryption at rest). If your constraint is strictly the open source license or the absence of dependency on Elastic BV, OpenSearch is a direct alternative to evaluate. Docker deployment follows the same pattern, with the `opensearchproject\u002Fopensearch` image instead.","A VPS built for Elasticsearch","Generous RAM, NVMe SSD and adjustable kernel settings from day one: the ServOrbit Cloud VPS gives you the foundation an Elasticsearch JVM requires in production.","Configure my Cloud VPS","\u002Fvps-cloud",[89,106,120],{"id":90,"slug":91,"slugs":92,"title":95,"excerpt":96,"readTime":97,"views":15,"isPinned":16,"publishedAt":98,"category":99,"categories":100,"featuredImage":26,"bgImage":27,"posterImage":102,"relatedSolution":103},56,"postgresql-on-a-vps-a-reliable-and-controlled-database",{"fr":93,"en":91,"ar":94},"heberger-postgresql-vps","postgresql-على-خادم-vps-قاعدة-بيانات-موثوقة-ومتحكم-بها","PostgreSQL on a VPS: a reliable and controlled database","Host PostgreSQL on a VPS: volumes, backups, restricted network access and sound configuration for your applications.",4,"2026-04-25T00:00:00+00:00",{"id":19,"name":20,"slug":21,"color":22,"icon":23},[101],{"id":19,"name":20,"slug":21,"color":22,"icon":23},"\u002Fblog\u002Fcovers\u002Fheberger-postgresql-vps-poster.svg",{"categorySlug":104,"appSlug":105},"databases","postgresql-stack",{"id":107,"slug":108,"slugs":109,"title":112,"excerpt":113,"readTime":114,"views":15,"isPinned":16,"publishedAt":115,"category":116,"categories":117,"featuredImage":26,"bgImage":27,"posterImage":119,"relatedSolution":26},57,"hosting-mysql-on-a-vps",{"fr":110,"en":108,"ar":111},"heberger-mysql-vps","استضافة-mysql-على-خادم-vps","Hosting MySQL on a VPS","Host MySQL on your Cloud VPS: Docker deployment, hardening, InnoDB tuning, and automated backups, step by step.",3,"2026-04-24T00:00:00+00:00",{"id":19,"name":20,"slug":21,"color":22,"icon":23},[118],{"id":19,"name":20,"slug":21,"color":22,"icon":23},"\u002Fblog\u002Fcovers\u002Fheberger-mysql-vps-poster.svg",{"id":121,"slug":122,"slugs":123,"title":126,"excerpt":127,"readTime":97,"views":15,"isPinned":16,"publishedAt":128,"category":129,"categories":130,"featuredImage":26,"bgImage":27,"posterImage":132,"relatedSolution":133},58,"hosting-redis-on-a-vps",{"fr":124,"en":122,"ar":125},"heberger-redis-vps","استضافة-redis-على-خادم-vps","Hosting Redis on a VPS","Deploy Redis on your Cloud VPS: in-memory cache, sessions, and queues, with persistence, security, and tuning.","2026-04-23T00:00:00+00:00",{"id":19,"name":20,"slug":21,"color":22,"icon":23},[131],{"id":19,"name":20,"slug":21,"color":22,"icon":23},"\u002Fblog\u002Fcovers\u002Fheberger-redis-vps-poster.svg",{"categorySlug":104,"appSlug":134},"redis-stack",1787581001199]