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

Add custom folders during paketo build #662

Closed
goafabric opened this issue Jun 15, 2022 · 12 comments
Closed

Add custom folders during paketo build #662

goafabric opened this issue Jun 15, 2022 · 12 comments

Comments

@goafabric
Copy link

[note: as requested by https://github.com/paketo-buildpacks/base-builder/issues/484]
I am using paketo build packs with Spring Boot for Native Container Images + Maven.
And because of some limitations of flyway, I have the requirement to add an additional directory with content to the image.
JIb has a property "extraDirectories" to achieve this.
But diving into paketos documentation i could not find something similar.
So is there something that can be activated by some <BP_XX> Parameter ?

Otherwise i have to leverage JIB or a Dockerfile afterwards

Thank you in advance

@dmikusa
Copy link
Contributor

dmikusa commented Jun 15, 2022

I would try setting BP_MAVEN_BUILT_ARTIFACT. Something like target/*.jar <pattern for flyway>.

Configure the built application artifact explicitly. Supersedes $BP_MAVEN_BUILT_MODULE Defaults to target/*.[ejw]ar. Can match a single file, multiple files or a directory. Can be one or more space separated patterns.

Normally, the buildpacks will only match the single JAR file that your build produces. That means files outside of that are considered "source code" and not included in your final container. You can adjust this pattern to match multiple files. When it matches multiple or a directory, the buildpack will keep everything. Everything that matches ends up under the /workspace directory in the final image.

@goafabric
Copy link
Author

@dmikusa-pivotal
a cool thank you very much ... in theory this would be
BP_MAVEN_BUILT_ARTIFACT=target/*.[ejw]ar target/classes/db/migration

but i am unsure about the first part .. as this is a Native application so workspace just has (in my case)
org.goafabric.personservice.Application

so this would rather be
BP_MAVEN_BUILT_ARTIFACT=target/*.Application target/classes/db/migration
i guess ?

because of native builds arm limitation i cannot build locally and have to leverage github actions

@goafabric
Copy link
Author

goafabric commented Jun 15, 2022

ok i guess for native images build inside docker this is a lil different, because console log tells me
/layers/paketo-buildpacks_native-image/native-image/org.***.personservice.Application (executable)

ok . now i see .. this is again different projekt at paketo
https://github.com/paketo-buildpacks/native-image

before beeing redirect a 3rd time .. i gues the equivalent here is
BP_NATIVE_IMAGE_BUILT_ARTIFACT
.. do you happen to know if the described mechanism is also possible with native images ?

because this just says:
--- cut ---
Configure the built application artifact explicitly. This is required if building a native image from a JAR file

And I am unsure how the configuration would look like than

@dmikusa
Copy link
Contributor

dmikusa commented Jun 15, 2022

Sorry, I was looking into this more and I don't think it's going to work presently. We are aggressively pruning files to keep the image size down. After compilation with Maven, we strip out all of the source code and after native-image compilation, we do the same with the bytecode.

For Maven and source code, you can use the argument I mentioned to ensure that stuff is retained in /workspace. There is not a similar option for native-image though. The buildpack removes all the bytecode and doesn't retain anything besides the image.

ok i guess for native images build inside docker this is a lil different, because console log tells me /layers/paketo-buildpacks_native-image/native-image/org.***.personservice.Application (executable)

The /layers directory contains the outputs from buildpacks, they are not all carried over into the final image. When you add the option for BP_MAVEN_BUILT_ARTIFACT it will save the matched files to /layers/paketo-buildpacks_maven/, but that is only available at build time.

I think what is needed here is a code change to the buildpack. I'd be interested in how you'd see this working. The buildpack can certainly persist files through to your final image. We could add an env variable to the native-image buildpack like BP_NATIVE_IMAGE_ADDITIONAL_FILES (the BP_NATIVE_IMAGE_BUILT_ARTIFACT is different, that points native image to a specific JAR file that we should build, in the case where you have multiple JAR files which isn't something that happens with Spring Boot apps). The env would be a space separate list of glob patterns. Anything matched, would be copied to the run image.

The part that is a little confusing here is that buildpacks work in a pipeline fashion and they can each transform the /workspace directory as they execute. The /workspace is where your final binary is located and that is what's executed in your final image. By the time native-image runs, the contents of your /workspace are not the same as your source code. That means you'd have to write glob patterns that match the state of the workspace at that time. That would essentially be the set of files that you preserve through the build phase with BP_MAVEN_BUILT_ARTIFACT, which is not exactly intuitive.

For example:

.
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   └── resources
│   └── test
│       └── java
└── target

If you set BP_MAVEN_BUILT_ARTIFACT='target/*.jar target/classes', then you'd end up with target/demo-0.0.1-SNAPSHOT.jar and target/classes/in the/workspacewhen native-image runs. You would then need to setBP_NATIVE_IMAGE_BUILT_ARTIFACT=target/.jar, so it can find your JAR and build the native image binary from it, and then BP_NATIVE_IMAGE_ADDITIONAL_FILES=target/classes/db/migrationso that it copies those files into the final run image. This could be a little confusing as you might expect to be able to setsrc/main/resources/db/migration`.

The output of this example would be:

├── io.paketo.demo.DemoApplication
└── target
│   ├── classes
|    │   ├── db
|    |    │   ├── migration
...

Your app would have to know to look in that location for the files, which may not be where it expects them.

I'm curious to know what you would expect here? Where you'd expect files to exist? Where your app would need them to exist? etc...

This might be something that we need to address differently. There is an issue open regarding the ability to control what files are/aren't deleted, paketo-buildpacks/libbs#103, I think the same concerns apply here. Adding a single env variable like is proposed there would probably be a better option. I still think there's questions about where stuff ends up in the final image though. If we copy src/main/resources/db/migrations to /workspace/src/main/resources/db/migrations, is that really helpful? In addition to paketo-buildpacks/libbs#103, we might need some sort of transform option but I'm not sure what that would look like off hand.

@goafabric
Copy link
Author

Thank you for the very detailed description and taking so much time.

The overall abstract requirement is quiete simple.
That would be any option similar to jibs extradirectiories
https://github.com/GoogleContainerTools/jib/blob/master/jib-maven-plugin/README.md#extradirectories-object

This lets you define a "from path" from your project /workspace
and and into, where to reside inside the container.
Of course both options only make sense, when the build job has acces to the "from" files.
And the application has acces to the "into folder".

** The concrete requirement in this special case **
is basically what you wrote and to copy the migrations.
This would basically be a workaround for spring-attic/spring-native#778
Of course if spring native would/will have proper flyway support that is not needed.

Currently i simulate the behaviour by having a jib or dockerfile process the container again after paketo.
And just adding the directory .. ANd then during bootstrap tell flyway to use the migrations from the filesystem.
You can define a location there .. no problem.
All in all that works, but just chaining one hack after another

Conclusion
For the concrete requirement the best solution would be a solution to the flyway ticket.
But overall having some functionality like extradirectories, would help in general

@dmikusa
Copy link
Contributor

dmikusa commented Jun 17, 2022

One additional note of reference for anyone coming upon this thread. In most cases, Spring Boot resources (i.e. files under src/main/resources should be bundled into the actual binary. The Spring Boot tooling will include resources in the resource-config.json that is generated, what's listed in there ends up in the binary.

@goafabric
Copy link
Author

i see no value in this anymore
i think for flyway we should have another solution

@dmikusa
Copy link
Contributor

dmikusa commented Sep 20, 2022

Just to follow up, we did end up implementing paketo-buildpacks/libbs#103 and it was released in 7.2.0.

That does not have the transformation capabilities I mentioned, but it would allow you to keep the files through into the final container. You could get around that by having the same directory structure in your source code, that you require in the final image.

For example: if you need /workspace/migrations, then you would just need to have migrations/ in the root of your JAR file & you could have that folder persisted into the final container.

Not sure if that helps, but thought I'd follow up.

@goafabric
Copy link
Author

@dmikusa thank you

@goafabric
Copy link
Author

@dmikusa sorry to contact you via this issue .. but i don't know another way without raising a new issue
can you tell me what happened to the issue concerning "arm64" support ?
paketo-buildpacks/stacks#51

this was still open and now just has the "repo has been archived now" status
so do we have support now for arm64 ? because last time i tried it did not work ..
also curious concerning spring boot 3.0
thank u

@dmikusa
Copy link
Contributor

dmikusa commented Oct 4, 2022

I suspect that is closed because of project repo changes, not because we have ARM64 support complete. That is still a work in progress.

What we have for ARM64 at the moment is a build-your-own option. See https://github.com/dmikusa/paketo-arm64.

A past colleague at VMware also has a Docker Hub image he's published using these instructions. You can use that, but it's an unofficial image at this point. See this comment.

There are still plans for official ARM64 support, but it's kind of hung up on some upstream issues that we need to build images in a sustainable way. See this and this. Upvotes on those helps.

@goafabric
Copy link
Author

@dmikusa thank u very much again

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

No branches or pull requests

2 participants