Back to Blog
Tutorial11 min read2026-07-02

How to Deploy a Quarkus Java App to Production

Deploy a Quarkus app to the cloud with JVM or native images, fast startup, health endpoints from SmallRye, and container-aware JVM settings — plus a Git-based deploy.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Quarkus was built for the container era: fast boot, low memory, and an optional native build via GraalVM that starts in milliseconds. Getting those benefits in production means choosing between the JVM and native paths, exposing the right health endpoints, and making the JVM respect container limits. Here's the full picture.

JVM vs native: pick deliberately

Quarkus can run as a regular JVM application or compile to a native executable with GraalVM.

JVM modeNative mode
Build timeFastSlow (minutes)
Startup~1 s~10-50 ms
Memory (RSS)HigherMuch lower
Peak throughputHighestSlightly lower
Best forMost services, fast CIServerless, scale-to-zero, tiny footprints

For a typical web API deployed continuously, JVM mode is the pragmatic default — fast builds and the JIT eventually gives you the best throughput. Choose native when cold start and memory dominate, such as scale-to-zero workloads.

Building the artifacts

JVM (fast-jar) build:

./mvnw package -DskipTests
# produces target/quarkus-app/quarkus-run.jar

Native build via the container-based GraalVM (no local GraalVM install needed):

./mvnw package -Dnative -Dquarkus.native.container-build=true

Health checks with SmallRye

Add the health extension and Quarkus exposes standard endpoints with no extra code:

./mvnw quarkus:add-extension -Dextensions=smallrye-health

This gives you /q/health/live and /q/health/ready. Point your platform's liveness probe at the first and readiness at the second. If you add the JDBC datasource extension, a database readiness check is wired automatically.

Dockerfiles

Quarkus generates Dockerfiles under src/main/docker/. For JVM fast-jar:

FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/quarkus-app/lib/ /app/lib/
COPY target/quarkus-app/*.jar /app/
COPY target/quarkus-app/app/ /app/app/
COPY target/quarkus-app/quarkus/ /app/quarkus/
EXPOSE 8080
CMD ["java", "-jar", "/app/quarkus-run.jar"]

The layered layout matters: dependencies (lib/) change rarely, so Docker caches that layer and only your application classes re-upload on each build.

For native, the runtime image is tiny:

FROM quay.io/quarkus/quarkus-micro-image:2.0
WORKDIR /app
COPY target/*-runner /app/application
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

Container-aware JVM settings

Modern JVMs respect cgroup limits, but you should still cap the heap relative to the container memory. Rather than hardcoding -Xmx, use a percentage so the same image works across instance sizes:

JAVA_OPTS=-XX:MaxRAMPercentage=75 -XX:+UseG1GC

Leaving headroom (75%, not 100%) avoids the OOM killer terminating your pod, since the JVM uses off-heap memory too.

Configuration

Quarkus binds environment variables to config keys. For a database:

QUARKUS_DATASOURCE_DB_KIND=postgresql
QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://host:5432/db
QUARKUS_DATASOURCE_USERNAME=...
QUARKUS_DATASOURCE_PASSWORD=...

If your platform provides a single DATABASE_URL, map it in application.properties or split it into the JDBC variables above.

Deploying on PandaStack

  1. 1Commit the generated JVM Dockerfile (or the native one if you've chosen native mode).
  2. 2Connect the repo as a container app in the [dashboard](https://dashboard.pandastack.io).
  3. 3PandaStack builds with rootless BuildKit in an ephemeral Kubernetes Job and deploys via Helm with automatic SSL.
  4. 4Attach a managed PostgreSQL database; set the QUARKUS_DATASOURCE_* variables from the injected credentials.
  5. 5Configure probes against /q/health/live and /q/health/ready.

If you run native images on a scale-to-zero free-tier app, Quarkus's millisecond startup makes cold starts nearly invisible — a genuinely good pairing.

References

  • [Quarkus: Container images guide](https://quarkus.io/guides/container-image)
  • [Quarkus: Building native executables](https://quarkus.io/guides/building-native-image)
  • [SmallRye Health in Quarkus](https://quarkus.io/guides/smallrye-health)
  • [JDK container awareness (JEP-aligned docs)](https://docs.oracle.com/en/java/javase/21/docs/specs/man/java.html)

Quarkus plus scale-to-zero is a great combo for cost-efficient Java. Deploy on PandaStack's free tier with a managed database at [dashboard.pandastack.io](https://dashboard.pandastack.io).

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also