Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/m1 docker build support #376

Merged
merged 10 commits into from
Oct 7, 2023
Merged

Conversation

vordimous
Copy link
Contributor

@vordimous vordimous commented Aug 21, 2023

Description

The primary issue I found was the eclipse-temurin:20-alpine issue only shows support for the amd64 platform.

These changes are meant to improve the usability and cross-platform support for the zilla docker images.

The cross-platform changes are based on the maven plugin docs to add a property for the supported platforms. I replaced the alpine build image for the eclipse-temurin:20 based on ubuntu:jammy a more suited build environment. The build image doesn't need to be as lean and is best to match the build purpose. This made building on both platforms able to use the same dockerfile. It isn't an industry standard to require apline images for all stages when using multistage builds.

command when running a build on an M1 architecture:
./mvnw -DskipTests clean install -Ddocker.platforms=linux/arm64

I included some metadata I have seen to be best practice. For now, a maintainer label and version env var following the nginx image template. There are other recommended labels, but I didn't want to add too much.

The remaining challenge is when the alpine image copies the necessary binaries, they are not able to be found but the running container. I am not sure if it is an Ubuntu -> Alpine issue or a user ownership issue. If the base image for the app container is ubuntu:jammy, matching the build image, everything works as expected when both build and app images are alpine versions.

Fixes # (issue)

@attilakreiner
Copy link
Contributor

The remaining challenge is when the alpine image copies the necessary binaries, they are not able to be found but the running container. I am not sure if it is an Ubuntu -> Alpine issue or a user ownership issue. If the base image for the app container is ubuntu:jammy, matching the build image, everything works as expected when both build and app images are alpine versions.

I tried this approach and reached the same conclusion, unfortunately it doesn't work this way; the zilla built with zpm on one distro can't be executed on the other. I don't have a deep enough understanding to give a detailed explanation, but I think it has to do with the fact that the files/libraries required to run java are laid out differently on Ubuntu vs Alpine (even when using the same java distro/version).

@vordimous
Copy link
Contributor Author

example of multi OS build management: https://github.com/emqx/emqx-builder

@vordimous vordimous force-pushed the feature/m1-docker-build-support branch from f32114a to d2df9b3 Compare August 29, 2023 20:05
@vordimous
Copy link
Contributor Author

vordimous commented Sep 24, 2023

After looking into how other repos manage this, I believe the solution is to publish a multi-platform image as the base image tagged with the semver [x.x.x]. This would mean using the base images from this PR ubuntu:jammy as the default images.

Then users who want to use the alpine version, which eclipse-temurin:alpine is only linux/x86_64 compatible, could still use that build specifying the alpine suffix [x.x.x-alpine]. There are M1 alpine images but practically alpine is only needed on hosted servers which don't use arm so we can cross that bridge later if we want.

Implementing that would mean keeping both versions of docker files in this PR and specifying one as the default image and one as the alpine image. Then when building the default image, we would specify both platforms -Ddocker.platforms=linux/arm64,linux/x86_64, and when building the alpine version only the -Ddocker.platforms=linux/x86_64

@jfallows @attilakreiner what do you think?

@jfallows
Copy link
Contributor

This may also help if we decide to perform release of different platform docker images via GitHub Actions workflows.

github/roadmap#528

- separate jammy and alpine
- add zilla version as env var
- add the docker platform to properties
- don't need to use alpine for build
@vordimous vordimous force-pushed the feature/m1-docker-build-support branch from d2df9b3 to d8dd58b Compare September 28, 2023 15:55
separate alpine base image from the default image and add more tagging options
@vordimous
Copy link
Contributor Author

arm support for alpine discussion: adoptium/containers#158

@vordimous
Copy link
Contributor Author

vordimous commented Sep 28, 2023

Attempted the suggested alternate image bellsoft/liberica-openjdk-alpine-musl:20 and ran into a module not found error: Module jdk.jdwp.agent not found

Looking at how adoptium builds their alpine images, they use their own java binaries and don't have an aarch64_alpine binary built. https://github.com/adoptium/temurin20-binaries/releases
In the dockerfile:line 44 there is a check to prevent builds on alpine for arch.

@vordimous vordimous force-pushed the feature/m1-docker-build-support branch from 4bf7f95 to d8dd58b Compare September 28, 2023 21:27
pom.xml Outdated Show resolved Hide resolved
pom.xml Outdated Show resolved Hide resolved
pom.xml Outdated Show resolved Hide resolved
@vordimous
Copy link
Contributor Author

vordimous commented Oct 2, 2023

@jfallows I think this PR is ready for review, but the builds are failing. I am not sure what to look for since the build works locally. Please advise.

Also my maven skills are pretty rusty so I think there is something missing her to make sure both release and alpine profiles are built.

@vordimous
Copy link
Contributor Author

The docker-maven-plugin docs specify the need to create a multi-platform buildx builder named maven so it will use that to compile the different platform layers. Here is the command I used:

docker buildx create --platform linux/arm64,linux/amd64 --name maven --bootstrap --use

local build and deploy to personal docker hub worked as intended: https://hub.docker.com/repository/docker/vordimous/zilla/tags?page=1&ordering=last_updated

./mvnw -DskipTests -Dmaven.deploy.skip clean deploy -U -Drelease

@vordimous
Copy link
Contributor Author

The incubator edge alternate tag is to match a more docker friendly naming scheme for the latest development work.

I am not in love with having the incubator-alpine directory but at least it is consistent with release? Local builds with then have both image version options if needed:
image

Any ideas on how to setup the pom differently are welcome.

cloud/docker-image/src/main/docker/incubator/Dockerfile Outdated Show resolved Hide resolved
cloud/docker-image/src/main/docker/incubator/Dockerfile Outdated Show resolved Hide resolved
pom.xml Outdated Show resolved Hide resolved
cloud/docker-image/pom.xml Outdated Show resolved Hide resolved
cloud/docker-image/pom.xml Outdated Show resolved Hide resolved
cloud/docker-image/pom.xml Outdated Show resolved Hide resolved
cloud/docker-image/pom.xml Outdated Show resolved Hide resolved
@vordimous vordimous marked this pull request as ready for review October 6, 2023 23:34
@jfallows jfallows merged commit cc14195 into develop Oct 7, 2023
2 of 8 checks passed
aDaemonThread pushed a commit to aDaemonThread/zilla that referenced this pull request Oct 25, 2023
* feature/m1-docker-build-support

- separate jammy and alpine
- add zilla version as env var
- add the docker platform to properties
- don't need to use alpine for build

* docker image tagging options

separate alpine base image from the default image and add more tagging options

* set the version env var in the alpine build

* remove the suffix for local build

* make version tagging more explicit for each profile

* move the alpine specific builds into the docker-image module

* reduce the folder complexity and add child pom placeholders

* revert the docker-image pom to develop

* Use buildx for multi-arch images, build alpine image for release only

* Move inline assembly to descriptor file and reference from alpine image

---------

Co-authored-by: John Fallows <john.r.fallows@gmail.com>
@jfallows jfallows deleted the feature/m1-docker-build-support branch February 7, 2024 00:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants