DevOps

Why Judge0 Doesn't Just Run on ARM64: What I Discovered While Investigating Compiler Infrastructure

I investigated what it actually takes to run Judge0 on ARM64, why its official Docker images are currently amd64, and how this differs from deployment platforms such as Nife, Vercel, Netlify, and Cloudflare.

Shilpa H K
Shilpa H K
26 min read
Why Judge0 Doesn't Just Run on ARM64: What I Discovered While Investigating Compiler Infrastructure

I started looking into ARM64 compatibility for Judge0 because I wanted to understand whether Judge0 could be moved to ARM-based infrastructure such as AWS Graviton.

At first, this looked like a straightforward Docker question.

If the application is packaged as a container, shouldn't I just do this?

docker buildx build \
  --platform linux/arm64 \
  -t judge0:arm64 .

That was my initial assumption.

But after looking at the Judge0 Docker images, its compiler image, the languages it packages, the sandbox it uses, and the way the application actually executes submitted code, I found that this is not really a normal Docker multi-architecture problem.

The more interesting question is:

What does ARM64 compatibility actually mean when your container contains dozens of compilers, interpreters, runtimes, and a code-execution sandbox?

That led me to compare Judge0 with platforms I work with more closely, including Nife, Vercel, Netlify, and Cloudflare.

The comparison revealed something important:

ARM64 support is relatively simple when the platform is deploying an application or serving already-built artifacts. It becomes a completely different engineering problem when the platform itself has to compile and execute arbitrary code.


Table of Contents

  1. Why I Started Investigating Judge0 on ARM64
  2. What I Found in the Official Judge0 Images
  3. Judge0 Is Not Just One Application
  4. The First ARM64 Problem: The Docker Image Itself
  5. The Second Problem: The Compiler Stack
  6. The Third Problem: The Sandbox
  7. Why --platform=linux/arm64 Is Not a Magic Fix
  8. What My Investigation Changed About the Question
  9. Judge0 vs Nife vs Vercel vs Netlify vs Cloudflare
  10. Nife: The Infrastructure Lens
  11. Nife Can Deploy More Than Just Websites
  12. Vercel: Architecture Is Exposed at the Function Layer
  13. Netlify: Build Environment vs Runtime
  14. Cloudflare: A Different Kind of Sandbox
  15. The Important Difference: Deployment Platform vs Code Execution Platform
  16. Why ARM64 Is More Difficult for Judge0
  17. What Would Be Required for Proper Judge0 ARM64 Support?
  18. What I Would Test Before Calling Judge0 ARM64-Compatible
  19. What Are the Practical Options Today?
  20. What About AWS Graviton?
  21. Where Nife Fits Into This
  22. Nife vs Vercel vs Netlify vs Cloudflare: What I Actually Learned
  23. The Real Comparison
  24. One More Important Discovery: ARM64 Does Not Mean "Everything Is Automatically Faster or Cheaper"
  25. What This Investigation Taught Me
  26. FAQ
  27. Conclusion
  28. Further Reading

Why I Started Investigating Judge0 on ARM64

ARM64 has become increasingly interesting for cloud infrastructure.

AWS Graviton is one example. Apple Silicon is another. ARM-based infrastructure is no longer something you only encounter in embedded devices.

So when I was looking at infrastructure workloads that could potentially move to ARM64, Judge0 became an interesting case.

Judge0 is an online code execution system. It doesn't simply receive a web request and return JSON.

It has to take untrusted source code such as:

#include <stdio.h>

int main() {
    printf("Hello World");
    return 0;
}

compile it using the appropriate compiler, execute the resulting program, enforce resource limits, isolate the process, and return the result.

And Judge0 supports a large collection of languages.

The official compiler image contains languages including multiple GCC versions, Clang, Mono, D, Erlang, Go, Haskell, Java, Node.js, Python, Ruby, Rust, and many others.

That immediately changes the ARM64 question.

I'm not asking:

"Can the Judge0 Rails application run on ARM64?"

I'm asking:

"Can the complete Judge0 execution environment—including its compiler toolchain, language runtimes, native dependencies, sandbox, and execution model—run correctly on ARM64?"

That is a much bigger problem.


What I Found in the Official Judge0 Images

The first thing I checked was the official Docker image rather than making assumptions about the architecture.

The official judge0/judge0 images currently published on Docker Hub are listed as:

linux/amd64

For example, the judge0/judge0:1.13.1 image is listed as a Linux AMD64 image, with a compressed size of roughly 3 GB. The extra image is also listed as AMD64.

The underlying compiler image tells the same story.

The official:

judge0/compilers:1.4.0

is published as:

linux/amd64

and is approximately 3 GB compressed.

The Judge0 Dockerfile also makes the dependency explicit:

FROM judge0/compilers:1.4.0 AS production

So the Judge0 API image isn't independently solving the architecture problem.

It inherits the architecture of the compiler image.

That was my first important finding.

Judge0 is not simply an application image

The architecture dependency starts below the API layer.

The stack is closer to:

Judge0 API
    |
    v
Judge0 compiler image
    |
    +-- GCC
    +-- Clang
    +-- Python
    +-- Ruby
    +-- Node.js
    +-- Java
    +-- Go
    +-- Rust
    +-- Haskell
    +-- Erlang
    +-- PHP
    +-- ...many more
    |
    v
Isolate sandbox
    |
    v
Linux kernel / CPU architecture

So changing the architecture at the Docker level is only the beginning.


Judge0 Is Not Just One Application

This is probably the most important distinction I discovered.

If I have a typical web application:

React / Next.js / Node.js application
        |
        v
Docker image
        |
        v
ARM64 container

I can usually solve architecture compatibility by making sure:

  • the base image supports ARM64
  • native dependencies support ARM64
  • the application dependencies support ARM64
  • the final image is built for ARM64

Judge0 is different.

The official compiler image intentionally bundles a large collection of programming languages and specific compiler/runtime versions.

For example, the Judge0 compiler list includes versions such as:

GCC 7.4.0
GCC 8.3.0
GCC 9.2.0
Clang 7.0.1
Mono 6.6.0.161
DMD 2.089.1
Erlang 22.2
Go 1.13.5
Haskell GHC 8.8.1
OpenJDK 13.0.1
Node.js 12.14.0
Python 2.7.17
Python 3.8.1
Ruby 2.7.0
Rust 1.40.0
TypeScript 3.7.4

These versions are part of the environment Judge0 provides.

That means ARM64 compatibility is effectively a dependency matrix.


The First ARM64 Problem: The Docker Image Itself

When Docker reports something like:

exec format error

the immediate problem can simply be architecture mismatch.

Ubuntu 22.04
Linux ... aarch64

exec /api/docker-entrypoint.sh: exec format error

The issue occurred when attempting to run the Judge0 containers on an ARM64 system.

This makes sense.

If the container contains an AMD64 executable and the host is ARM64, the kernel cannot simply execute the binary as if it were native ARM64.

You can check the architecture of a host with:

uname -m

For an ARM64 system you would normally see:

aarch64

And you can inspect an image with:

docker image inspect judge0/judge0:1.13.1 \
  --format '{{.Architecture}}'

If the image is AMD64, you have an immediate architecture mismatch.


The Second Problem: The Compiler Stack

This is where the investigation gets much more interesting.

A compiler is itself software.

And when you run:

C source
   |
   v
GCC
   |
   v
machine code

GCC must understand the target architecture.

On x86_64:

C source
   |
   v
GCC
   |
   v
x86_64 executable

On ARM64:

C source
   |
   v
GCC
   |
   v
ARM64 executable

That doesn't mean GCC itself has to be compiled on the same architecture in every scenario, because cross-compilers exist.

But Judge0's environment is not simply one modern compiler.

It is a collection of many language implementations and compiler versions.

The official compiler image is built around a large set of pinned versions.

That means I can't reasonably say:

"GCC supports ARM64, therefore Judge0 supports ARM64."

Those are different statements.

I would need to verify the complete stack.

For example:

GCC
Clang
Mono
GHC
DMD
SBCL
Erlang
OpenJDK
Node.js
Python
Ruby
Rust
...

And then their native dependencies.

The question becomes:

Does component X support ARM64?
        +
Does version Y of component X support ARM64?
        +
Does Judge0 build/configure it correctly?
        +
Does it behave correctly inside the Judge0 sandbox?

That is a very different problem from building an ordinary Docker application.


The Third Problem: The Sandbox

There is another important component: Isolate.

Judge0 uses Isolate to execute submitted programs with resource and isolation controls. The Judge0 changelog explicitly describes compilation and execution taking place inside the sandbox and notes that Judge0's compiler image uses an updated Isolate version.

This means architecture compatibility isn't only about compiler binaries.

The execution environment itself matters.

A simplified execution path looks like:

User submission
      |
      v
Judge0 API
      |
      v
Worker
      |
      v
Isolate
      |
      v
Compiler
      |
      v
Generated executable
      |
      v
Isolated execution

If the compiler works but the sandbox environment doesn't behave correctly, Judge0 still isn't ARM64-compatible.

And this is one reason I don't think it is accurate to describe ARM64 support as simply:

docker buildx build --platform linux/arm64

That command can produce an ARM64 image.

It does not prove that the application inside the image is correct.


Why --platform=linux/arm64 Is Not a Magic Fix

Docker makes multi-platform builds look deceptively simple.

For example:

docker buildx build \
    --platform linux/amd64,linux/arm64 \
    -t myimage:latest \
    --push .

For a straightforward application, this can be enough.

But there are actually three different questions:

Question 1: Can I build the image?

Docker build

Question 2: Can the image start?

Container runtime

Question 3: Does the application behave correctly?

Application
+
dependencies
+
sandbox
+
native binaries
+
architecture-specific behavior

For Judge0, the third question is the difficult one.

A successful Docker build would not automatically demonstrate that:

  • every language runtime works
  • every compiler produces correct binaries
  • native dependencies behave correctly
  • sandbox limits are enforced correctly
  • submitted programs execute correctly
  • language-specific tests pass
  • ARM64 behavior matches AMD64 behavior

So the correct definition of ARM64 support should be closer to:

A reproducible ARM64 image plus validated compiler/runtime coverage plus validated sandbox behavior.

Not simply:

Docker image successfully built.


What My Investigation Changed About the Question

Initially, I was asking:

"Why doesn't Judge0 support ARM64?"

After investigating the architecture, I think the better question is:

"What would Judge0 have to validate before it could officially claim ARM64 support?"

That is a much more useful engineering question.

The answer is not one Dockerfile change.

It is a compatibility matrix.

Something like:

ComponentAMD64ARM64What needs verification
Judge0 APIYesNeeds validationApplication/runtime dependencies
Compiler imageYesNeeds new imageBase image + binaries
GCC versionsYesNeeds validationCompiler builds + generated code
ClangYesNeeds validationCompiler/runtime behavior
Python versionsYesNeeds validationRuntime + native extensions
RubyYesNeeds validationRuntime + native dependencies
Node.jsYesNeeds validationRuntime + native modules
RustYesNeeds validationToolchain + target support
JavaYesNeeds validationJDK architecture
Other languagesYesNeeds validationIndividual toolchains
IsolateYesNeeds validationSandbox behavior
Full Judge0 stackYesNeeds end-to-end validationIntegration testing

This is the key difference between architecture support and architecture availability.


Judge0 vs Nife vs Vercel vs Netlify vs Cloudflare

This is where my investigation became especially interesting.

At first glance, it might seem strange that platforms such as Nife, Vercel, Netlify, and Cloudflare can deploy applications across modern infrastructure while Judge0 has a much more complicated ARM64 story.

But these platforms are solving different problems.

Here is the comparison I found useful.

Judge0NifeVercelNetlifyCloudflare
Primary purposeCode executionApplication/infrastructure deploymentApplication deploymentWeb/app deploymentEdge application runtime
Typical workloadCompile and execute submitted codeContainers, apps, sites, databases, VMs/infrastructureWeb apps and functionsSites and applicationsWorkers/edge applications
Infrastructure controlApplication-specificHighManagedManagedHighly managed
VM provisioningNoYesNoNoNo
Database provisioningSupporting component, not primary purposeYesIntegrations/servicesIntegrations/servicesStorage/database products
Static websitesNot primary purposeYesYesYesYes
Docker workloadsCore technologyYesDifferent deployment modelDifferent deployment modelDifferent container/runtime models
Multi-architecture challengeInside the execution environmentDepends on image and target infrastructurePlatform abstracts much of itPlatform abstracts much of itPlatform abstracts runtime architecture

The point is not that one platform is "better."

The point is that the architecture boundary is different.


Nife: The Infrastructure Lens

This is where Nife became particularly relevant to my investigation.

Nife is not simply a static-site deployment service.

Its platform supports application deployment, Docker workloads, sites, databases, virtual machines, Kubernetes environments, and infrastructure management. The current documentation explicitly separates application, standard, site, and database deployment types, and also documents virtual machines and Kubernetes infrastructure.

Nife can deploy applications from Git, Docker images, or source, while also providing infrastructure control across cloud and other environments.

That makes Nife useful as a lens for understanding the Judge0 problem.

Suppose I have:

Judge0 Docker image
        |
        v
Nife
        |
        v
Infrastructure

Nife can provide the deployment and infrastructure layer.

But that does not automatically transform an AMD64 Judge0 image into an ARM64 Judge0 image.

The architecture compatibility still belongs to the workload.

If my Judge0 image contains AMD64 binaries:

Judge0 image
    |
    +-- AMD64 executable
    +-- AMD64 compiler
    +-- AMD64 runtime
    +-- sandbox

then putting that image onto an ARM64 machine does not make those binaries ARM64.

This is an important distinction:

A deployment platform can make infrastructure deployment easier without changing the architecture requirements of the application being deployed.


Nife Can Deploy More Than Just Websites

This also changes the comparison with Vercel and Netlify.

A typical comparison often looks like:

Nife vs Vercel vs Netlify

as if all three were simply frontend deployment platforms.

That misses part of what Nife provides.

With Nife, the deployment surface includes:

Applications
Containers
Sites / static websites
Databases
Virtual Machines
Kubernetes infrastructure
Storage

The documentation also describes deploying Docker applications and managing infrastructure such as VMs, databases, Kubernetes clusters, and storage.

So when I compare Nife with Vercel, Netlify, or Cloudflare in this article, I'm not saying they are identical platforms.

They aren't.

The comparison is useful because they sit at different levels of the infrastructure stack.


Vercel: Architecture Is Exposed at the Function Layer

Vercel is much closer to a managed application/runtime platform.

Vercel Functions support managed runtimes such as Node.js, Python, Ruby, and Go, and Vercel's Build Output API exposes architecture as a property that can be x86_64 or arm64, with x86_64 documented as the default.

That is interesting because Vercel doesn't need every customer to manually build and maintain an entire operating-system-level compiler distribution.

The platform owns the execution environment.

The developer generally supplies application code and dependencies.

That makes architecture a much more contained concern.


Netlify: Build Environment vs Runtime

Netlify also provides a managed build system.

When a build is triggered, Netlify starts a virtual machine from a build image containing preinstalled tools and configuration. Its documentation also describes build commands and publish directories that define what gets built and what gets deployed.

The important distinction is:

Source code
    |
    v
Managed build environment
    |
    v
Build output
    |
    v
Deployment

The platform is managing the build environment.

Judge0 is doing something fundamentally different:

User source code
    |
    v
Judge0
    |
    +-- select compiler
    +-- compile
    +-- sandbox
    +-- execute
    +-- enforce limits
    |
    v
Result

The compiler infrastructure is not merely a build step.

It is part of the product.


Cloudflare: A Different Kind of Sandbox

Cloudflare provides another interesting contrast.

Cloudflare Workers uses the V8 engine and isolates for executing user code. Cloudflare describes Workers as running code inside lightweight isolates rather than creating a virtual machine for every function.

That gives us another example of why "sandbox" does not always mean the same thing.

Judge0:

Linux process
      |
      v
Isolate
      |
      v
Compiler
      |
      v
User executable

Cloudflare Workers:

Cloudflare runtime
      |
      v
V8
      |
      v
Isolate
      |
      v
JavaScript / supported Worker code

These are fundamentally different execution models.

Cloudflare does not need to provide a GCC 7.4 compiler, GCC 8.3 compiler, GHC, DMD, Mono, Ruby, Python, and dozens of other toolchains inside every Worker runtime.

That is one reason the architecture problem looks very different.


The Important Difference: Deployment Platform vs Code Execution Platform

After looking at all of these systems, this became the clearest way for me to explain the difference.

Typical deployment platform

The workflow looks approximately like:

Developer code
      |
      v
Build
      |
      v
Application artifact
      |
      v
Deployment platform
      |
      v
Users

Architecture compatibility matters, but the platform can abstract much of it.


Judge0

Judge0 looks more like:

User source code
      |
      v
Judge0 API
      |
      v
Language selection
      |
      v
Compiler / interpreter
      |
      v
Native executable
      |
      v
Sandbox
      |
      v
CPU / kernel
      |
      v
Execution result

The architecture is part of the execution pipeline.

That is the key insight.


Why ARM64 Is More Difficult for Judge0

The problem can be summarized as a dependency chain.

ARM64 host
    |
    +-- Linux kernel
    |
    +-- Container runtime
    |
    +-- Judge0
          |
          +-- Isolate
          |
          +-- Compiler toolchains
          |      |
          |      +-- GCC
          |      +-- Clang
          |      +-- GHC
          |      +-- DMD
          |      +-- Mono
          |      +-- etc.
          |
          +-- Language runtimes
                 |
                 +-- Python
                 +-- Ruby
                 +-- Node
                 +-- Java
                 +-- Go
                 +-- Rust
                 +-- etc.

Every native component becomes part of the ARM64 compatibility question.

That is why the phrase:

"Just make a multi-architecture Docker image"

doesn't fully capture the work involved.


What Would Be Required for Proper Judge0 ARM64 Support?

If I were approaching this as an engineering project, I would break it into stages.

1. Build an ARM64 base image

First:

Ubuntu/Debian
      |
      v
ARM64 base image

Then verify that all system packages required by Judge0 are available.


2. Build or obtain ARM64 versions of every required toolchain

The next layer is:

ARM64
 |
 +-- GCC
 +-- Clang
 +-- Python
 +-- Ruby
 +-- Node
 +-- Java
 +-- Go
 +-- Rust
 +-- Haskell
 +-- Erlang
 +-- Mono
 +-- etc.

The important word here is every.

It isn't enough for five of the languages to work.

If Judge0 advertises a language, that language needs to be tested.


3. Validate native dependencies

Many language runtimes and compilers depend on native libraries.

So I would test:

compiler
   |
   +-- libc
   +-- libstdc++
   +-- GMP
   +-- MPFR
   +-- zlib
   +-- OpenSSL
   +-- other native dependencies

depending on the particular toolchain.


4. Validate Isolate

Then the sandbox needs independent testing.

I would test:

CPU limits
Memory limits
Process limits
Execution timeout
Filesystem restrictions
Network restrictions
Signal handling
Process cleanup
Concurrent executions

And I would run these tests on both architectures.


5. Compare behavior

The important question isn't just:

Does it start?

It is:

Does the same submission behave correctly?

For example:

Test case                 AMD64       ARM64
--------------------------------------------
C compilation              PASS        PASS
C++ compilation            PASS        PASS
Python execution           PASS        PASS
Rust compilation           PASS        PASS
Timeout enforcement        PASS        PASS
Memory enforcement         PASS        PASS
Process isolation          PASS        PASS
Filesystem restriction     PASS        PASS
Concurrent submissions     PASS        PASS

Only after this kind of matrix passes would I be comfortable calling it production-ready ARM64 support.


What I Would Test Before Calling Judge0 ARM64-Compatible

My test plan would look something like this.

Architecture tests

uname -m
docker version
docker info

Confirm:

aarch64
linux/arm64

Image tests

docker buildx imagetools inspect <image>

Confirm the expected architectures are published.


Language tests

Run representative submissions for every supported language.

For example:

C
C++
Java
Python
Ruby
Go
Rust
JavaScript
TypeScript
C#
Haskell
Erlang
PHP

Resource tests

Test:

CPU limit
Memory limit
Wall-clock timeout
Process limit

Security tests

Test:

Filesystem isolation
Network restrictions
Process isolation
Privilege boundaries
Sandbox escape attempts

Regression tests

The same test suite should run against:

AMD64
ARM64

and results should be compared.

This is where I think the real engineering cost lies.


What Are the Practical Options Today?

Based on the current official images I investigated, the official Judge0 images I checked are AMD64 images.

That leaves several practical approaches.

Option 1: Keep Judge0 on AMD64

This is the simplest architecture choice.

Judge0
   |
   v
AMD64 infrastructure

You avoid introducing an unofficial architecture build into the production execution path.


Option 2: Build your own ARM64 variant

You can investigate building the compiler image yourself.

Conceptually:

docker buildx build \
    --platform linux/arm64 \
    -t my-judge0:arm64 \
    .

But the important part is everything that comes after the build.

You need to test the resulting image rather than assuming that a successful build means Judge0 is supported.


What About AWS Graviton?

This was one of the reasons I started the investigation in the first place.

AWS Graviton provides ARM64 compute, so the infrastructure side is attractive.

But the architecture decision should be driven by the workload.

If the workload is:

Node.js application
Python application
Go application
Docker application with ARM64 image

ARM64 can be relatively straightforward when all required dependencies support it.

Judge0 is different because the application includes the toolchains used to compile and execute other programs.

So the question is not:

"Is Graviton compatible with Docker?"

It is.

The question is:

"Is this particular Judge0 execution environment compatible with ARM64?"

That is a much more specific question.


Where Nife Fits Into This

This is where my investigation connected back to Nife.

Nife is a deployment and infrastructure platform rather than a compiler execution environment.

You can use Nife to deploy:

Applications
Containers
Websites / static sites
Databases
Virtual machines
Kubernetes infrastructure

and manage workloads across connected infrastructure.

That means Nife can be the layer through which I deploy an application, while the application's own architecture requirements remain the application's responsibility.

For example:

                 Nife
                  |
       +----------+----------+
       |          |          |
     AWS        GCP        Other
       |
    ARM64
       |
    Container
       |
   Judge0 image

If the Judge0 image is AMD64:

AMD64 image
      |
      X
ARM64 host

Nife cannot solve that simply by deploying it.

But if I have a validated ARM64 Judge0 image:

ARM64 Judge0 image
        |
        v
ARM64 infrastructure
        |
        v
Nife

then Nife becomes the deployment and infrastructure layer.

That distinction is important.


Nife vs Vercel vs Netlify vs Cloudflare: What I Actually Learned

The comparison isn't really about who "supports ARM64 better."

It is about where architecture complexity lives.

Nife

Nife exposes more infrastructure.

You can deploy applications and containers, but you can also manage databases, sites, VMs, Kubernetes infrastructure, and other resources.

Therefore:

More infrastructure control
        =
More responsibility for workload compatibility

Vercel

Vercel abstracts much of the infrastructure.

Developers work primarily with application runtimes and deployment primitives.

Vercel explicitly exposes architecture for functions as x86_64 or arm64, which shows that architecture still exists underneath the abstraction—but the platform manages much more of the runtime environment.


Netlify

Netlify provides managed build environments and deployment workflows.

The platform starts a build environment, runs the configured build, and deploys the resulting output.

Again, architecture is present underneath the system, but developers generally don't maintain a giant multi-language compiler image like Judge0.


Cloudflare

Cloudflare Workers uses a V8 isolate-based execution model.

The platform controls the runtime and the isolation mechanism rather than asking every developer to maintain a complete operating-system-level sandbox for arbitrary native executables.


The Real Comparison

I found this model more useful than a traditional feature comparison:

                 CONTROL
                    ^
                    |
                    |
        Nife       |
                    |
                    |
                    |
      Vercel ------+------ Netlify
                    |
                    |
               Cloudflare
                    |
                    v
              MORE ABSTRACTION

And Judge0 is different because its core workload is:

SOURCE CODE
    |
    v
COMPILER
    |
    v
EXECUTABLE
    |
    v
SANDBOX
    |
    v
RESULT

It isn't simply a deployment artifact.


One More Important Discovery: ARM64 Does Not Mean "Everything Is Automatically Faster or Cheaper"

One thing I would avoid in an ARM64 migration article is saying:

"ARM64 is cheaper, therefore we should move Judge0."

That isn't enough.

The actual calculation is:

Infrastructure cost
+
build cost
+
CI cost
+
testing cost
+
maintenance cost
+
engineering time

For a normal application, the architecture migration may be relatively small.

For Judge0, the engineering cost of validating a large compiler matrix can become a significant part of the decision.

So I would evaluate:

AMD64 infrastructure cost
        vs
ARM64 infrastructure cost
        +
ARM64 engineering effort
        +
ongoing maintenance

That is a much more useful way to make the decision.


What This Investigation Taught Me

My initial assumption was:

"Judge0 doesn't support ARM64 because the Docker image is AMD64."

That statement is technically true as far as the official images I inspected go, but it isn't the complete story.

The deeper problem is:

Judge0's architecture is part of its execution environment.

The official compiler image packages a large collection of language toolchains and runtimes, and the Judge0 API image builds on that compiler image.

So supporting ARM64 means validating much more than the API.

It means validating:

Docker image
      +
base OS
      +
native libraries
      +
compiler toolchains
      +
language runtimes
      +
Isolate
      +
resource limits
      +
security model
      +
actual submitted programs

That is why I don't think the correct conclusion is:

"Judge0 needs a different Docker flag."

The better conclusion is:

Judge0 needs an ARM64-compatible execution stack.

And that is a much larger engineering problem.


FAQ

Can I run the official Judge0 image directly on an ARM64 server?

The official Judge0 images I inspected are published as linux/amd64, so you should not assume that they are native ARM64 images.

You may be able to use emulation in some environments, but that is different from having a native ARM64 image.


Does Docker support ARM64?

Yes.

Docker itself supports multi-platform images and ARM64 hosts.

The problem is not Docker's inability to run ARM64 containers.

The problem is whether the software inside the container supports ARM64.


Can I use Docker Buildx?

Yes.

For example:

docker buildx build \
    --platform linux/arm64 \
    -t my-judge0:arm64 \
    .

But a successful image build should be treated as the beginning of validation, not the end.


Why can't I just cross-compile everything?

Cross-compilation can help with some components, but Judge0 isn't one compiler.

You still have to produce and test the complete runtime environment, including language-specific dependencies and the sandbox.

Cross-compiling a binary is not equivalent to proving the complete execution environment works correctly on ARM64.


Does Apple Silicon have the same problem?

Apple Silicon is also ARM64, so the same fundamental architecture question applies.

Docker Desktop may use emulation depending on the image and configuration, which can sometimes hide architecture incompatibilities.

For a production ARM64 deployment, I would test on actual Linux ARM64 infrastructure.


Does AWS Graviton solve the problem?

No.

Graviton provides ARM64 compute.

It does not automatically convert an AMD64 container into a native ARM64 application.

The application image and all required components still need to support ARM64.


Can Nife deploy Judge0?

Nife can deploy applications and Docker workloads, but the architecture compatibility of the Judge0 image remains a property of the image and target infrastructure.

A deployment platform does not automatically change the CPU architecture of the binaries inside your container. Nife's platform supports Docker/application deployments as well as broader infrastructure such as VMs, databases, Kubernetes, and sites.


Does Vercel solve the same problem as Judge0?

No.

Vercel provides managed application runtimes and functions. Its function model supports architecture selection, including x86_64 and arm64.

Judge0 is specifically designed to compile and execute submitted programs using a broad collection of compiler and runtime environments.

They have different architecture requirements because they solve different problems.


Is Cloudflare Workers equivalent to Judge0's sandbox?

No.

Cloudflare Workers uses V8 isolates as its execution model. Judge0 uses a Linux sandboxing approach around native compiler/runtime execution.

Both involve isolation, but they are not the same architecture.


Conclusion

The most useful conclusion from my investigation is simple:

ARM64 support is not one problem.

For a normal application:

Application
    |
    v
ARM64 container

For Judge0:

Judge0
   |
   +-- API
   |
   +-- compiler image
   |
   +-- dozens of language toolchains
   |
   +-- native dependencies
   |
   +-- Isolate
   |
   +-- resource controls
   |
   +-- untrusted executable code
   |
   v
ARM64 Linux

That is why a Docker architecture flag isn't enough.

The interesting part of this investigation wasn't discovering that the official Judge0 image is AMD64.

It was discovering why that architecture boundary exists.

Judge0 isn't just a web application that happens to run in Docker.

It is an execution environment for other programs.

And once you look at it that way, ARM64 compatibility becomes a compiler, runtime, sandbox, testing, and infrastructure problem—not simply a container problem.


Further Reading


Nife: Deploy applications, containers, databases, websites, and infrastructure from one platform.

Get started with Nife

© Nife — Deploy anything, anywhere.

From the team at Nife

Deploy your next app in minutes, not days.

Nife is a multi-cloud edge platform that lets you deploy, scale, and manage applications globally without the infrastructure headache.