Neo4j docker-compose to kubernetes
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Moving Neo4j from docker-compose to Kubernetes is not a line-for-line file conversion. Compose is convenient for local development, but Kubernetes needs you to model state, storage, networking, and secrets explicitly, which is especially important for a stateful database such as Neo4j.
Start by translating concepts, not YAML syntax
A typical Compose setup for Neo4j defines an image, published ports, environment variables, and a mounted data volume. In Kubernetes, those concerns are split across several resources.
- a
StatefulSetorDeploymentfor the container - a
Servicefor stable networking - a
PersistentVolumeClaimfor data - a
Secretfor credentials
For Neo4j, StatefulSet is usually the better choice because the database benefits from stable identity and persistent storage.
A minimal single-node Kubernetes setup
This example shows the basic shape of a single-node Neo4j deployment. It is a starting point for development or small internal environments, not a full production topology.
This maps the same major ideas as Compose, but in Kubernetes-native terms.
Handle persistence first
The biggest architectural difference is storage. In Compose, mounting a local directory is easy. In Kubernetes, the pod may move between nodes, so data must live on a persistent volume. If you skip that step, a pod restart can look like data loss because the new container starts with an empty filesystem.
For production, storage class choice matters. Latency, IOPS, and backup support affect database behavior much more than the YAML itself.
Treat credentials as secrets, not environment text
Many Compose examples hard-code NEO4J_AUTH directly in the file. In Kubernetes, move that into a Secret. Even though the container still receives an environment variable, the configuration is now separated from the workload manifest and can be managed more safely.
That same pattern applies to TLS settings, plugin credentials, and cloud backup keys.
Expose Neo4j carefully
Neo4j usually needs two ports: HTTP on 7474 for the browser and Bolt on 7687 for drivers. Inside the cluster, a Service is enough. For external access, you may add an ingress, a load balancer, or port forwarding during development.
Do not expose the database publicly by default just because Compose published ports on localhost. Kubernetes makes exposure easier to scale, which also makes accidental exposure easier to cause.
Do not stop at a mechanical migration
A Kubernetes migration is a chance to add readiness probes, resource requests, backups, and monitoring. Those are the pieces that make the deployment operational rather than merely runnable.
For larger Neo4j topologies, use the vendor-supported Helm chart or operator instead of hand-maintaining every manifest. That is usually a better path than manually recreating cluster behavior from a local Compose file.
Common Pitfalls
- Converting the Compose file literally instead of mapping it to Kubernetes concepts.
- Using a
Deploymentwith ephemeral storage for a stateful database. - Hard-coding
NEO4J_AUTHin plain YAML rather than using aSecret. - Exposing ports externally before deciding who should actually reach the database.
- Treating a working pod as a complete migration without backups, probes, and monitoring.
Summary
- Neo4j migration from Compose to Kubernetes is a design translation, not a text conversion.
- Use
StatefulSet, persistent storage, andServiceresources for a solid baseline. - Store credentials in
Secretobjects rather than inline manifests. - Plan networking and external exposure deliberately.
- For production-grade setups, prefer the supported chart or operator over handwritten manifests alone.

