Running ERPNext on ARM64 servers

ERPNext can run on ARM64 servers when every image and native dependency in your stack is built for arm64. This page explains how to build, publish and pin multi-architecture images and what to verify before production.

On this page

Can ERPNext run on ARM64 servers such as Graviton?

Whether ERPNext runs on ARM64 depends less on ERPNext itself than on the arm64 availability of every image and native dependency in your stack. A self-hosted ERPNext pulls in the Frappe Framework, Python and Node.js packages with compiled extensions, a database server, Redis, and an NGINX proxy. If any one of those components ships only for amd64, the whole deployment needs either an emulation layer or a different host. Teams ask this question mostly for three reasons: they want lower-cost compute on AWS Graviton instances, they want cheap or local test capacity on Apple Silicon machines, or they run a mixed fleet and want one set of build artifacts across both architectures. Self-hosting ERPNext is free under its open-source license, so the cost question is about the infrastructure you run it on, not a license fee. The frappe_docker repository provides production Docker images and Compose files for ERPNext and related services, which is the most practical starting point for an ARM64 test. Do not assume those images are published for arm64 because the project is widely used. Check the image manifest for the exact ERPNext and Frappe version you plan to run, and confirm that the MariaDB, Redis and NGINX tags you pin also provide arm64 variants. Record the result in your build notes so the check is repeatable at each upgrade. If an arm64 manifest is missing for any component, you have three options: build that image yourself, pin a different tag that supports arm64, or run that service on amd64 hardware. Treat ARM64 as a supported target only after a full install, a site creation, a background job run and a backup restore have succeeded on the target architecture, not just after the containers start.

Which ARM64 build approach fits your environment

This table compares four ways to produce ERPNext images that run on ARM64, from one multi-architecture build to an all-ARM64 pipeline. Read each row against your own build farm, registry setup and test coverage. The main takeaway is that the approach with the fastest build is not always the one that gives you the most confidence in production.

ApproachWhen it fitsBuild time and CI implicationsTest confidence and production trade-offs
Single multi-architecture image with buildx, one registry tagYou want one image name that serves both amd64 and arm64 hosts, and your CI can reach both build platformsBuilds run for each platform inside one buildx invocation, so pipeline logic stays simple but the job waits on the slowest platformOne tag covers both architectures, so every promoted release needs tests on both platforms before it is published
Separate native amd64 and arm64 builds merged into a manifestYou have native arm64 build capacity, such as ARM runners, and want each architecture built on its own hardwareParallel jobs shorten wall-clock time, but CI needs a manifest step that runs only after both images are pushedEach architecture can be tested on native hardware, which gives stronger evidence than emulation, but the merge step must be verified
Building on x86 with QEMU emulationYou have only x86 build agents and need arm64 images for occasional test machines rather than production trafficEmulated builds are generally slower, and some native dependency compilation may be significantly slower or fail, so confirm the pipeline timing on your own runnersEmulated images can behave differently from native ones, so run functional tests on real arm64 hardware before relying on the result
All-ARM64 environment that builds only arm64Your production, staging and developer machines all run ARM64 and you do not need amd64 imagesSmallest matrix and simplest pipeline, but you lose the amd64 build as a fallback if a dependency lacks arm64 supportStrong fit for one architecture, but any amd64 host you add later needs its own build path and test cycle
Production exposure of the chosen approachYour organization must support a mixed fleet or move hosts between architectures during upgradesConfirm with your platform team how image pulls resolve on each node and whether your Kubernetes or Compose setup selects the right platformDocument which architectures are supported, who signs off each release and how a rollback is run on each platform

How buildx produces one tag for both architectures

A multi-platform build with docker buildx compiles the same Dockerfile once per target architecture, typically linux/amd64 and linux/arm64, and publishes the results under one tag. That tag points to a manifest list (also called an image index), which is a small document listing one image per platform. When a Docker host pulls the tag, the engine reads the manifest list, selects the entry that matches its own CPU architecture, and downloads only that variant. An x86 build server and a Graviton instance can therefore run the same image:tag line in a Compose file and each receive its native image. The build step needs a buildx builder that supports the target platforms, and the push must go to a registry that accepts manifest lists. Confirm both on your build host before assuming the pipeline works.

Each service in a Compose file can state its target with the platform key, for example platform: linux/arm64, which forces the engine to request that variant even when the host is different. Use this on test machines only when you need to pin behavior deliberately, because a forced platform on an emulated host runs far slower. If a service has no arm64 entry in its manifest list, the pull fails on an ARM64 host with a no-matching-manifest error, or the engine falls back to emulation if that is enabled. Check every image the stack uses, including MariaDB, Redis and any helper containers, and confirm each one publishes arm64 before you commit to the platform. The exact build arguments, Dockerfile paths and Compose file names change between releases, so take them from the frappe_docker repository for the version you deploy, not from older notes.

The tag alone does not prove the image is correct. A tag such as latest or a version label can resolve to a manifest that lists arm64, while the arm64 layers were built from different app commits or with a missing dependency. Inspect the manifest with docker buildx imagetools inspect and confirm both platforms are present, then run the ERPNext and Frappe version checks inside each architecture's container. Record the digest of each platform image in your change record so a later pull can be compared against the tested build. Pinning the digest, not only the tag, is the control that shows which bytes a given host ran.

Which images and dependencies must support arm64

An ERPNext stack on ARM64 is only as portable as its slowest dependency. Each component below can block a build, a pull or a runtime call, so check them in the order they appear in your images and build pipeline. For each one, confirm arm64 availability from the vendor's own published tags or build metadata rather than assuming it.

ERPNext and Frappe application image

This is the image your bench or Compose stack builds from the frappe and erpnext apps plus any extra apps. Confirm that the base image you build from and the frappe_docker build process produce a linux/arm64 variant, and that the apps you add do not pin x86-only binaries. Check the platform field on every build step, because a single amd64 base layer forces an emulated or failed build for the whole image. Pin the ERPNext version you test on, since the supported majors are 15 and 16.

MariaDB image

MariaDB runs the site databases and is the component most sensitive to storage and memory behavior. Check the official MariaDB image tags on your registry for a linux/arm64 manifest for the exact version your Compose file or Helm values reference. If you use an external managed database, confirm with the provider which engine versions and CPU architectures they run, and test restore on the same architecture you will run production on.

Redis image

Redis serves as both cache and queue for background jobs in ERPNext. Confirm that the Redis tag your deployment uses publishes an arm64 manifest, and check the same for any Redis-compatible replacement you choose. Test queue behavior under load on ARM64, because the workers and scheduler depend on it for document events, emails and scheduled jobs.

Nginx image

The Nginx service routes requests to the web workers and Socket.io, and it serves static assets. Confirm that the Nginx tag you pin has an arm64 manifest, and that any custom configuration or module you add builds on that architecture. If you terminate TLS at a separate proxy or load balancer, confirm that component as well, since it sits on the same request path.

Socket.io and scheduler containers

These containers run the realtime server and the scheduler, and they reuse the ERPNext application image with different commands. Confirm they start from the same arm64 image digest as the web and worker containers, so you do not run two architectures in one deployment. Check that the scheduler process starts and logs its jobs on ARM64, because a silent scheduler failure only shows up later as missed invoices, emails or reorders.

PDF rendering tooling for print formats

Print formats and invoices rely on a PDF rendering engine that depends on system libraries and fonts. Check that the wkhtmltopdf or equivalent build you install provides an arm64 package, or that your Linux distribution packages it for that architecture. Render each print format you use in production on the ARM64 target and compare layout, fonts and page breaks with your x86 baseline.

Node-based asset build and native Python extensions

Asset bundling runs Node tooling during the build, and Python packages from custom or third-party apps may compile native extensions. Confirm that the Node version and any native modules publish arm64 binaries, and that Python wheels exist for aarch64 or the build can compile from source. Record each native dependency in your app manifest, because a package that only ships an x86 wheel will fail at build time or break at runtime.

Setup sequence for an ARM64 ERPNext environment

This sequence takes a team from a version decision through a multi-architecture image build to a running ERPNext site on an ARM64 host, with a check at each step so failures surface before go-live testing. It produces a recorded set of image digests that ties the tested environment to specific builds.

  1. Confirm the ERPNext and Frappe version

    The platform engineer checks the Frappe supported versions page and selects an ERPNext and Frappe Framework major version that is still listed as supported. Confirm the version line against the current support table before you pin anything, because versions 14 and 15 are on different end-of-life dates. Record the chosen version in your build notes. Done when you have a written version pair and a note that it is listed as supported on the day of the decision.

  2. Inventory every image and app in the stack

    The platform engineer lists every container image in the Compose or Helm setup, including MariaDB, Redis, the ERPNext and Frappe images, Nginx and any custom apps listed in your apps.json. For each entry, note the upstream source, whether it publishes an arm64 variant, and the tag or digest you plan to pin. Flag any third-party app that has no arm64 build so it becomes a build task rather than a surprise. Done when the inventory has one row per image with a pinned tag and an arm64 status column.

  3. Enable a buildx builder with arm64 support

    The build engineer creates a Docker buildx builder that can target linux/amd64 and linux/arm64, using either QEMU emulation on an x86 build host or a native ARM64 builder node. Emulated builds are slower and can fail on compiled Python or Node dependencies, so decide which path fits your CI runners. Confirm the builder before the image build starts. Done when the command that lists builders shows a builder whose platforms include both linux/amd64 and linux/arm64.

  4. Build and push a multi-architecture image

    The build engineer runs a buildx build for the custom ERPNext image with both target platforms, pushes it to your registry, and uses the same apps.json and pinned Frappe branch used in step one. Build secrets for private app repositories should be passed as secrets, not build arguments. Done when the push completes without errors and the registry shows one tag that points to a manifest list.

  5. Verify the manifest lists both platforms

    The build engineer inspects the pushed tag with the buildx imagetools inspect command or an equivalent registry query. The output should list a linux/amd64 entry and a linux/arm64 entry, each with its own digest. If only one platform appears, the build did not produce a manifest list and should be rerun before any deployment. Done when both platform entries are visible for the tag you plan to deploy.

  6. Set the platform on each Compose service where needed

    The platform engineer edits the Compose file so that services built from your image, and any third-party service that lacks a matching arm64 image, declare the platform explicitly. Pull behavior varies by image, so set the platform only where a service needs it and leave multi-architecture upstream images to resolve automatically. Record each override and the reason for it. Done when the Compose config renders without warnings and each overridden service has a comment explaining the change.

  7. Pull and start the stack on an ARM64 host

    The platform engineer copies the Compose file and environment file to an ARM64 host, pulls every image, and starts the stack in detached mode. Check the logs of the configurator, database and web containers for startup errors such as exec format errors, which usually signal a wrong-architecture image. Done when each container reports a running state and the web container logs show Gunicorn or the expected server process starting.

  8. Confirm container architecture and create a site

    The platform engineer runs a command inside a running ERPNext container to print its architecture, such as uname -m, and expects aarch64 or arm64. Then the engineer creates a site with the bench command inside the backend container and installs the required apps. Done when uname reports an ARM64 architecture and the site creation command completes without errors.

  9. Run a smoke test and record image digests

    The QA engineer logs in to the new site, opens a sample document, saves it, runs a basic report, and confirms background jobs run through the worker logs. Then the engineer records the manifest digests for the ARM64 and AMD64 images, the Compose file revision and the ERPNext version in your change record. Done when the smoke test passes and the change record contains the digests that the tested environment used.

Graviton servers and Apple Silicon test machines need different checks

A Graviton tab should be read as the closest thing to a production check on ARM64. The question is whether the same images, configuration and workload run correctly on the instance family and storage you plan to operate, and whether the x86 path you already trust gives the same results. Confirm the instance family, the number of vCPUs, memory, and the EBS volume type and throughput with your cloud provider before you size anything, because the ERPNext database and background workers depend heavily on disk latency.

  • Instance selection: Choose an instance family that matches the ARM64 architecture and the memory your database buffer pool needs. Ask the provider which families are current for your region.
  • Storage sizing: Confirm volume type, provisioned IOPS and throughput for the MariaDB data directory and the file store. Ask how burst credits, if any, behave under sustained load.
  • Network sizing: Confirm bandwidth limits for the instance type and whether traffic between web, worker and database nodes stays within the same availability zone.
  • Parity testing: Run the same site, the same apps and the same scheduled jobs on an x86 build and an ARM64 build, then compare reports, print outputs, background job results and error logs.
  • Image pinning: Use the same version tags on both paths, and record the digest of every image you deploy so you can prove what ran.

Before sign-off, check that every background queue drains, that scheduled jobs complete, and that the parity results match for your most used reports and documents.

Security risks in multi-architecture builds

Building one ERPNext image for both amd64 and arm64 doubles the artifacts you must trust, sign off and keep patched. The risks below sit in the build pipeline and registry rather than in ERPNext itself, and each one changes what you check before a release goes to a site that holds your accounting and stock data.

Base image provenance per architecture

Each architecture variant of a base image can come from a different publisher build, so confirm the source of the arm64 variant separately from amd64. Record which upstream image and tag each architecture pulls, and confirm that the publisher documents how its arm64 images are built. Keep the base images your Dockerfiles reference on an approved list that your security team reviews.

Pinning tags to digests

A tag such as a version name can move to new content, so the amd64 and arm64 images can drift apart without any visible change in your Dockerfile. Pin base images and your own outputs to digests, and check that both architectures in a manifest list resolve to the build you tested. Update digests through a reviewed change rather than a rebuild that silently picks up new content.

Build secrets kept out of layers

Credentials used to fetch private apps or packages during a build can persist in image layers, where anyone with pull access can extract them. Pass secrets to the build with buildx secret mounts, never as build arguments or ENV lines, and inspect the image history after each build to confirm nothing sensitive remains. Rotate any credential that once reached a layer.

Scanning each architecture variant

A vulnerability scan of the amd64 image does not describe the arm64 image, because packages and binaries differ by architecture. Scan every platform variant, and scan the manifest list by digest so the scan result is tied to the artifact you deploy. Keep the scanner's findings with the release record so you can show what was reviewed for each architecture.

Trust in emulated builds

Building the arm64 image on an amd64 runner through QEMU emulation runs third-party binaries under emulation, which can behave differently from native execution and makes failures harder to diagnose. Treat emulated build steps as part of your supply chain, limit which build stages run under emulation, and prefer native arm64 build runners for release builds where your CI platform offers them.

Registry access control

Anyone who can push to the registry can replace an image that your staging and production hosts pull, so write access should sit with the release pipeline and not with individual engineers. Restrict pushes to named CI identities, require signed or attested artifacts where your registry supports them, and review who can delete or retag images.

How to test ERPNext before trusting an ARM64 build

Treat an ARM64 build of ERPNext as untrusted until the same functional tests pass on it and on the x86_64 build you already run. The core idea is comparison: run identical scenarios on both architectures and compare the results, not just whether the containers start. Most of ERPNext is Python and JavaScript, so a successful boot proves little. The risk sits in native code pulled in by the Python dependencies, the database driver, and any compiled assets, where a wheel built for the wrong architecture can fail only when a specific code path runs.

Build the plan around the paths your business depends on. Cover document saves across the accounting and stock doctypes you use, including submission, cancellation and naming series. Exercise background jobs and the scheduler by queuing a long job and confirming it runs on the long queue worker, and trigger one scheduled task with a known outcome. Generate a report and a print format for the same documents on both architectures, then compare the PDFs and exported data. Upload a file through the Desk and confirm it is stored, served and readable. Finally, test the login path you actually use, whether that is local password, two-factor authentication, LDAP or a Social Login Key provider, because identity flows touch libraries that are easy to overlook.

Write the coverage and acceptance criteria into the written scope before any build is accepted. Agree which scenarios, which data sets, which documents and which comparison method (exact output, field-level diff or reviewed sign-off) define a pass, and who signs off on any difference. Confirm with your partner and with the image maintainers which ARM64 base images and dependency builds have been exercised by the project, rather than assuming parity. Record any mismatch as a blocking defect until it is explained.

Limits to confirm in your environment

ARM64 support for ERPNext depends on several layers at once: the application images, the custom apps you add, the database and cache services, the backup tooling and the cloud services underneath. Each layer has its own answer, and a gap in any one of them can block a go-live. Confirm each item below against the named source before you commit to an instance family.

Architecture support for your exact versions

Confirm that the ERPNext and Frappe Framework versions you plan to run publish arm64 images or build cleanly for linux/arm64. Support can differ between minor releases, so check the exact tags you pin, not the project in general. Use the release pages for ERPNext to see which versions are current, and test the tag you intend to deploy on the target architecture before you rely on it. The answer comes from the Frappe project and your own test run.

Support status of the chosen version

An architecture that builds is not the same as a version that is supported. Check the Frappe support page for the end-of-life date of your ERPNext and Frappe version before you choose the platform. A version past end of life still runs on ARM64, but you will carry the security and upgrade risk alone. Confirm the support window with Frappe and record it in your upgrade plan.

Custom apps building on arm64

Every app in your image must build on the target architecture, including Frappe apps from third parties and your own code. Pure Python apps usually build cleanly, but apps with compiled Python dependencies or Node packages that ship native binaries can fail or pull the wrong wheel. Run the full image build for linux/arm64 in CI, and confirm that each app's dependencies publish arm64 wheels or compile from source.

Database and cache images with your settings

The MariaDB and Redis images you run in production must have arm64 variants that accept the configuration you need, such as the character set, collation, buffer pool size and the Redis persistence options ERPNext depends on. Check the image tags against the arm64 platform list, and confirm that the settings you apply through configuration files behave the same on that build. Test restores on the same image you run in production.

Backup and restore tooling on the target architecture

Backup scripts, database dump utilities, encryption tools and any offsite sync agent must run on the architecture you deploy to. A backup that runs on an x86 workstation but fails on an ARM64 host is a gap you only find during an incident. Run a full backup and a restore into a clean environment on ARM64, and time it against your recovery objectives. Record the tool versions used in the test.

Managed services and instance family support

If you use managed database, cache, object storage or Kubernetes services, confirm that the specific instance family and the service version support ARM64 in your region. Some managed offerings support arm64 for certain engine versions only, and some features, such as certain storage or replication options, may be unavailable on that family. Ask the cloud provider for the current support matrix, and confirm the answer in a test environment before you size production.

Questions teams ask before running ERPNext on ARM64

Is ERPNext supported on ARM64 servers?

ERPNext itself is a Python and JavaScript application on the Frappe Framework, so it is not tied to one processor architecture, but whether a given image, base layer or dependency runs on ARM64 depends on how it was built and which apps you add. Before committing, confirm with your own build which images and native packages publish ARM64 variants. Test the full stack on your target architecture, including the database, Redis and every custom app, rather than assuming a working x86_64 build transfers. Treat the platform choice as a question your build pipeline must answer for each release.

What does a buildx setup change in the build pipeline?

Docker Buildx lets one build definition produce images for more than one platform, usually linux/amd64 and linux/arm64, and publish them under a single tag as a multi-architecture manifest. In practice you set the platform on each service in your Compose file or CI job, add QEMU emulation or native ARM64 runners, and push both variants to the same registry path. Build time, cache handling and secret injection change, because emulated builds of compiled dependencies are much slower than native ones. Pin tags so the amd64 and arm64 images always come from the same source revision.

Is Apple Silicon good enough for ERPNext testing?

Apple Silicon machines run ARM64 Linux containers natively, so they are a reasonable place to check that images start, migrate and serve pages. They are less suited to load testing, because the hardware, memory and disk behavior differ from the server class you plan to run in production. Use them for functional checks and developer builds, then confirm performance and final image behavior on servers that match your production architecture. Ask your partner or internal team to state which checks run on which hardware.

How much effort does ARM64 support take, and what drives it?

Effort depends mostly on the number of custom apps, how many of them contain native extensions or compiled dependencies, and how much of your CI relies on x86_64 assumptions. A standard ERPNext image with no extra apps is the simplest case. Each additional app adds build steps, test runs and possible dependency fixes. Changes to CI, such as adding ARM64 runners or emulation, and the test matrix you need for accounting, stock and production flows also add work. Ask for an estimate that lists these drivers separately, since no fixed duration can be given before the app inventory is known.

Can our team do this without an outside partner?

Yes, if you have people who can maintain Docker builds, read dependency failures and run ERPNext upgrades. The work is largely engineering judgment applied to your build pipeline, so the main question is capacity and skill, not access to a special toolchain. Teams usually find the first build and test cycle takes the longest, and that later releases are faster once the pipeline is stable. A partner can be useful for the initial pipeline design, dependency review and handover, or for ongoing maintenance through a retainer if your team cannot keep up with releases.

What does the work need from our team?

You will need a container registry that accepts multi-architecture manifests, CI runners or build hosts for ARM64 (native or emulated), a test environment that runs the same images you plan to deploy, and a named owner who approves changes and decides on releases. Access to your source repositories for custom apps and to the production-like database and storage used in tests is also required. Confirm these with your platform team early, because missing runners or registry permissions are a common reason builds stall.

How is the cost structured, and what should a written quote include?

Costs fall into two groups. One-time work includes pipeline design, multi-architecture build setup, custom app compatibility fixes and the first test cycle. Recurring work includes rebuilding images for each ERPNext and app release, rerunning tests, patching base images and maintaining runners. The quote should separate these groups, name every custom app in scope, state which environments and architectures are tested, and list what the client provides, such as runners, registry access and test data. Ask how upgrades to later ERPNext minor and major versions are priced and whether retainer support is included.

How DeployOpen scopes and delivers ARM64 ERPNext work

DeployOpen plans, implements, hardens, documents and supports self-hosted open-source platforms inside your own infrastructure, including ERPNext on ARM64 hosts. We start from a written scope that names the architectures, images, services and test machines involved, then build and verify each step before anything reaches a production environment.

How we scope

  • Written scope names the target ARM64 hosts, such as Graviton or Apple Silicon test machines, and their operating systems.
  • We list every ERPNext service image and confirm which ones must be rebuilt for linux/arm64.
  • Scope records which of your custom apps and third-party Frappe apps need ARM64 compatible builds.
  • Engagements are fixed-scope, so deliverables and timelines are agreed in writing before work starts.

How we build

  • We configure buildx builders and produce multi-architecture images for each ERPNext service.
  • Each service in the Compose or Kubernetes definition gets an explicit platform setting that we verify.
  • Pinned tags and build inputs are recorded so a rebuild produces the same image set.
  • We run the stack on the target ARM64 hosts and test web, worker, scheduler and socket.io paths.

How we hand over

  • You receive the build scripts, image definitions and platform configuration in your own repository.
  • Runbooks describe how to add an architecture, rebuild images and roll back a failed release.
  • We document which checks confirm a deployment is healthy on ARM64 and which differ from amd64.
  • Handover includes a walkthrough with the engineers who will operate the platform.

How we support

  • Ongoing support, upgrades and continuous testing are available as a retainer.
  • Retainer work can cover rebuilding images when ERPNext or Frappe releases new minor versions.
  • We can retest ARM64 builds after dependency changes, base image updates or host replacements.
  • Support scope and response expectations are confirmed in writing before the retainer starts.

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.