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.