EAP 8 build on disconnected environment
Environment
- Red Hat Enterprise Application Platform
- 8.x
- Galleon
- Red hat OpenShift Container Platform (OCP)
- 4.x
Issue
- How to build EAP 8 inside a disconnected environment?
- Build EAP 8 without internet
Resolution
EAP 8 has required access for its build. There are a few alternatives however:
| Alternative | Pro | Cons |
|---|---|---|
1- User could specify this local maven repository as a maven repository that is actually on the local file system. That is done in your settings using the URL file://... | Maven settings and local download is required | Requires the maven repository and set this on the build |
| 2- Do a full build locally from scratch, then copy all in your new builder image, which is then imported to a disconnected environment for runtime build (two stage build) | Disconnected environment must be able to build | Requires moving the image from one connect environment to disconnect environment, to be built |
| 3- Do a full build (builder and runtime) in a non-disconnected environment and then import the resulting image into the disconnected environment | Connected environment does the full build, disconnected environment receives the full built image | Requires moving the image from one connect enviroment to the disconnected environment, to be run. |
Attention when using ENV GALLEON_PROVISION_CHANNELS org.jboss.eap.channels:eap-8.0, in case a newnew manifest is released so all jars would be fetched again. Therefore the user should specify a manifest version to be sure that all that is in the cache is what s going to be used at build time, example: org.jboss.eap.channels:eap-8.0:1.5.1.GA-redhat-00002, so specifying the full version in length.
More details on the procedure above: do a full build using the pom.xml file that you would use during s2i. Use a scratch m2 local cache, (specify -Dmaven.repo.local=your_path), Then put this generated local cache in the image - copy it directly to local or into an image.
Example - builder container with dependencies inside
The following Dockerfile:
# Use EAP 8 Builder image to create a JBoss EAP 8 server with its default configuration
FROM registry.redhat.io/jboss-eap-8/eap8-openjdk17-builder-openshift-rhel8:latest AS builder
# With these 3 environments variables, a JBoss EAP 8 server is provisioned with the "same"
RUN echo $MAVEN_OPTS
RUN echo $MAVEN_OPTS_APPEND
RUN mkdir -p /tmp/m2
ENV MAVEN_OPTS_APPEND -Dmaven.repo.local=/tmp/m2
# cloud configuration that EAP standalone.xml
ENV GALLEON_PROVISION_FEATURE_PACKS org.jboss.eap:wildfly-ee-galleon-pack,org.jboss.eap.cloud:eap-cloud-galleon-pack
ENV GALLEON_PROVISION_LAYERS cloud-default-config
ENV GALLEON_PROVISION_CHANNELS org.jboss.eap.channels:eap-8.0
# ENV MAVEN_MIRROR_URL <maven mirror URL if needed>
RUN /usr/local/s2i/assemble
RUN ls /tmp/artifacts/m2
RUN ls /tmp/artifacts/m2/xml-resolver/xml-resolver/1.2.0.redhat-12/
Will return the following output - which is the list of jars:
$ podman build --no-cache --tag eap8:disconnected --authfile ../../pull-secret.txt -f ./Dockerfile
[1/2] STEP 1/11: FROM registry.redhat.io/jboss-eap-8/eap8-openjdk17-builder-openshift-rhel8:latest AS builder
...
[1/2] STEP 6/11: ENV GALLEON_PROVISION_FEATURE_PACKS org.jboss.eap:wildfly-ee-galleon-pack,org.jboss.eap.cloud:eap-cloud-galleon-pack
--> 33f2516817ca
[1/2] STEP 7/11: ENV GALLEON_PROVISION_LAYERS cloud-default-config
--> 754bcfeae85e
[1/2] STEP 8/11: ENV GALLEON_PROVISION_CHANNELS org.jboss.eap.channels:eap-8.0
--> 5a238f9bbc73
[1/2] STEP 9/11: RUN /usr/local/s2i/assemble
INFO You have activated legacy s2i workflow by setting GALLEON_PROVISION_FEATURE_PACKS or GALLEON_USE_LOCAL_FILE env variable.
INFO Provisioning
INFO Provisioning WildFly server...
INFO Performing Maven build in /opt/jboss/container/wildfly/s2i/galleon/provisioning/generic_layers
INFO Using MAVEN_OPTS -XX:MaxRAMPercentage=80.0 -XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:+ExitOnOutOfMemoryError -XX:MaxRAMPercentage=25.0
INFO Using Apache Maven 3.8.5 (Red Hat 3.8.5-6)
Maven home: /usr/share/maven
Java version: 17.0.13, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-17-openjdk-17.0.13.0.11-3.el8.x86_64
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "6.8.9-100.fc38.x86_64", arch: "amd64", family: "unix"
INFO Running 'mvn -e -Popenshift -DskipTests -Dcom.redhat.xpaas.repo.redhatga -Dfabric8.skip=true -Djkube.skip=true --batch-mode -Djava.net.preferIPv4Stack=true -s /tmp/galleon-settings.xml -Dmaven.repo.local=/tmp/artifacts/m2 package'
...
...
RUN ls /tmp/artifacts/m2
com commons-beanutils commons-cli commons-codec commons-collections commons-io commons-logging de gnu io jakarta jboss joda-time net org wsdl4j xml-resolver
...
[1/2] STEP 11/11: RUN ls /tmp/artifacts/m2/xml-resolver/xml-resolver/1.2.0.redhat-12/
_remote.repositories
xml-resolver-1.2.0.redhat-12.jar <--------
xml-resolver-1.2.0.redhat-12.jar.sha1
To copy from builder to runtime, one can use COPY --from=builder --chown=jboss:root /tmp/artifacts/m2 /tmp/m2:
[2/2] STEP 4/7: COPY --from=builder --chown=jboss:root /tmp/artifacts/m2 /tmp/m2
--> eb4e94fcec5c
[2/2] STEP 5/7: RUN ls /tmp/m2
com
commons-beanutils
commons-cli
commons-codec
commons-collections
commons-io
commons-logging
de
gnu
io
jakarta
jboss
joda-time
net
org
wsdl4j
xml-resolver
Therefore, as presented above, it could be possible to have a builder image with the dependencies:
- Dockerfile ': Builder -> Dependency Builder
- Dockerfile ": Dependency Builder -> Runtime
So then the dependencies present in the Dependency Builder can be fetched or the Dependency Builder image itself can be imported to the disconnected environment, basically using two Dockerfiles: Dockerfile' and Dockerfile".
Custom settings.xml
It is possible to set a custom settings.xml or provide a few custom environment variables, for example MAVEN_MIRROR_URL. However MAVEN_MIRROR_USER and MAVEN_MIRROR_PASSWORD do not exist in the S2I build.
Root Cause
As explained on EAP 8 Runtime vs Builder image container images tools in OpenShift,
EAP 8 build requires access to the Redhat GA and central repositories for the jars build, given EAP is an umbrella based on several other jars/projects.
This requirement was added to give more flexibility to EAP 8 in terms of patching fixes on subsystems' jars given the patches don’t need to go through a new image process every time and get updated immediately upon building. However, this functionality added the requirement for fetching those dependencies and this solution EAP 8 build on disconnected environment, present alternatives for disconnected environments.
Notes for fully disconnected environment builds:
- Maven builds will require all dependency to be available at runtime - without internet access.
- Some dependencies come from RH repository, however Maven central is used. Therefore, it is expected to be mirrored too.
- The Maven mirroring process can be not-trivial and it is not supported by Red Hat directly.
- To facilitate the build, the user can be in a connected environment and then mirror all the dependencies listed using the debug logs, as detailed here.
Corollary from above
Given the notes above, in this case other options can be detailed below - also on the Resolution section above:
Option 2- build outside and import that imageOption 3- build with two stage as above
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.