Examples Catalog¶
The repository ships a catalog of ready-to-apply YAML manifests under
examples/
— one file per scenario, covering every CRD the operator manages. Use them as
copy-paste starting points: pick the closest match, copy it, and adjust image
tag, storage, and resources for your environment.
Apply an example straight from GitHub without cloning the repo:
# Pin to a release tag for production; use main for the latest examples
kubectl apply -f https://raw.githubusercontent.com/priyolahiri/neo4j-kubernetes-operator/main/examples/clusters/minimal-cluster.yaml
Or from a local clone:
Create Secrets out-of-band first
The examples intentionally do not define credential Secrets inline — re-applying a manifest would overwrite a real password with the placeholder. Most examples expect an admin Secret to exist before you apply them:
kubectl create secret generic neo4j-admin-secret \
--from-literal=username=neo4j \
--from-literal=password='<your-secure-password>'
Each file's header comments list any additional Secrets it needs
(cloud credentials, LDAP bind accounts, Aura tokens, …) with the exact
kubectl create secret command.
Neo4j version
Most examples use 5.26-enterprise (the LTS line, which tracks the latest
5.26 patch), but every one works on a CalVer release too — just change the
image tag (e.g. 2026.08.1-enterprise); the operator auto-detects CalVer.
Property sharding examples require Neo4j 2025.12+ and use the CalVer release
CI validates (2026.08.1-enterprise).
All GitHub links below point at the main branch.
Standalone¶
Single-node Neo4jEnterpriseStandalone deployments for development, testing, and simple production workloads.
| Example | What it shows | Notable fields |
|---|---|---|
single-node-standalone.yaml |
Minimal single-node deployment; also works as a Neo4jDatabase target via clusterRef |
storage.size, resources, default-StorageClass inheritance |
tls-standalone.yaml |
Standalone with cert-manager TLS and native auth | tls.mode: cert-manager, tls.issuerRef, heap/pagecache config |
ldap-standalone.yaml |
LDAP + native authentication on a standalone instance | auth.ldap, authorization.systemAccountSecretRef |
standalone-with-trusted-ca.yaml |
Trusting an internal CA (e.g. a corporate OIDC IdP cert) via the operator's JKS truststore; bundles the cert-manager Certificate |
trustedCASecrets, CalVer image tag |
Clusters¶
Neo4jEnterpriseCluster topologies from a 2-server minimum to production-tuned multi-zone deployments.
| Example | What it shows | Notable fields |
|---|---|---|
minimal-cluster.yaml |
Smallest possible cluster — 2 servers that self-organize | topology.servers: 2, optional serverModeConstraint |
three-node-simple.yaml |
3 servers with TLS disabled — simplest HA setup for local testing without cert-manager | topology.servers: 3, tls.mode: disabled |
three-node-cluster.yaml |
3-server HA cluster with cert-manager TLS and production sizing | tls.mode: cert-manager, resources (4Gi/1 CPU requests) |
tls-cluster.yaml |
Minimal 2-server cluster with cert-manager TLS | tls.issuerRef, auth.authenticationProviders |
multi-server-cluster.yaml |
5-server production cluster with TLS and automatic role organization (CR name: multi-primary-cluster) |
topology.servers: 5, production resources |
production-optimized-cluster.yaml |
Production tuning — transaction memory limits, JVM settings, data retention; bundles a Neo4jDatabase |
storage.retentionPolicy: Retain, tuned config |
cluster-with-read-replicas.yaml |
5 servers sized for read-heavy workloads so databases can run secondary (read) replicas | topology.servers: 5 |
topology-placement-cluster.yaml |
Multi-zone placement with spread constraints and hard anti-affinity | topology.placement.topologySpread, placement.antiAffinity, availabilityZones |
auth-example.yaml |
One cluster with native auth, plus commented LDAP and OIDC/SSO auth: variants to swap in |
auth.adminSecret, commented auth.ldap / auth.oidc blocks |
cluster-with-trusted-cas.yaml |
Trusting internal CAs declaratively (cert-manager Certificate → Secret → JVM truststore) |
trustedCASecrets |
storage-expansion.yaml |
Online PVC expansion walkthrough — patch storage.size on a running cluster |
storage.size, requires allowVolumeExpansion: true StorageClass |
External Access¶
Exposing a cluster outside Kubernetes via the four supported Service exposure modes. These paths need real cluster networking — validate them in your own environment.
| Example | What it shows | Notable fields |
|---|---|---|
loadbalancer-cluster.yaml |
LoadBalancer Service for cloud environments (AWS, GCP, Azure) | service.type: LoadBalancer |
nodeport-cluster.yaml |
NodePort exposure for on-premises or development environments | service.type: NodePort |
ingress-cluster.yaml |
Neo4j Browser behind an Ingress controller (e.g. nginx) with cert-manager TLS | service.ingress |
route-cluster.yaml |
OpenShift Route with edge TLS termination over a ClusterIP Service | service.route.enabled, route.tls.termination, securityContext |
Databases & Sharding¶
Neo4jDatabase creation, topology, and seed-from-backup, plus Neo4jShardedDatabase property sharding (Neo4j 2025.12+).
| Example | What it shows | Notable fields |
|---|---|---|
database-2025x.yaml |
CalVer-only default Cypher language on a database | defaultCypherLanguage: "25" |
database-standalone.yaml |
Two databases created on a Neo4jEnterpriseStandalone via the same clusterRef field |
clusterRef, ifNotExists, wait |
database-with-topology.yaml |
Custom database topology distributed across cluster servers | topology.primaries: 2, topology.secondaries: 1 |
database-from-s3-seed.yaml |
Seeding a database from an S3 backup with explicit credentials | seedURI: s3://…, seedCredentials.secretRef |
database-from-gcs-seed.yaml |
Seeding from Google Cloud Storage using workload identity, with point-in-time restoreUntil |
seedURI: gs://…, seedConfig.restoreUntil: "txId:…" |
database-from-azure-seed.yaml |
Seeding from Azure Blob Storage — storage-key and SAS-token auth variants | seedURI: azb://…, seedCredentials.secretRef |
database-from-http-seed.yaml |
Seeding over HTTPS (authenticated), HTTP, and FTP — three variants | seedURI: https://…, seedCredentials |
database-dump-vs-backup-seed.yaml |
Side-by-side comparison of seeding from .dump vs .backup files |
seedURI, seedConfig.config (compression, validation, buffer size) |
basic-property-sharding.yaml |
Minimal working property-sharding setup — cluster + Neo4jShardedDatabase |
propertySharding.enabled, 4Gi+ memory per server |
development-property-sharding.yaml |
Property sharding at minimum viable resources for dev/learning | propertySharding, dedicated namespace |
advanced-property-sharding.yaml |
Production-grade sharding — high-performance sizing, TLS, monitoring | propertySharding, tls, monitoring |
property-sharding-with-backup.yaml |
Backing up a sharded database with a Neo4jBackup CR |
Neo4jShardedDatabase + Neo4jBackup target |
all-databases-backup-sharded-dr.yaml |
One all-databases backup as the DR source for a cluster mixing standard and sharded databases; sharded families restore via their own CR | allDatabases: true, Neo4jShardedDatabase.spec.seedBackupRef, seedSourceDatabase |
Backup & Restore¶
Job-per-CR Neo4jBackup (one-shot and scheduled) and Neo4jRestore scenarios. See the Backup & Restore guide for the concepts.
| Example | What it shows | Notable fields |
|---|---|---|
backup-pvc-simple.yaml |
One-shot backup of every database on an instance to a PVC | instanceRef + allDatabases: true, storage.type: pvc |
backup-s3-basic.yaml |
S3 backup — explicit-credentials and IRSA/workload-identity variants | storage.cloud.credentialsSecretRef, cloud.identity.autoCreate |
backup-scheduled-daily.yaml |
Scheduled daily backup to S3 (plus a weekly variant) | schedule: "0 2 * * *" (flat cron string), retention |
backup-incremental.yaml |
Incremental (AUTO) backups of one database every 6 hours | instanceRef + database, options.backupType: AUTO |
backup-with-type.yaml |
Explicit FULL backups with compression, page-cache sizing, and retention | options.backupType: FULL, options.pageCache, retention.maxAge/maxCount |
backup-minio.yaml |
Backups to MinIO / any S3-compatible store — full, scheduled, and external-TLS-endpoint variants | cloud.endpointURL, cloud.forcePathStyle: true |
restore-from-backup.yaml |
Restore from a Neo4jBackup reference, with pre/post Cypher hooks and a post-restore validation Job variant (online on clusters and standalones) |
source.backupRef, options.preRestore/postRestore |
restore-overwrite.yaml |
Destructive restore over an existing database on a cluster (Cypher/seedURI path — no Job) | options.replaceExisting: true |
restore-point-in-time-online.yaml |
Online point-in-time restore into a new database, on a cluster or a standalone (CalVer, cloud storage) | source.type: backup, source.pointInTime |
restore-pitr-basic.yaml |
Point-in-time recovery on a standalone target, plus an advanced storage-based variant with hooks | source.type: pitr, pointInTime, pitr.baseBackup |
pitr-setup-complete.yaml |
End-to-end PITR environment — base backup with validation, log-retention notes, and the restore | options.validate, options.includeMetadata, source.type: pitr |
source.type: pitr is standalone-only
source.type: pitr runs neo4j-admin database restore --restore-until as a
Job that stops the instance, and applies only to Neo4jEnterpriseStandalone
targets. A cluster restores to a point in time online with
source.type: backup + source.pointInTime, into a new database, on
CalVer, from cloud storage — see restore-point-in-time-online.yaml.
Cross-Cluster Replication & Aliases¶
Read-only replicas of a database on another Neo4j cluster, fed by a differential backup chain in object storage — plus the aliases that keep connection strings stable across a failover. See the Cross-Cluster Replication guide and the Database aliases guide.
Composite databases give one query endpoint over several constituent databases (USE cineasts.latest). Runnable manifests are in examples/composite-databases/ — a local composite, granting access through one, and remote constituents in both authentication modes. See the Composite databases guide.
Apply these across two Kubernetes clusters, in order: 01 upstream, 02–04 downstream.
| Example | What it shows | Notable fields |
|---|---|---|
01-upstream-backup-chain.yaml |
Upstream backup chain that feeds a replica; publishes the pull URI for the downstream CR | mode: replication-source, status.replicationPullURI |
02-downstream-replica.yaml |
The read-only replica, seeded from and following that chain | source.mode: backup, source.pullURI/seedURI, pullInterval |
03-failover-alias.yaml |
Stable client name pre-staged before any failover — aliases can target a database that is still a replica | targetDatabase |
04-promotion.yaml |
The one-way failover action, recording the RPO it took | replicaRef, topology, status.observedLagTxIds |
Two things no validation can catch
Bucket lifecycle rules. For cloud storage the operator never prunes — retention is delegated to lifecycle rules it cannot read. One that expires objects under the chain path silently breaks replication and forces a full replica rebuild. Exclude that path from expiry.
Promotion is irreversible. A promoted database cannot be re-attached to its upstream, and whatever lag is outstanding becomes permanent data loss.
Users, Roles & Auth¶
Declarative user, role, and access management via Neo4jUser, Neo4jRole, Neo4jRoleBinding, and Neo4jAuthRule. Numbered for a natural reading order; see User & Role Management.
| Example | What it shows | Notable fields |
|---|---|---|
01-readonly-user.yaml |
Read-only application user bound to the built-in reader role |
passwordSecretRef, roles: [reader] |
02-custom-role-with-user.yaml |
The canonical pattern — privileges on a Neo4jRole, user references it by name |
Neo4jRole.spec.privileges (GRANT/DENY ending in TO <role>) |
03-suspended-user.yaml |
Suspending a user during a security incident without deleting the CR | accountStatus: suspended |
04-external-auth.yaml |
User authenticated only via OIDC and LDAP providers — no native password | externalAuth[].provider/id, no passwordSecretRef |
05-adopt-builtin.yaml |
Adopting the built-in editor role to tighten its privileges (never dropped on CR delete) |
adoptBuiltin: true |
06-rolebinding-sso-user.yaml |
Granting roles to an externally-provisioned (SSO/LDAP) user the operator does not manage | Neo4jRoleBinding.spec.roles, optional enforceExclusive |
07-authrule-abac.yaml |
Attribute-based access control — mapping OIDC token claims to roles at login (Neo4j 2026.03+) | Neo4jAuthRule condition expressions over token claims |
Plugins¶
Neo4jPlugin examples — clusterRef can point at either a cluster or a standalone.
| Example | What it shows | Notable fields |
|---|---|---|
apoc-plugin-example.yaml |
APOC with env-var-based configuration (the 5.26+ way — APOC config does not live in neo4j.conf) |
config.apoc.* → NEO4J_APOC_* env vars |
gds-plugin-example.yaml |
Graph Data Science with automatic procedure allowlisting | source.type: community, gds.enterprise.license_file |
bloom-plugin-example.yaml |
Bloom with its required neo4j.conf settings |
dbms.bloom.license_file, role restriction |
genai-plugin-example.yaml |
GenAI plugin for vector embeddings and AI integrations (download needs internet egress) | name: genai, source.type: official |
standalone-plugin-example.yaml |
GDS on a standalone deployment, with a plugin dependency declaration | dependencies[].versionConstraint |
cluster-plugin-example.yaml |
Deprecated legacy APOC config approach, kept for reference — use apoc-plugin-example.yaml instead |
— |
Security¶
Workload-namespace NetworkPolicies and Kyverno conformance policies (the operator validates inline; these are defence-in-depth at admission time).
| Example | What it shows | Notable fields |
|---|---|---|
networkpolicy-cluster.yaml |
Hand-applied NetworkPolicy for a cluster namespace — Bolt/HTTP for clients, discovery/RAFT pod-to-pod, metrics for the operator, default-deny egress | Ports 7687/7474/7473, 6000/7000, 2004 |
networkpolicy-standalone.yaml |
Same shape for the single-pod standalone case (no intra-cluster ports) | podSelector on app: <standalone-name> |
policies/01-enterprise-image.yaml |
Kyverno audit: image tag must be an Enterprise image | validationFailureAction: Audit |
policies/02-tls-required.yaml |
Kyverno audit: flags CRs with TLS disabled | spec.tls.mode check |
policies/03-monitoring-enabled.yaml |
Kyverno audit: recommends spec.monitoring so diagnostics and health conditions populate |
spec.monitoring check |
policies/04-runAsNonRoot-not-disabled.yaml |
Kyverno audit: catches securityContext overrides that disable runAsNonRoot |
spec.securityContext check |
policies/05-resource-limits.yaml |
Kyverno audit: requires memory and CPU limits (Enterprise needs ≥ 1.5Gi) | spec.resources.limits check |
Fleet Management¶
Registering self-managed deployments with Aura Fleet Management so they appear in the Aura console. Requires a token from your Aura tenant.
| Example | What it shows | Notable fields |
|---|---|---|
cluster-with-fleet-management.yaml |
3-server cluster registered with Aura Fleet Management | auraFleetManagement.enabled, tokenSecretRef.name/key |
standalone-with-fleet-management.yaml |
Single-node deployment registered with Aura Fleet Management | auraFleetManagement.enabled, tokenSecretRef.name |
cluster-with-fleet-provisioning.yaml |
Operator-managed onboarding — the operator registers the deployment and mints the token itself from Aura API credentials | auraFleetManagement.provision (mutually exclusive with tokenSecretRef) |
End-to-End¶
Multi-resource scenarios that compose the CRDs above into complete environments.
| Example | What it shows | Notable fields |
|---|---|---|
complete-deployment.yaml |
Full production stack — namespace, TLS cluster, two databases, two backups, a plugin, and Prometheus ServiceMonitor wiring |
Cluster + Neo4jDatabase + Neo4jBackup + Neo4jPlugin + monitoring |
development-workflow.yaml |
Lightweight dev setup — standalone instance plus a dev database and a separate integration-test database, with cypher-shell workflow notes | Standalone + two Neo4jDatabase CRs |
disaster-recovery.yaml |
DR proactive phase — scheduled compressed off-site S3 backup, with recovery-phase restore snippets in comments | Neo4jBackup every 4 hours, commented Neo4jRestore recipes |
multi-tenancy.yaml |
Logical multi-tenancy — one shared cluster, a database per tenant, per-tenant backup cadence; honest about what it does not isolate | Cluster + four Neo4jDatabase + three Neo4jBackup CRs |
See also¶
- Examples README — prerequisites, customization, and topology guidance
- Getting Started — first deployment walkthrough
- Configuration Guide — every spec field explained