Back to Blog
Tutorial10 min read2026-07-01

How to Deploy a Quarkus Java App

Quarkus brings fast startup and low memory to Java. Here's how to deploy it as a JVM container or a GraalVM native image, with a managed Postgres wired in via JDBC.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Quarkus: Java that starts fast

Quarkus was built for the cloud-native, container era. It does ahead-of-time work at build time so the JVM does less at runtime, giving startup times and memory footprints that traditional Spring-on-JVM struggles to match — and it can compile to a GraalVM native image for truly tiny, instant-start binaries. Both deployment modes work well on a container platform; let's cover each.

Step 1: A REST endpoint and config

// GreetingResource.java
@Path("/health")
public class HealthResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Map<String, String> health() {
        return Map.of("status", "ok");
    }
}

Quarkus reads application.properties. Bind the HTTP port to the injected PORT:

# application.properties
quarkus.http.host=0.0.0.0
quarkus.http.port=${PORT:8080}

Step 2: Option A — JVM container

The simplest path is a JVM image. Quarkus generates layered output for good Docker caching:

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"]

Build the app first: ./mvnw package. The layered structure means dependency layers cache between builds.

Step 2: Option B — GraalVM native image

For minimal memory and instant startup (great for scale-to-zero), compile native:

./mvnw package -Dnative -Dquarkus.native.container-build=true
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"]

Native images start in tens of milliseconds and use a fraction of the memory — ideal on the free tier where apps scale to zero on spot nodes. The trade-off is longer build times.

Step 3: Wire a managed Postgres

Add the JDBC extension (quarkus-jdbc-postgresql) and configure the datasource from env. PandaStack injects DATABASE_URL when you attach a managed PostgreSQL — map it to Quarkus's datasource properties:

quarkus.datasource.db-kind=postgresql
quarkus.datasource.jdbc.url=${JDBC_DATABASE_URL}
quarkus.datasource.username=${DB_USER}
quarkus.datasource.password=${DB_PASSWORD}
quarkus.datasource.jdbc.max-size=10

JDBC URLs differ slightly from the standard postgres:// form, so either set JDBC_DATABASE_URL explicitly or translate the injected connection details. Keep max-size below your tier limit (50 free, 300 Pro, 1000 Premium).

Step 4: Schema management

Use Flyway (quarkus-flyway) for migrations, run at startup or as a release step:

quarkus.flyway.migrate-at-start=true

For multi-replica deploys, prefer a dedicated migration job over migrate-at-start to avoid concurrent migration races.

Step 5: Deploy

Connect your repo and push:

git push origin main

The build runs in a rootless BuildKit K8s Job pod, the image ships to Artifact Registry, and Helm deploys it. Live logs stream in real time, automatic SSL covers your domain, and server-side metrics come built in.

Step 6: Health checks and observability

Add quarkus-smallrye-health for liveness/readiness endpoints at /q/health — the orchestrator uses these for rollout. Quarkus also exposes metrics via Micrometer if you want app-level metrics alongside the platform's server-side metrics.

JVM vs native: which to pick

JVM imageNative image
StartupSub-second to secondsTens of ms
MemoryHigherVery low
Build timeFastSlow
Best forSteady traffic, dev velocityScale-to-zero, density

Start with the JVM image for fast iteration; switch to native when you want the cold-start and memory wins on the free tier.

References

  • [Quarkus — Container images](https://quarkus.io/guides/container-image)
  • [Quarkus — Building a native executable](https://quarkus.io/guides/building-native-image)
  • [Quarkus — Datasources](https://quarkus.io/guides/datasource)
  • [Quarkus — SmallRye Health](https://quarkus.io/guides/smallrye-health)

---

Quarkus gives Java a genuinely cloud-native deploy story, especially with native images on scale-to-zero infrastructure. Push one to PandaStack's [free tier](https://dashboard.pandastack.io), attach a managed Postgres, and wire your datasource to the injected connection details.

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also