Deploying Apache Fineract on Kubernetes

A planning and build guide for running Apache Fineract on Kubernetes: instance types, migration jobs, health checks, tenant secrets, and upgrades on a cluster you control.

On this page

Deploying Apache Fineract on Kubernetes: when a cluster fits your core banking platform

A Kubernetes cluster fits Apache Fineract when your team can operate the cluster itself and wants Fineract's read, write and batch roles scheduled, scaled and rolled out as separate workloads. Fineract is an Apache 2.0 licensed core banking system delivered as a headless application: it exposes REST APIs and no user interface of its own, so the cluster hosts the back end while a separate front end, such as the Mifos X web application that the project's Kubernetes example uses, sits on top. The project recommends PostgreSQL as the database, and every API call identifies its tenant with the Fineract-Platform-TenantId header, with tenant connections read from a tenants database. Those choices matter before any manifest is written, because each tenant's data and credentials become part of the cluster's configuration. The instance model is the main reason Kubernetes is a natural host. Fineract's documentation describes read, write and batch instances selected by environment variables, with one write instance, one batch instance and several read instances on database read replicas for high load. Each role has different scaling, restart and resource needs, and Liquibase migrations run only on write instances, so Kubernetes deployments, probes and jobs can be separated to match. Confirm with your own load tests whether you need read instances at all before you pay for the extra replicas and the replication setup they depend on.

Treat the cluster as a serious undertaking, not a shortcut. The README warns that a production deployment can be complex, costly and time-consuming, and that the project does not provide a comprehensive production deployment guide. The example manifests in the repository are a starting point, not a finished design. Your team will own the cluster lifecycle, including control plane high availability, etcd backups, Secret protection and upgrades, along with the Fineract-specific choices for database access, batch scheduling and the close of business run. If your platform team cannot staff those responsibilities, a Docker deployment on virtual machines or a managed hosting arrangement may fit better, and the answer should come from that capacity assessment rather than from a preference for containers.

How read, write and batch instances map to Kubernetes workloads

The write instance accepts requests that create or change client, loan, savings and accounting data. It is the only instance type that runs Liquibase database migrations, so it is the workload that holds schema-changing privileges. On Kubernetes, it usually runs as a single Deployment that owns the connection path to the primary PostgreSQL server for changes.

  • Role: Serves REST calls that modify portfolio and accounting records.
  • Configuration: Enabled through the instance-mode environment variables for write, with the other roles switched off on that pod.
  • Count: The documentation recommends one write instance.
  • Database: Needs read and write access to the primary and to the tenants database, with schema privileges only for the migration window.
  • Migrations: Runs Liquibase only when the write role is active, which is why a second write pod would be an unnecessary risk during upgrades.

Confirm that exactly one Deployment carries the write role and that its database user has schema rights only when you intend a migration.

Which Kubernetes deployment pattern fits your Fineract footprint

This table compares the deployment patterns most teams weigh for Fineract on Kubernetes, from a single namespace with one write and one batch workload to read deployments on replicas, a Mifos X front end and managed versus self-managed clusters. Read each row as a question about your own footprint: the fit tells you when the pattern makes sense, and the trade-off tells you what you take on by choosing it.

PatternBest fitTrade-off to weigh
Single namespace, one write and one batch deploymentEarly environments, pilots and smaller tenant counts where load is modest and read traffic is lightSimplest to operate, but a single write instance and a single batch instance leave no spare capacity for failures or heavy read traffic
Add read deployments on PostgreSQL read replicasReporting, self-service portals or integrations that read heavily while writes stay steadyReplica lag must be understood before reads drive decisions, and each read deployment adds pods, connection pools and monitoring
Separate Liquibase migration job before rolloutAny environment where schema changes ship with each Fineract release and must run once, outside application podsAdds a pipeline step that must succeed before new pods start, so migration failures need a clear rollback plan
Mifos X front end in the same clusterTeams that want a browser interface for back-office staff within the same network boundaryAnother workload to patch, expose and secure, with its own ingress and authentication decisions to settle
Managed Kubernetes serviceOrganizations that want the provider to run the control plane and upgrade it, with platform staff focused on FineractControl plane upgrades follow the provider's schedule, and you must confirm which Kubernetes versions and add-ons it supports
Self-managed distributionOrganizations with strict control over the control plane, etcd, node images or air-gapped delivery requirementsYou own etcd backups, control plane high availability, version skew planning and security hardening for the whole cluster
Batch workload on a dedicated node poolClose of Business runs that take hours on large account books and must not compete with request trafficExtra node capacity sits idle outside batch windows, so confirm the cost and scheduling model with your platform team

Setup sequence for Fineract on a Kubernetes cluster

This sequence takes a Fineract deployment from the example manifests in the repository to a verified HTTPS endpoint, with the database schema migrated once before any write pod serves traffic. Each step closes with a check so the team knows it can move on.

  1. Read the example manifests before editing

    Start from the Kubernetes example files in the apache/fineract repository and read every object before changing anything. Your platform engineer should map each Deployment to its instance type, list the environment variables it sets, and note any image tag, probe, service or ingress definition the example assumes. Fineract's example is a reference for a demo cluster, so the team should expect to replace hard-coded values and default credentials. The step is done when the team can explain, for each workload, which instance type it runs and which settings it relies on.

  2. Create tenant database secrets

    Create Kubernetes Secrets that hold the tenants database connection details and the credentials for each tenant database, using your secret tooling rather than values committed to Git. Restrict who can read these Secrets with namespace-scoped RBAC, because Kubernetes stores Secrets unencrypted in etcd by default unless encryption at rest is configured. Ask your cluster administrator to confirm that encryption at rest or an external secret store is in place. The step is done when the Secrets exist in the target namespace, pods can reference them by name, and a sample RBAC check shows that only the deployment service account can read them.

  3. Run the Liquibase migration as a separate job

    Run the liquibase-only Spring profile as a one-time Kubernetes Job before any write instance starts. Fineract runs Liquibase migrations only on write instances, so a separate job keeps schema changes out of the pod startup path and gives the team a clear record of when the schema changed. Confirm the job uses the same image tag as the write and batch deployments that follow. The step is done when the Job reports completed, its logs show the migration finishing without errors, and the team can query the tenant schemas to confirm they are present and at the expected version.

  4. Deploy write, batch and read instances

    Create one write Deployment, one batch Deployment and the read Deployments, setting the instance type and the database connection through environment variables for each. Point read instances at database read replicas where your PostgreSQL design includes them, and keep the batch instance separate so scheduled jobs and Close of Business work do not compete with the write path. Start with the replica counts your load test supports, not the example counts. The step is done when all pods report ready, the write pod logs show the application started against the expected tenants database, and the read pods show they are not running migrations.

  5. Wire actuator health probes

    Configure liveness and readiness probes against the Spring Boot actuator health endpoints, and confirm the exact path and port in the Fineract documentation for your image tag. Readiness should depend on the database connection, so a pod that cannot reach PostgreSQL stops receiving traffic, while liveness should be tolerant enough that a slow start during the first boot does not trigger restarts. Keep the probes off the batch instance if it has no HTTP listener you intend to expose. The step is done when kubectl describe shows the probes configured, the pods become ready in a clean rollout, and a deliberately blocked database connection in a test namespace marks the pod not ready.

  6. Expose the service through HTTPS ingress

    Publish the read and write services through an ingress controller that terminates TLS with a certificate your organization manages, and set the forwarded headers the Fineract documentation requires for your proxy setup. Decide whether Fineract's embedded SSL stays on or moves to the plain HTTP port behind the ingress, and record that decision with the reason. Restrict the batch instance to internal cluster access. The step is done when an external request over HTTPS returns a valid certificate chain, plain HTTP requests redirect or fail, and the team can see the forwarded scheme in the application logs.

  7. Verify tenant headers and a changed login

    Send a request with the Fineract-Platform-TenantId header set to your tenant identifier and confirm the response comes from the expected tenant database. Then replace the development default login with a strong credential from your secret store and confirm the default one is rejected. Test the authentication path your deployment uses, whether basic authentication or OAuth2, and check that a request without the tenant header fails. The step is done when the tenant-scoped request returns data for that tenant only, the default login no longer works, and the results are recorded so the security team can reproduce them at the next upgrade.

How tenant database secrets should be stored and rotated

Fineract reads its tenant connections from the tenants database, so the credentials for that database and for each tenant database must reach the pods at runtime, never inside the image. Build the image once from the published Fineract distribution and inject database users and passwords through Kubernetes objects, so the same image can move between environments without a rebuild. Confirm which environment variables your chosen Fineract image version expects for the tenants database and for tenant connections before you write the Secret manifests, because the key names are the contract between the manifest and the container.

A Kubernetes Secret is stored unencrypted in etcd by default, so anyone who can read etcd backups or the API with broad list or watch rights can read tenant passwords. Ask the cluster team to confirm that encryption at rest is enabled for Secret resources and that etcd backups are encrypted and access controlled. Then restrict RBAC so that only the Fineract service accounts and the people who deploy them can get or list Secrets in the Fineract namespace, and remove list and watch rights from general developer and monitoring roles. The Kubernetes good practices guidance for Secrets covers these controls and is the right reference for the cluster hardening review.

If your security team requires that secret values are held in a dedicated store with its own audit trail and rotation, use the Secrets Store CSI Driver to mount values from that external store into the pods. Rotation then becomes a change in the external store plus a controlled restart of the read, write and batch deployments, which should be scheduled outside close of business. Replace the default mifos login and password before any environment is shared, and treat the change as a go-live gate. Document who owns each secret, how often it rotates, and how a rotation is tested against the tenants database first.

Security controls for a Fineract cluster on Kubernetes

A Fineract cluster holds client data and ledger records, so the controls around its pods, jobs, credentials and network paths matter as much as the application configuration. The cards below cover the Kubernetes controls that connect the read, write, batch and migration workloads, and the review reference to check them against.

Pod Security Standards for Fineract pods

Apply a Pod Security Standards level to the namespace that runs the read, write and batch deployments, and confirm that the Fineract containers can run without privilege escalation, host networking or host paths. Check the image user, the read-only root filesystem and the dropped Linux capabilities against the level you choose. Test the manifests in a non-production namespace first, because a stricter level can block the migration job or sidecars your team adds.

RBAC scope for migration and batch jobs

The Liquibase migration job and the batch instance need different permissions from the read and write workloads, so give each its own service account and role. Bind only the verbs and secrets each job reads, and confirm that no job can list or watch Secrets across the namespace. Review the bindings after every upgrade, since a new chart version can add permissions that were never granted on purpose.

HTTPS only with SSL settings

Decide where TLS ends: at the ingress controller or inside the Fineract pod through settings such as FINERACT_SERVER_SSL_ENABLED. The Fineract documentation strongly encourages HTTPS only, so the chosen path must reject plain HTTP to the API and forward the original scheme to the application. Record the certificate source, renewal method and cipher policy in the deployment plan, and test them with an external scan before go-live.

OIDC for cluster access

Kubernetes does not manage ordinary users as API objects, so human access to the cluster depends on the authentication method you configure, such as X.509 client certificates, OpenID Connect tokens or an authenticating proxy. Connect the cluster to your identity provider with OIDC, map groups to RBAC roles, and disable shared static credentials. Confirm who can reach the API server and the namespace that holds the tenant database secrets.

CIS Kubernetes Benchmark review

Use the CIS Kubernetes Benchmark as an independent checklist for the control plane, worker nodes and policies around the Fineract namespace. Run a benchmark scan against the cluster, record each failed item with an owner and a decision to fix or accept it, and keep the results with your change records. The benchmark is a review reference, not a certification, so it does not replace an assessment by your auditor.

Network policies for database access

Create network policies that allow only the Fineract read, write and batch pods to reach the PostgreSQL endpoint on its port, and deny other ingress to the database namespace. Confirm that your CNI plugin enforces network policies, because a policy object without enforcement has no effect. Include the batch instance and any read instances that connect to read replicas in the allow list, and test the rules by attempting a connection from an unrelated pod.

How rolling upgrades of Fineract and Kubernetes should be sequenced

Upgrade Fineract and Kubernetes as two separate tracks, and sequence each one deliberately. Fineract publishes official releases quarterly, at the end of each quarter, and archives end-of-life releases, so the image tag in your manifests should be pinned to a specific release and changed only through a planned change. Read the release notes for every Fineract version you skip over, check whether the Liquibase changes need a maintenance window, and confirm the target release is still supported before you start. Kubernetes moves faster: releases arrive roughly every 14 weeks, and the project currently maintains 1.37 (end of life October 28, 2027), 1.36 (June 28, 2027) and 1.35 (February 28, 2027), as of September 2026. Plan your cluster upgrades against those dates so that you never run an unsupported minor version in production.

On the Fineract side, run the Liquibase migration job once, to completion, before any write pod rolls to the new image. Liquibase migrations run only on write instances, and on Kubernetes they are designed to run separately with the liquibase-only Spring profile, so the schema is already in its new shape when the new application code starts. Roll the write deployment next, then the batch instance, and only then the read instances, so that the component that owns the schema and the Close of Business job are on the same version before readers and background work follow. Confirm that the batch job is not mid-run when you roll it, because a restarted COB run is a recovery task in its own right. Check the health of each rollout through the actuator endpoints before moving to the next deployment.

On the cluster side, the Kubernetes version skew policy sets the order: upgrade kube-apiserver first, one minor version at a time, then kube-controller-manager and kube-scheduler, then kubelets. Kubelets may run up to three minor versions older than kube-apiserver, which gives you room to upgrade nodes in batches, but it is not a reason to delay them indefinitely. Upgrade the etcd cluster and take a snapshot with etcdctl snapshot save before the control plane changes, and confirm the snapshot restores in a test environment. Keep the Fineract upgrade and the Kubernetes upgrade in separate change windows so that a failure can be attributed to one of them, and record the exact Fineract image tag and Kubernetes version that were running before each change.

Limits to confirm in your environment before go-live

The example manifests and the Fineract documentation do not settle several decisions for your cluster. Each card below names one limit to confirm with your platform team, your vendor or your own test results before production traffic reaches the platform.

Kubernetes conformance and support window

Confirm that your distribution is listed as a CNCF Certified Kubernetes offering and that its minor version is still inside the upstream support window. Upstream support for 1.35 ends February 28, 2027, so a cluster on that line will need an upgrade plan before the next Fineract release cycle. Ask your distribution vendor for its own patch policy, since it may lag upstream.

etcd topology and backup plan

Decide between a stacked control plane and an external etcd cluster, and confirm the member count is odd. Upstream guidance recommends five members in production. Test the etcdctl snapshot save backup on a schedule, and rehearse a restore with etcdutl in a non-production cluster so the procedure is known before an incident.

COB duration at your account volume

The Close of Business job can run for several hours on deployments with millions of accounts. Measure COB on a copy of your data volume, not on the demo dataset, and set the batch instance's pod resources and any remote partitioning workers from that measurement. Confirm the window your business day allows before setting the cron schedule.

Manifests matched to your Fineract release

The example manifests in the repository change with the project. Confirm that the image tag, the Liquibase job and the environment variables in your manifests match the exact Fineract release you run, and check the release notes before each upgrade. Pin image tags rather than using a moving tag such as latest.

Event broker setup if enabled

External business events are disabled by default. If you enable them, confirm which broker you run, ActiveMQ or other JMS brokers or Apache Kafka, and that its topics, credentials and network paths exist in the same cluster or reachable network. Test event delivery and consumer lag before relying on downstream systems, and store broker credentials as Kubernetes Secrets.

Mifos X front end version compatibility

Mifos X is the front end the Kubernetes example uses, and it is a separate project with its own release line. Confirm with its maintainers which version works with your Fineract release, and test login, tenant selection and loan workflows after every Fineract or front-end upgrade. Do not assume a newer front end works with an older API.

Questions buyers ask before deploying Fineract on Kubernetes

What drives the cost and effort of deploying Fineract on Kubernetes?

The main drivers are how many Fineract instance types you run, how much of the surrounding platform you build, and how much existing cluster work you can reuse. A plain setup with one write instance, one batch instance and a few read instances is far less work than a setup that also adds ingress and TLS design, external identity, secrets management, monitoring, backups and a tested upgrade runbook. Cost is mostly people time, both for DeployOpen's fixed-scope work and for your own staff who review, approve and operate the result. Ask for a written scope that lists each Kubernetes object, each integration, each environment (test, staging, production), and who owns each recurring task after handover. Ask separately for any retainer for upgrades and support, since those costs recur.

Can our own team deploy Fineract on Kubernetes without outside help?

A team with solid Kubernetes, PostgreSQL and Java operations experience can deploy Fineract without a partner, but the project's own README warns that a production deployment can be complex, costly and time-consuming and that it does not provide a comprehensive production deployment guide. The work that most often catches teams out is not the first install. It is the separation of write, batch and read instances, the Liquibase migration step, tenant database secrets, health checks, and a rolling upgrade plan that respects the database. Decide early whether your team will own the design and the runbooks, or only run them. If you want an outside check, ask the partner to state which parts they build, which they review, and which your staff must complete.

How long does a Fineract Kubernetes deployment take and what affects it?

Duration depends on the number of environments, the state of your cluster, how many tenants you start with, and whether database and identity services already exist. A cluster that already runs a GitOps pipeline, managed PostgreSQL and a central identity provider shortens the work. A greenfield cluster needs time for network policy, storage, ingress and certificate decisions first. Most engagements are fixed-scope, so the timeline is agreed in writing before work starts. Ask for milestones tied to specific deliverables, such as a working write instance against a test database, a verified migration job, and a documented rollback, rather than a single completion date.

What does the work need from our side: cluster access, database, identity and change windows?

The work needs a few things from your organization before it starts:

  • Cluster access for the agreed namespaces, with the RBAC roles the team will use during and after the build.
  • A PostgreSQL server that Fineract can reach, since PostgreSQL is the recommended database and the Docker image ships only its JDBC driver, plus a tenants database and credentials for each tenant.
  • An identity decision for OAuth2 or HTTP basic authentication, because the default development login must be replaced before any real use.
  • Change windows for schema migrations and for rolling upgrades, agreed with the business teams that run loan and savings operations.

Ask the partner to list each of these as a client dependency with an owner and a date in the written scope.

Is Kubernetes required to run Apache Fineract in production?

No. Fineract is a Spring Boot application that can run from a JAR, and the project's documentation describes read, write and batch instance types set through environment variables that work outside Kubernetes too. Kubernetes is a reasonable choice when you already operate clusters and want the scaling, health checking and rolling update features they provide. If your platform team has no Kubernetes experience, a plain container host or virtual machines may be simpler to run. The decision should follow your existing operating model, your staffing and your recovery requirements. Ask for a written comparison before the build starts so the choice is recorded.

How are Fineract upgrades handled on Kubernetes?

An upgrade has two parts: the Fineract release and the Kubernetes version. The project creates official releases quarterly, and its documentation says Liquibase migrations run only on write instances, so the migration job must complete before the new application version takes traffic. For the cluster, Kubernetes maintains the three most recent minor releases and its version skew policy requires the API server to be upgraded one minor version at a time, before the controller manager, scheduler and kubelets. Ask for a written upgrade runbook that covers a database backup before each step, a staging rehearsal, the order of workloads, and a rollback path. Confirm whether upgrade work is included in the fixed scope or billed as a retainer.

Does DeployOpen issue compliance certificates for a Fineract Kubernetes deployment?

No. DeployOpen prepares systems, controls and evidence for compliance assessments, but it does not issue audit reports, attestations or certifications. Independent auditors and certification bodies perform those assessments. For a Kubernetes deployment, the evidence typically includes configuration baselines, RBAC reviews, how Secrets are protected, backup and restore test records, and change records for upgrades. Kubernetes stores Secrets unencrypted in etcd by default, so encryption at rest is one item your assessor will expect to see evidenced. Ask the partner which evidence it will prepare, in what format, and which parts remain your responsibility.

How DeployOpen scopes, delivers and supports Fineract on Kubernetes

DeployOpen plans, implements, hardens, documents and supports self-hosted open-source platforms inside the client's own infrastructure, and a Fineract on Kubernetes engagement follows the same pattern. DeployOpen is a Chainscore Labs company. The work runs in your cloud accounts, data centers or air-gapped networks, so the cluster, the tenant databases, the secrets store and the registry stay under your control. Before any build starts, the team agrees the scope in writing: which clusters and namespaces are in play, how many write, batch and read instances Fineract will run, which PostgreSQL topology sits behind them, how TLS is terminated, and which upgrade path applies. Each of those decisions changes the effort, so they belong in the written scope rather than in a later change request.

Most engagements are fixed-scope, and the written scope lists deliverables and timelines before work begins. DeployOpen does not publish a price list, so the quote follows from that scope. To prepare a useful quote, ask for the list of deliverables, the environments covered (for example, non-production and production), the handover format for manifests and runbooks, the acceptance tests that close each deliverable, and the assumptions the team has made about your clusters, identity provider and database. One-time costs cover design, build, configuration, verification and knowledge transfer. Recurring costs appear when you keep the platform supported after go-live. Ask for those separately so you can compare them with running the platform with your own staff.

Ongoing support, upgrades and continuous testing are available as retainers. This matters for Fineract because the project publishes quarterly releases and archives end-of-life releases, so the cluster will need regular manifest updates, image tag changes and Liquibase migration runs. A retainer can cover monitoring of the upgrade calendar, testing against the new release, and rolling upgrades in a staging environment before production. Confirm with DeployOpen which of these items the retainer covers, which response expectations are written into it, and who owns Kubernetes cluster upgrades, which follow their own version skew rules. Ask for those answers in writing before you sign.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.