[{"data":1,"prerenderedAt":187},["ShallowReactive",2],{"seo-verification":3,"blog-self-host-neo4j-vps-graph-database-ma-en":6,"promo-bar-likely":186},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-self-host-neo4j-vps-graph-database-ma-en",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":27,"featuredImage":29,"bgImage":30,"posterImage":31,"relatedSolution":32,"intro":35,"sections":36,"ctaTitle":120,"ctaBody":121,"ctaButton":122,"ctaUrl":123,"relatedPosts":124},574,"self-host-neo4j-vps-graph-database",{"fr":12,"en":10,"ar":13,"es":14},"self-host-neo4j-vps","استضافة-neo4j-على-vps-قاعدة-بيانات-رسومية","autoalojar-neo4j-vps-base-de-datos-grafos","Self-Host Neo4j on a VPS: Graph Database, Cypher and GraphRAG","Install Neo4j on a VPS with Docker Compose: Cypher queries, Neo4j Browser and the HTTP API behind nginx over HTTPS, Bolt drivers and vector indexes.",7,0,false,"2026-11-10T00:00:00+00:00","2026-11-10T14:39:01+00:00",{"id":17,"name":23,"slug":24,"color":25,"icon":26},"Self-hosting","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[28],{"id":17,"name":23,"slug":24,"color":25,"icon":26},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fself-host-neo4j-vps-poster.svg",{"categorySlug":33,"appSlug":34},"databases","neo4j","Some data does not fit well in tables: who knows whom, which service depends on which, which document cites which contract. In SQL, every level of relationship costs a join. Neo4j, the most widely used graph database, stores nodes and their relationships directly and queries them in Cypher. This guide installs Neo4j Community Edition on a VPS with Docker Compose, publishes Neo4j Browser and the Bolt connection over HTTPS on a single name, then connects an application and lays the groundwork for GraphRAG.",[37,41,51,82,85,98,102,105,108,111,114,117],{"type":38,"title":39,"body":40},"h2","What Neo4j does","Neo4j records **nodes** — a customer, a product, a server — carrying labels (`:Person`, `:Product`) and properties, connected by directed, named **relationships** (`:KNOWS`, `:BOUGHT`, `:DEPENDS_ON`). A relationship is stored as a direct link between two nodes: following it needs no index lookup, however large the database grows.\n\nYou query it in **Cypher**, a language that draws the pattern you are looking for: `(a:Person)-[:KNOWS]->(b:Person)`. Variable-length paths (`-[:KNOWS*1..3]->`), shortest paths and aggregations fit on one line, where SQL stacks joins or recursive queries.",{"type":42,"title":43,"items":44},"ul","What Neo4j brings",[45,46,47,48,49,50],"**Cypher** — `MATCH`, `MERGE`, variable-length and shortest paths, in a readable language.","**Neo4j Browser** — a web interface that runs queries and draws the resulting graph.","**HTTP API** — one Cypher query per `POST` call, JSON response, from any language.","**Official Bolt drivers** — Python, JavaScript, Java, Go and .NET.","**Indexes and constraints** — uniqueness, full-text search and vector indexes for embeddings.","**ACID transactions** — a consistent graph, even when several applications write to it.",{"type":52,"title":53,"headers":54,"rows":58},"comparison","Neo4j compared with other options",[5,55,56,57],"Neo4j","PostgreSQL","Qdrant",[59,64,69,74,79],[60,61,62,63],"Model","Nodes and relationships","Tables and joins","Vectors and metadata",[65,66,67,68],"Queries","Cypher","SQL","Similarity search",[70,71,72,73],"Strength","Multi-level relationships","Transactions and tabular data","Semantic search",[75,76,77,78],"Role in a RAG","Connected, sourced facts","Business data","Passages close to the question",[80,81,81,81],"Cost","VPS price",{"type":38,"title":83,"body":84},"Prerequisites","An Ubuntu 24.04 VPS with 2 GB of RAM and 20 GB of disk, Docker and the Compose plugin installed, nginx and Certbot on the host, and a subdomain pointing to the VPS, for example `neo4j.example.com`. Neo4j is fastest when the graph fits in its page cache: plan more memory for a graph of tens of millions of nodes.",{"type":86,"title":87,"steps":88},"steps","Install Neo4j with Docker Compose",[89,92,95],{"title":90,"body":91},"Prepare the directory and the password","The `.env` file holds the password of the `neo4j` user. The `backups` folder will receive the backups: it belongs to user 7474, the container's user.\n```bash\nmkdir -p \u002Fopt\u002Fneo4j\u002Fbackups && cd \u002Fopt\u002Fneo4j\necho \"NEO4J_PASSWORD=$(openssl rand -hex 16)\" > .env\nchmod 600 .env\nchown 7474:7474 backups\n```",{"title":93,"body":94},"Write the docker-compose.yml file","Both ports are published on the loopback only: 7474 for Neo4j Browser and the HTTP API, 7687 for Bolt. `NEO4J_AUTH` creates the `neo4j` user with your password on first start, and the advertised Bolt address is the one nginx will publish over HTTPS.\n```yaml\nservices:\n  neo4j:\n    image: neo4j:2026.10.2-community\n    restart: unless-stopped\n    ports:\n      - \"127.0.0.1:7474:7474\"\n      - \"127.0.0.1:7687:7687\"\n    environment:\n      NEO4J_AUTH: neo4j\u002F${NEO4J_PASSWORD}\n      NEO4J_server_bolt_advertised__address: neo4j.example.com:443\n      NEO4J_server_memory_heap_initial__size: 512m\n      NEO4J_server_memory_heap_max__size: 512m\n      NEO4J_server_memory_pagecache_size: 512m\n    volumes:\n      - neo4j-data:\u002Fdata\n      - neo4j-logs:\u002Flogs\nvolumes:\n  neo4j-data: {}\n  neo4j-logs: {}\n```",{"title":96,"body":97},"Start Neo4j","The first start takes about thirty seconds; the root then answers with a small JSON document giving the version and the connection addresses.\n```bash\ndocker compose up -d\ndocker compose ps\ncurl -s http:\u002F\u002F127.0.0.1:7474\u002F\n```",{"type":99,"title":100,"body":101},"tip","Never publish 7474 or 7687 to the Internet","Keep both ports on `127.0.0.1`: a database reachable directly from the Internet is scanned within hours. nginx carries HTTPS on 443, and the browser's Bolt connection goes through the same name over WebSocket. Keep `NEO4J_AUTH` too: without it, the `neo4j` user starts with the factory password `neo4j`, which everybody knows.",{"type":38,"title":103,"body":104},"Put Neo4j behind nginx over HTTPS","Neo4j Browser needs two things: the HTTP interface and a Bolt connection, which the browser opens over WebSocket. nginx routes both on the same name: ordinary requests to 7474, WebSocket requests to 7687.\n\n```nginx\nmap $http_upgrade $neo4j_backend {\n    default   127.0.0.1:7474;\n    websocket 127.0.0.1:7687;\n}\nserver {\n    listen 80;\n    server_name neo4j.example.com;\n    location \u002F {\n        proxy_pass http:\u002F\u002F$neo4j_backend;\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection $http_connection;\n        proxy_set_header Host $host;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_read_timeout 3600s;\n    }\n}\n```\n\n```bash\ncertbot --nginx -d neo4j.example.com\n```\n\nThen open `https:\u002F\u002Fneo4j.example.com`. In Neo4j Browser, enter `neo4j+s:\u002F\u002Fneo4j.example.com:443` as the Connect URL, the user `neo4j` and your password.",{"type":38,"title":106,"body":107},"First Cypher queries","In Neo4j Browser, create a uniqueness constraint, a few nodes and their relationships, then follow a path of at most two levels. `MERGE` only creates a node or relationship if it does not exist yet: the query can be replayed without duplicates.\n\n```cypher\nCREATE CONSTRAINT person_name IF NOT EXISTS FOR (p:Person) REQUIRE p.name IS UNIQUE;\nMERGE (sara:Person {name: 'Sara'})\nMERGE (yassine:Person {name: 'Yassine'})\nMERGE (casa:City {name: 'Casablanca'})\nMERGE (sara)-[:KNOWS]->(yassine)\nMERGE (yassine)-[:LIVES_IN]->(casa);\nMATCH (p:Person {name: 'Sara'})-[:KNOWS*1..2]->(f)-[:LIVES_IN]->(c:City)\nRETURN f.name, c.name;\n```\n\nThe Browser draws the result; the `:guide` command opens its built-in tutorials, and `:sysinfo` shows the database size and cache usage.",{"type":38,"title":109,"body":110},"Connect an application","From any language, the **HTTP API** takes a Cypher query by `POST` and answers in JSON, with HTTP basic authentication. An application installed on the same VPS rather uses an **official driver** over Bolt, at `bolt:\u002F\u002F127.0.0.1:7687`. From your development machine, an SSH tunnel makes the same port reachable without opening it to the Internet.\n\n```bash\ncurl -s -u neo4j:$NEO4J_PASSWORD \\\n  -H 'Content-Type: application\u002Fjson' \\\n  -d '{\"statement\": \"MATCH (p:Person) RETURN p.name LIMIT 5\"}' \\\n  https:\u002F\u002Fneo4j.example.com\u002Fdb\u002Fneo4j\u002Fquery\u002Fv2\n```\n\n```python\nfrom neo4j import GraphDatabase\n\ndriver = GraphDatabase.driver(\"bolt:\u002F\u002F127.0.0.1:7687\", auth=(\"neo4j\", \"\u003Cmot-de-passe>\"))\nrecords, _, _ = driver.execute_query(\"MATCH (p:Person) RETURN p.name AS name\")\nprint([r[\"name\"] for r in records])\n```\n\n```bash\nssh -L 7687:127.0.0.1:7687 root@203.0.113.10\n```\n\nUse the `bolt:\u002F\u002F` scheme rather than `neo4j:\u002F\u002F` for a local connection: the latter requests the routing table, which advertises the public address on port 443.",{"type":38,"title":112,"body":113},"GraphRAG: give an AI assistant connected facts","A classic RAG retrieves passages close to the question. **GraphRAG** adds the relationships: entities extracted from documents (people, contracts, products) become nodes, linked to each other and to the passages that mention them. Neo4j holds both in the same database, thanks to its vector indexes.\n\n```cypher\nCREATE VECTOR INDEX chunk_embedding IF NOT EXISTS\nFOR (c:Chunk) ON c.embedding\nOPTIONS {indexConfig: {`vector.dimensions`: 768, `vector.similarity_function`: 'cosine'}};\n```\n\nVector search finds the relevant passages, then a Cypher query follows their relationships to gather context: the assistant answers with connected facts and the source of each one. Embeddings can come from a local model served by Ollama on the same VPS.",{"type":38,"title":115,"body":116},"Back up and update","In Community Edition, backups are taken with the database stopped, using `neo4j-admin database dump`: a few seconds of downtime for a medium-sized graph. Schedule it at night.\n\n```bash\ncd \u002Fopt\u002Fneo4j\ndocker compose stop neo4j\ndocker compose run --rm -v \u002Fopt\u002Fneo4j\u002Fbackups:\u002Fbackups neo4j \\\n  neo4j-admin database dump neo4j --to-path=\u002Fbackups --overwrite-destination=true\ndocker compose start neo4j\n```\n\nThen copy `backups\u002Fneo4j.dump` off the VPS. To update, change the image version in `docker-compose.yml`, then `docker compose pull && docker compose up -d`, right after a backup; read the release notes before moving to a new major version.",{"type":38,"title":118,"body":119},"One-click install on ServOrbit","From the Marketplace in your client area, Neo4j installs on a ServOrbit VPS without writing a line: Neo4j Community Edition is deployed behind a small proxy that serves Neo4j Browser, the HTTP API and the Bolt connection on a single port, the password of the `neo4j` user is generated and shown in your client area, and everything is published over HTTPS on your domain or on the VPS's free subdomain. The Bolt port stays available locally, at `bolt:\u002F\u002F127.0.0.1:7687`, for your applications.","Your graph database on a VPS","An Ubuntu 24.04 ServOrbit VPS with 2 GB of RAM is enough to start Neo4j. One-click install from the Marketplace, HTTPS on your domain or on the VPS's free subdomain, password generated for you.","Install Neo4j","\u002Fapplications\u002Fdatabases\u002Fneo4j",[125,149,168],{"id":126,"slug":127,"slugs":128,"title":132,"excerpt":133,"readTime":134,"views":135,"isPinned":19,"noindex":19,"publishedAt":136,"updatedAt":137,"category":138,"categories":144,"featuredImage":29,"bgImage":30,"posterImage":146,"relatedSolution":147},65,"hosting-qdrant-on-a-vps",{"fr":129,"en":127,"ar":130,"es":131},"heberger-qdrant-vps","استضافة-qdrant-على-خادم-vps","alojar-qdrant-en-un-vps","Hosting Qdrant on a VPS","Host Qdrant on your VPS: Docker Compose, API key, TLS, HNSW tuning, quantization, Python v1 client, snapshots and Prometheus monitoring.",8,1,"2026-04-16T00:00:00+00:00","2026-10-20T23:18:05+00:00",{"id":139,"name":140,"slug":141,"color":142,"icon":143},6,"Databases","bases-de-donnees","bg-teal-500\u002F10 text-teal-400","database",[145],{"id":139,"name":140,"slug":141,"color":142,"icon":143},"\u002Fblog\u002Fcovers\u002Fheberger-qdrant-vps-poster.svg",{"categorySlug":33,"appSlug":148},"qdrant",{"id":150,"slug":151,"slugs":152,"title":156,"excerpt":157,"readTime":158,"views":18,"isPinned":19,"noindex":19,"publishedAt":159,"updatedAt":160,"category":161,"categories":162,"featuredImage":29,"bgImage":30,"posterImage":164,"relatedSolution":165},66,"hosting-weaviate-on-a-vps",{"fr":153,"en":151,"ar":154,"es":155},"heberger-weaviate-vps","استضافة-weaviate-على-خادم-vps","alojar-weaviate-en-un-vps","Hosting Weaviate on a VPS","Weaviate on a VPS: annotated Docker Compose, API key auth, vectorizer choice, HNSW and quantization, backups, Python client v4 and troubleshooting.",12,"2026-04-15T00:00:00+00:00","2026-11-04T16:30:25+00:00",{"id":139,"name":140,"slug":141,"color":142,"icon":143},[163],{"id":139,"name":140,"slug":141,"color":142,"icon":143},"\u002Fblog\u002Fcovers\u002Fheberger-weaviate-vps-poster.svg",{"categorySlug":166,"appSlug":167},"artificial-intelligence","weaviate",{"id":169,"slug":170,"slugs":171,"title":175,"excerpt":176,"readTime":177,"views":135,"isPinned":19,"noindex":19,"publishedAt":178,"updatedAt":179,"category":180,"categories":181,"featuredImage":29,"bgImage":30,"posterImage":183,"relatedSolution":184},56,"postgresql-on-a-vps-a-reliable-and-controlled-database",{"fr":172,"en":170,"ar":173,"es":174},"heberger-postgresql-vps","postgresql-على-خادم-vps-قاعدة-بيانات-موثوقة-ومتحكم-بها","alojar-postgresql-en-un-vps","PostgreSQL on a VPS: reliable, controlled database","Host PostgreSQL on a VPS: production config, pgBackRest backups, streaming HA, RDS\u002FSupabase\u002FNeon comparison and OOM troubleshooting.",9,"2026-04-25T00:00:00+00:00","2026-10-21T15:21:37+00:00",{"id":139,"name":140,"slug":141,"color":142,"icon":143},[182],{"id":139,"name":140,"slug":141,"color":142,"icon":143},"\u002Fblog\u002Fcovers\u002Fheberger-postgresql-vps-poster.svg",{"categorySlug":33,"appSlug":185},"postgresql-stack",true,1794322174629]