neo4j
docker-compose
kubernetes
containerization
deployment

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 StatefulSet or Deployment for the container
  • a Service for stable networking
  • a PersistentVolumeClaim for data
  • a Secret for 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.

yaml
1apiVersion: v1
2kind: Secret
3metadata:
4  name: neo4j-auth
5type: Opaque
6stringData:
7  NEO4J_AUTH: neo4j/password123
8---
9apiVersion: apps/v1
10kind: StatefulSet
11metadata:
12  name: neo4j
13spec:
14  serviceName: neo4j
15  replicas: 1
16  selector:
17    matchLabels:
18      app: neo4j
19  template:
20    metadata:
21      labels:
22        app: neo4j
23    spec:
24      containers:
25        - name: neo4j
26          image: neo4j:5
27          ports:
28            - containerPort: 7474
29            - containerPort: 7687
30          envFrom:
31            - secretRef:
32                name: neo4j-auth
33          volumeMounts:
34            - name: data
35              mountPath: /data
36  volumeClaimTemplates:
37    - metadata:
38        name: data
39      spec:
40        accessModes: ["ReadWriteOnce"]
41        resources:
42          requests:
43            storage: 10Gi
44---
45apiVersion: v1
46kind: Service
47metadata:
48  name: neo4j
49spec:
50  selector:
51    app: neo4j
52  ports:
53    - name: http
54      port: 7474
55      targetPort: 7474
56    - name: bolt
57      port: 7687
58      targetPort: 7687

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 Deployment with ephemeral storage for a stateful database.
  • Hard-coding NEO4J_AUTH in plain YAML rather than using a Secret.
  • 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, and Service resources for a solid baseline.
  • Store credentials in Secret objects rather than inline manifests.
  • Plan networking and external exposure deliberately.
  • For production-grade setups, prefer the supported chart or operator over handwritten manifests alone.

Course illustration
Course illustration

All Rights Reserved.