Cyclops
Cyclops

Reputation: 689

Using a jib for maven but non-Java application

I am in the process of creating a project and use Jib to create containers and push them to ECR. It is a multi-module maven project which has 3 sub-modules, 2 of them are standard java spring-boot project which is woking fine with Jib and the other one is an npm project which build using mvn. Here is the pom for it.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>my-search-frontend</artifactId>
    <packaging>pom</packaging>
    <version>1.11.0-SNAPSHOT</version>
    <name>my search frontend</name>
    <description>my search frontend</description>

    <parent>
        <artifactId>my-search</artifactId>
        <groupId>com.regalo.my</groupId>
        <version>1.11.0-SNAPSHOT</version>
    </parent>

    <build>
        <finalName>my-search-frontend</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <filesets>
                        <fileset>
                            <directory>node_modules</directory>
                            <includes>
                                <include>**/*</include>
                            </includes>
                            <followSymlinks>false</followSymlinks>
                        </fileset>
                        <fileset>
                            <directory>build</directory>
                            <includes>
                                <include>**/*</include>
                            </includes>
                            <followSymlinks>false</followSymlinks>
                        </fileset>
                    </filesets>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <executions>
                    <execution>
                        <id>npm-install</id>
                        <phase>initialize</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                        <configuration>
                            <executable>npm</executable>
                            <arguments>
                                <argument>install</argument>
                            </arguments>
                            <workingDirectory>${project.basedir}</workingDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>npm-run-build</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                        <configuration>
                            <executable>npm</executable>
                            <arguments>
                                <argument>run</argument>
                                <argument>build</argument>
                            </arguments>
                            <workingDirectory>${project.basedir}</workingDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <configuration>
                    <skipDocker>${skip.docker}</skipDocker>
                    <imageTags>
                        <imageTag>${project.version}</imageTag>
                        <imageTag>latest</imageTag>
                    </imageTags>
                    <dockerDirectory>${project.basedir}/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/build</targetPath>
                            <directory>${project.basedir}/build</directory>
                            <include>**/*</include>
                        </resource>
                        <resource>
                            <targetPath>/build</targetPath>
                            <directory>${project.basedir}</directory>
                            <includes>
                                <include>index.html</include>
                            </includes>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <configuration>
                    <to>
                        <image>${docker.repository.host}/${project.artifactId}:${project.version}</image>
                    </to>
                    <!-- <skip>${skip.docker}</skip> -->
                    <extraDirectories>
                        <paths>
                            <path>
                                <from>${project.basedir}</from>
                                <into>/build</into>
                            </path>
                        </paths>
                    </extraDirectories>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Spotify one is the way previously we did it and now we are moving to Jib. But I am getting sollowing issue for this app build,

    [ERROR] Failed to execute goal com.google.cloud.tools:jib-maven-plugin:2.7.1:build (default-cli) on project my-search-frontend: Obtaining project build output files failed; make sure you have compiled your project before trying to build the image. 
(Did you accidentally run "mvn clean jib:build" instead of "mvn clean compile jib:build"?): /home/cyrex/Documents/Sourcecode/my-search/my-search-frontend/target/classes -> [Help 1]

Project structure of app

enter image description here

Help on this would highly appreciate.

Upvotes: 3

Views: 3183

Answers (3)

Chanseok Oh
Chanseok Oh

Reputation: 4306

The Jib Maven and Gradle plugins are for Java apps, and the error message is complaining that there are no compiled .class files in your NPM module. However, technically, you may be able to make Jib build an NPM image with some tricks (for example, put a dummy DummyClass.java under src/main/java to bypass the error, override <container><entrypoint> to not execute java, use <extraDirectories> to put arbitrary files, set <from><image> to use a non-JRE base image, etc.). You may also need to remove files using the Jib Layer-Filter extension. However, since Jib is really tailored to Java apps, I cannot really recommend it.

Just FYI, Jib is highly customizable and extensible with the Jib Extension Framework, so theoretically you could write an NPM Jib extension to cover this highly specialized workflow (and share it with the Jib community).

Also for non-Java apps and non-Maven workflows, we have other Jib solutions: Jib Core (the Java library) and Jib CLI. Jib CLI may work in this case, although it's a not a Maven plugin. (I don't know if it's a good idea, but FYI, there seems a few ways to run an arbitrary command in Maven.)


Related, this article shows an example that uses the Jib Layer-Filter extension to enable use cases not supported by Jib.

Upvotes: 6

wohlben
wohlben

Reputation: 31

To offer an alternative if anyone is still looking going forward (this was first hit for my google search):

you can set the jib plugin to use the packaged .jar file, which is auto generated if you use mvn package and pretty small if no code exists (~2kb)

Also make sure that your project doesn't have a parent or dependencies, otherwise jib will copy the libraries into the image.

<build>
    <plugins>
        <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>1.12.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>install-node-and-npm</goal>
                    </goals>
                </execution>
                <execution>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                </execution>
                <execution>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>run build</arguments>
                    </configuration>
                </execution>
            </executions>
            <configuration>
                <nodeVersion>v16.9.1</nodeVersion>
            </configuration>
        </plugin>

        <plugin>
            <groupId>com.google.cloud.tools</groupId>
            <artifactId>jib-maven-plugin</artifactId>
            <version>2.7.1</version>
            <configuration>
                <containerizingMode>packaged</containerizingMode>
                <extraDirectories>
                    <paths>
                        <path>
                            <from>build</from>
                            <into>/var/www/html</into>
                        </path>
                    </paths>
                </extraDirectories>
                <container>
                    <entrypoint>INHERIT</entrypoint>
                </container>
                <from>
                    <image>nginx</image>
                </from>
                <to>
                    <image>THE IMAGE NAME:${project.version}</image>
                </to>
            </configuration>
        </plugin>
    </plugins>
</build>

to create it: mvn clean package jib:dockerBuild

use dive to check if unnecessary files were added

Upvotes: 3

GeertPt
GeertPt

Reputation: 17846

JIB is only for java projects. It handles installing a Java Runtime and dependencies in optimized layers. But it cannot create NPM docker images.

So you can only enable the jib-maven-plugin maven plugin for java modules.

For NPM, you should stick to the spotify docker-maven-plugin or something similar. Or give fabric8 a try.

Upvotes: 0

Related Questions