Dockerfile reference

How the Dockerfile pattern works and how to extend it.

Single extension

Copy the snippet from any extension's Overview tab. It is always in this form:

FROM quay.io/keycloak/keycloak AS builder
COPY --from=kcer.dev/providers/keycloak-home-idp-discovery:v26.1.1 /providers/ /opt/keycloak/providers/
RUN /opt/keycloak/bin/kc.sh build

FROM quay.io/keycloak/keycloak
COPY --from=builder /opt/keycloak/ /opt/keycloak/
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]
CMD ["start", "--optimized"]

Multiple extensions

Add one COPY --from= line per extension, before the RUN kc.sh build step. The pattern is identical regardless of how many extensions you include.

FROM quay.io/keycloak/keycloak AS builder
COPY --from=kcer.dev/providers/keycloak-home-idp-discovery:v26.1.1 /providers/ /opt/keycloak/providers/
COPY --from=kcer.dev/providers/keycloak-magic-link:v2.0.0 /providers/ /opt/keycloak/providers/
RUN /opt/keycloak/bin/kc.sh build

FROM quay.io/keycloak/keycloak
COPY --from=builder /opt/keycloak/ /opt/keycloak/
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]
CMD ["start", "--optimized"]

What each stage does

builder stage

Starts from the official Keycloak image. Each COPY --from= pulls a minimal provider image (published by this registry) and copies the JAR into /opt/keycloak/providers/. kc.sh build then augments and optimises Keycloak's classpath for the installed providers — this is required for the --optimized start flag.

final stage

Starts from a fresh Keycloak image and copies in only the built output. The build tooling and provider images never end up in your running container.

How provider images work

When this registry syncs a new extension version, it automatically builds and publishes a minimal OCI image containing only the JAR file at /providers/. The image tag is the exact extension version, so pinning is automatic. Images are public and free to pull with no rate limits.