arnaud-deprez / docker

This repository contains my custom docker images

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Karaf: Using features

anton-johansson opened this issue · comments

I am planning on building a docker image of my application which runs on Karaf, and your Karaf docker image looks perfect. But I would want to install a feature (from my custom features.xml file) instead of using hot-deployment. How would you recommend I do that? I see two alternatives:

  • Write my own org.apache.karaf.features.cfg file and replace the built-in one
  • Send commands to Karaf somehow, feature:repo-add mvn:xx/yy/zz/xml/features and feature:install abc.

The features.xml file is expected to exist in the local Maven repository at build-time.

Dear,
Docker best practices is to use immutable deployment, meaning you can't modify your image once it's build.
So it doesn't fit well with the dynamic nature of Karaf which by definition is designed to mutate its state once it is running.

  • If you create your own org.apache.karaf.feature.cfg and if your don't have all your dependencies included in your image, it will download all your dependencies at its first start. I've already seen that my container fails to start from time to time due to an download error or something like that. So this solution is to avoid.
  • The second option is better because you will download every dependencies at the image build time but I've met some issues here too because once the feature is installed, it stops the karaf directly without waiting that all bundles are started and sometimes you might be in an inconsistent state. The good new is that once your image is built correctly, it will work well for each container.
  • A third option, which is my preferred one, is to build your custom karaf instance with the karaf maven bundle plugin and then add it on top of your favourite java image.

I didn't publish it as official karaf image because it's custom and depends on the needs. My karaf images can be used easily for development where you can have access to the container and install what you want but in production you must be sure that your image is built correctly and will run correct container instances.

Hope I'm clear, if you need help for that, I might publish an example. You can also check the one from fabric8's team

What you say makes a lot of sense, thanks. Yeah, I understand that the image should be complete at build time, and it makes sense that using a custom org.apache.karaf.features.cfg file wouldn't allow that.

Side note, just curious: how about deploying docker images containing databases? Such as a mongodb server? I guess that would still count as immutable, even though data grows and changes in there?

About the second option, I might try that and see if I bump into the same issues as you.

Third option seems very good, yes. You mean packaging my application as a KAR? I haven't worked very much with KAR's yet, so I'm gonna have to read up a little on that first. Thanks for the advice!

For database, you will run a MongoDB container with a volume mounted in it that will contain the data. Volume are kind of special container in docker which doesn't run any process.

For the third option, I really build a complete karaf (not simply a KAR). The KAR should work (build it and drop it to deploy) but I when I tried I've also met issues :-(

Ah, of course. That makes sense.

Allright. I'm reading up on the karaf-maven-plugin as we speak. I guess I can build a complete Karaf using the karaf-assembly packaging instead of the kar packaging. Just gonna figure it out. :)

Hmm, I can't quite figure it out. I have a POM like this:
https://gist.github.com/anton-johansson/6fa769c031bb99c8420d917330043af0

And it assembles a clean Karaf. But of course, I want to add my artifacts to the assembled Karaf. So I go ahead and add my features as a dependency:

        <dependency>
            <groupId>com.anton-johansson</groupId>
            <artifactId>assembly-test-features</artifactId>
            <version>${project.version}</version>
            <classifier>features</classifier>
            <type>xml</type>
        </dependency>

Then I get assembly errors, like so:
Unable to build assembly: Unable to resolve root: missing requirement [root] ...

My features are built correct and work if I run them in a standalone (regular) Karaf. Not sure why it won't resolve dependencies and stuff. Does karaf-maven-plugin handle dependencies differently or something? My feature installs another feature: CXF.

You have any idea?

Hmm, turns out that my bundles contain the following MANIFEST-header:
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"

This is good, since I use Java 8 code, it's nice to tell the container that I require Java 8. However, that's when karaf-assembly gives me the error that ends with: missing requirement [assembly-test-commons/1.0.0.SNAPSHOT] osgi.ee; filter:="(&(osgi.ee=JavaSE)(version=1.8))". Do you know why it doesn't work with a Java 8 requirement?

If I remove the Require-Capability header (through the instruction <_noee>true</_noee> in maven-bundle-plugin), my assembly is generated perfectly, and it runs without any problem.

Mmmmhhh sorry, I don't see where can be the error here, but it works with java 8. I did a similar thing for one of my client last year, unfortunately, I don't have the project anymore.
If you can share your project on github, I could take a look if you want.