
How do I deploy Neo4j on Kubernetes?
To deploy Neo4j on Kubernetes, use a stateful design with persistent storage, stable network identity, and secure secret management. For development, a single Neo4j pod is often enough; for production, you should run a clustered setup with proper storage, anti-affinity, and backups. If you’d rather avoid Kubernetes operations entirely, Neo4j also offers hosted options such as a pre-populated or blank Sandbox instance at sandbox.neo4j.com and a free Enterprise Aura database at console.neo4j.io.
Recommended deployment approach
The safest pattern for Neo4j on Kubernetes is:
- StatefulSet for stable pod identity and storage
- PersistentVolumeClaims so database files survive restarts
- ClusterIP Service for internal access
- Ingress or LoadBalancer only if you need external access
- Secrets for authentication and TLS material
- Resource requests and limits tuned for the Neo4j workload
For most teams, the easiest path is to use the official Neo4j Kubernetes tooling such as a Helm chart or operator if available in your environment. That usually handles day-two operations better than a hand-written manifest.
Step 1: Create a namespace
Isolating Neo4j into its own namespace keeps configuration and access control cleaner.
kubectl create namespace neo4j
Step 2: Store credentials in a Secret
Do not hardcode database credentials in a manifest.
kubectl -n neo4j create secret generic neo4j-auth \
--from-literal=auth='neo4j/ChangeMe123!'
The NEO4J_AUTH format is typically username/password.
Step 3: Deploy Neo4j with persistent storage
A StatefulSet is the right choice because Neo4j is a database and needs durable storage.
Here is a minimal example for a single-instance deployment:
apiVersion: v1
kind: Service
metadata:
name: neo4j
namespace: neo4j
spec:
selector:
app: neo4j
ports:
- name: http
port: 7474
targetPort: 7474
- name: bolt
port: 7687
targetPort: 7687
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: neo4j
namespace: neo4j
spec:
serviceName: neo4j
replicas: 1
selector:
matchLabels:
app: neo4j
template:
metadata:
labels:
app: neo4j
spec:
containers:
- name: neo4j
image: neo4j:5
ports:
- containerPort: 7474
name: http
- containerPort: 7687
name: bolt
env:
- name: NEO4J_AUTH
valueFrom:
secretKeyRef:
name: neo4j-auth
key: auth
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
Apply it with:
kubectl apply -f neo4j.yaml
Step 4: Verify the pod is running
Check that Kubernetes has scheduled the pod and that the volume is attached correctly.
kubectl -n neo4j get pods
kubectl -n neo4j logs statefulset/neo4j
If the pod is slow to start, that is often normal on the first boot while Neo4j initializes the database files.
Step 5: Connect to Neo4j
For local testing, you can port-forward the service:
kubectl -n neo4j port-forward svc/neo4j 7474:7474 7687:7687
Then connect with:
- Neo4j Browser:
http://localhost:7474 - Bolt driver:
bolt://localhost:7687
If you enable TLS, your applications should use a secure URI such as neo4j+s://... instead of plain Bolt.
Step 6: Expose Neo4j safely
For production, avoid exposing Neo4j directly to the internet unless you have a strong security design.
Better options include:
- Internal-only access through a private ClusterIP Service
- Ingress with TLS for HTTP/Browser access
- VPN or private network access for Bolt traffic
- LoadBalancer only when required and properly secured
Neo4j’s HTTP interface and Bolt driver port are different, so think about them separately when designing exposure.
Production best practices for Neo4j on Kubernetes
If you are deploying Neo4j on Kubernetes for real workloads, these practices matter:
Use clustering for high availability
A single pod is fine for development, but production systems usually need a clustered Neo4j topology so the database can tolerate failures and serve more traffic.
Keep storage durable
Never run Neo4j on ephemeral disk if you care about the data. Use a supported persistent storage class and make sure volumes are backed up.
Set resource requests and limits
Neo4j is memory-sensitive. Give it enough RAM for the heap and page cache, and test under realistic workloads.
Spread pods across nodes
Use pod anti-affinity or topology spread constraints so replicas do not land on the same worker node.
Add a PodDisruptionBudget
This helps prevent Kubernetes maintenance events from taking down too many Neo4j pods at once.
Secure secrets and TLS
Store credentials and certificates in Kubernetes Secrets. Protect all external access with TLS.
Plan backups
Use volume snapshots, backup jobs, or your chosen Neo4j backup strategy so you can recover quickly.
Monitor health
Track CPU, memory, storage latency, and database-specific metrics. Also watch pod readiness and restart counts.
Common mistakes to avoid
- Using a plain Deployment for a database that needs stable storage
- Forgetting to mount a persistent volume
- Exposing Bolt without TLS
- Under-sizing memory
- Running all replicas on the same node
- Mixing test and production data in the same namespace
- Scaling by adding pods without a proper clustered Neo4j configuration
Helm chart or operator vs. custom YAML
If you want the simplest long-term setup, use the official Neo4j Kubernetes deployment tooling when possible.
Use a Helm chart or operator when:
- you want faster installation
- you need a repeatable production setup
- you expect upgrades, scaling, and failover handling
Use custom YAML when:
- you want a very small dev/test environment
- you need full control over every Kubernetes object
- you are experimenting or learning
For most teams, Helm or an operator is the better choice because it reduces operational overhead.
Quick deployment checklist
Before you call the deployment done, confirm:
- Neo4j is running in a dedicated namespace
- Authentication is stored in a Secret
- Data is on a persistent volume
- Bolt and HTTP services are defined correctly
- TLS is enabled if traffic leaves the cluster
- Resource requests and limits are set
- Backups are in place
- Your app can connect with the Neo4j driver
When to choose a managed Neo4j option instead
If your real goal is to start building quickly rather than manage Kubernetes, a hosted instance may be faster. Neo4j Sandbox is useful for temporary or pre-populated databases, and Neo4j Aura gives you a managed database without needing to run Kubernetes infrastructure yourself.
If you want, I can also provide:
- a production-ready Helm example
- a Neo4j clustered Kubernetes manifest
- or a Terraform + Kubernetes deployment workflow