////
This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
= Container Images

include::./attributes.adoc[]

Quarkus provides extensions for building (and pushing) container images. Currently it supports:

- <<#jib,Jib>>
- <<#docker,Docker>>
- <<#s2i,S2I>>
- <<#buildpack,Buildpack>>

== Container Image extensions

[#jib]
=== Jib

The extension `quarkus-container-image-jib` is powered by https://github.com/GoogleContainerTools/jib[Jib] for performing container image builds.
The major benefit of using Jib with Quarkus is that all the dependencies (everything found under `target/lib`) are cached in a different layer than the actual application making rebuilds really fast and small (when it comes to pushing).
Another important benefit of using this extension is that it provides the ability to create a container image without having to have any dedicated client side tooling (like Docker) or running daemon processes (like the Docker daemon)
when all that is needed is the ability to push to a container image registry.

To use this feature, add the following extension to your project:

:add-extension-extensions: container-image-jib
include::includes/devtools/extension-add.adoc[]

WARNING: In situations where all that is needed to build a container image and no push to a registry is necessary (essentially by having set `quarkus.container-image.build=true` and left `quarkus.container-image.push` unset - it defaults to `false`), then this extension creates a container image and registers
it with the Docker daemon. This means that although Docker isn't used to build the image, it is nevertheless necessary. Also note that using this mode, the built container image *will*
show up when executing `docker images`.

==== Including extra files

There are cases when additional files (other than ones produced by the Quarkus build) need to be added to a container image.
To support these cases, Quarkus copies any file under `src/main/jib` into the built container image (which is essentially the same
idea that the Jib Maven and Gradle plugins support).
For example, the presence of `src/main/jib/foo/bar` would result in  `/foo/bar` being added into the container filesystem.

==== JVM Debugging

There are cases where the built container image may need to have Java debugging conditionally enabled at runtime.

When the base image has not been changed (and therefore `ubi8/openjdk-11-runtime` or `ubi8/openjdk-17-runtime` is used), then the `quarkus.jib.jvm-arguments` configuration property can be used in order to
make the JVM listen on the debug port at startup.

The exact configuration is:

[source,properties]
----
quarkus.jib.jvm-arguments=-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=n\\,address=*:5005
----

Other base images might provide launch scripts that enable debugging when an environment variable is set, in which case you would set than environment variable when launching the container.

Finally, the `quarkus.jib.jvm-entrypoint` configuration property can be used to completely override the container entry point and can thus be used to either hard code the JVM debug configuration or point to a script that handles the details.

[#docker]
=== Docker

The extension `quarkus-container-image-docker` is using the Docker binary and the generated Dockerfiles under `src/main/docker` in order to perform Docker builds.

To use this feature, add the following extension to your project.

:add-extension-extensions: container-image-docker
include::includes/devtools/extension-add.adoc[]

[#s2i]
=== S2I

The extension `quarkus-container-image-s2i` is using S2I binary builds in order to perform container builds inside the OpenShift cluster.
The idea behind the binary build is that you just upload the artifact and its dependencies to the cluster and during the build they will be merged to a builder image (defaults to `fabric8/s2i-java`).

The benefit of this approach, is that it can be combined with OpenShift's `DeploymentConfig` that makes it easy to roll out changes to the cluster.

To use this feature, add the following extension to your project.

:add-extension-extensions: container-image-s2i
include::includes/devtools/extension-add.adoc[]

S2I builds require creating a `BuildConfig` and two `ImageStream` resources, one for the builder image and one for the output image.
The creation of such objects is being taken care of by the Quarkus Kubernetes extension.


[#buildpack]
=== Buildpack

The extension `quarkus-container-image-buildpack` is using buildpacks in order to perform container image builds. 
Under the hood buildpacks will use a Docker daemon for the actual build.
While buildpacks support alternatives to Docker, this extension will only work with Docker.

Additionally, the user will have to configure which build image to use (no default image is provided). For example:

[source,properties]
----
quarkus.buildpack.jvm-builder-image=<jvm builder image>
----

or for native:

[source,properties]
----
quarkus.buildpack.native-builder-image=<native builder image>
----

To use this feature, add the following extension to your project.

:add-extension-extensions: container-image-buildpack
include::includes/devtools/extension-add.adoc[]

NOTE: When using the buildpack container image extension it is strongly advised to avoid adding `quarkus.container-image.build=true` in your properties configuration as it might trigger nesting builds within builds. It's preferable to pass it as an option to the build command instead.

== Building

To build a container image for your project, `quarkus.container-image.build=true` needs to be set using any of the ways that Quarkus supports.

:build-additional-parameters: -Dquarkus.container-image.build=true
include::includes/devtools/build.adoc[]
:!build-additional-parameters:

NOTE: If you ever want to build a native container image and already have an existing native image you can set `-Dquarkus.native.reuse-existing=true` and the native image build will not be re-run.

== Pushing

To push a container image for your project, `quarkus.container-image.push=true` needs to be set using any of the ways that Quarkus supports.

:build-additional-parameters: -Dquarkus.container-image.push=true
include::includes/devtools/build.adoc[]
:!build-additional-parameters:

NOTE: If no registry is set (using `quarkus.container-image.registry`) then `docker.io` will be used as the default.

== Selecting among multiple extensions

It does not make sense to use multiple extension as part of the same build. When multiple container image extensions are present, an error will be raised to inform the user. The user can either remove the unneeded extensions or select one using `application.properties`.

For example, if both `container-image-docker` and `container-image-s2i` are present and the user needs to use `container-image-docker`:

[source,properties]
----
quarkus.container-image.builder=docker
----

== Customizing

The following properties can be used to customize the container image build process.

=== Container Image Options

include::{generated-dir}/config/quarkus-container-image.adoc[opts=optional, leveloffset=+1]

==== Using CI Environments

Various CI environments provide a ready to use container-image registry which can be combined with the container-image Quarkus extensions in order to
effortlessly create and push a Quarkus application to said registry.

For example, https://gitlab.com/[GitLab] provides such a registry and in the provided CI environment,
makes available the `CI_REGISTRY_IMAGE` environment variable
(see GitLab's https://docs.gitlab.com/ee/ci/variables/[documentation]) for more information), which can be used in Quarkus like so:

[source,properties]
----
quarkus.container-image.image=${CI_REGISTRY_IMAGE}
----

NOTE: See xref:config.adoc#combine-property-env-var[this] for more information on how to combine properties with environment variables.

=== Jib Options

In addition to the generic container image options, the `container-image-jib` also provides the following options:

include::{generated-dir}/config/quarkus-container-image-jib.adoc[opts=optional, leveloffset=+1]

=== Docker Options

In addition to the generic container image options, the `container-image-docker` also provides the following options:

include::{generated-dir}/config/quarkus-container-image-docker.adoc[opts=optional, leveloffset=+1]

=== S2I  Options

In addition to the generic container image options, the `container-image-s2i` also provides the following options:

include::{generated-dir}/config/quarkus-container-image-s2i.adoc[opts=optional, leveloffset=+1]
