Skip to main content

Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Scout » Gitlab CI/CD integration
Gitlab CI/CD integration [message #1856681] Thu, 22 December 2022 13:32 Go to next message
Jerome HolbeinFriend
Messages: 13
Registered: June 2020
Junior Member
Hi there,

We want to set up GitLab CI/CD and for now just do some smoke tests, but I haven't been able to find much help on how to do so online. I've stumbled upon these slides on how to build docker images of Scout Server and Client applications: and upon this (apparently abandoned?) Jenkins integration git repo: .

Accordingly, for now I'm trying to build docker images for Server and Client, push them to our GitLab container registry and then set up a gitlab-ci.yml file to get a pipeline running, that loads, runs and links these two images into a working Scout app. While I can build the two docker images and run them locally (with a docker-compose a pointed out in the above slides), setting up an equivalent gitlab-ci.yml has been challenging. Any pointers on how to do this? Or more generally, what do you guys see as the most fitting way to provide a CI pipeline for Scout apps?

Best regards,
Jérôme Holbein
Re: Gitlab CI/CD integration [message #1856686 is a reply to message #1856681] Thu, 22 December 2022 15:02 Go to previous messageGo to next message
Nils Israel is currently offline Nils IsraelFriend
Messages: 72
Registered: May 2010
Hi Jérôme,
we use such a setup with a Scout Classic application. Since both the user interface and the server run on the same host anyway, we combined them into a single deployable application using the "org.eclipse.scout.rt.serverbridge".
First we deployed the .war file to a Tomcat using the Maven Tomcat plugin. But now we use the same .war file, put it in a Docker container and deploy it to the project's container registry.

The Docker image is based on the default Jetty image. You cannot use the Jetty 11 version because it uses the Servlet 5.0 model and Scout is based on 4.0.

Maybe you can use the following snippets as a starting point for your project:

FROM jetty:10-jre17
# jetty 11 uses servlet 5.0, eclipse scout still 4.0
USER root
RUN mkdir -p /app
RUN chown jetty:jetty /app
RUN java -jar "/usr/local/jetty/start.jar" --add-to-startd=http-forwarded
USER jetty
RUN mkdir -p /app/logs /app/config /app/storage /app/remoteFile
ADD target/ /var/lib/jetty/webapps/ROOT.war
CMD ["java","-jar","/usr/local/jetty/start.jar"]

Here are the essential parts of the gitlab ci pipeline. I copied it from a larger file, so you might need to tweak it here or there to get it working.

image: yourfavouritebuildimage


  - build
  - publish

  stage: build
    - ./mvnw $MAVEN_CLI_OPTS clean verify
    expire_in: 1 week
      - "*/target/"
      - target/
      - scout.ui.html/node_modules/
      - node_modules/

  image: docker:latest
  stage: publish
    - mvn-build
    - docker:dind
    - cd
    - docker build -t $DOCKER_TAG_COMMIT -t $DOCKER_TAG_LATEST .
    - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
    - docker push $DOCKER_TAG_COMMIT
    - docker push $DOCKER_TAG_LATEST


Re: Gitlab CI/CD integration [message #1856694 is a reply to message #1856686] Fri, 23 December 2022 07:17 Go to previous messageGo to next message
Jerome HolbeinFriend
Messages: 13
Registered: June 2020
Junior Member
Hi Nils,

Thanks for the quick reply. I wasn't even aware of such the serverbridge repo. That's a huge help. Not only for CI, but also for simplifying our deployment process as a whole (we also run Server and Client on the same host). If I run into trouble I might be back with questions, but this looks very promising.

Enjoy the holidays,
Re: Gitlab CI/CD integration [message #1858190 is a reply to message #1856694] Tue, 21 March 2023 16:01 Go to previous message
Nils Israel is currently offline Nils IsraelFriend
Messages: 72
Registered: May 2010
Some time ago I discovered that the npm script "build:dev:watch" wasn't working as expected and that I always had to execute a "mvn package" to get the resource files of the project.ui.html project into the correct location.
That was annoying, but I didn't had any clue what was causing this.

During the update to 23.1 I had to play around with the ObjectFactory and our custom widgets and I had to restart a lot. That was so annoying that I tried to find the cause for this. I found out that the DefaultFilesystemWebResourceRootContributor is relying on a naming convention. In the standard scout setup the jetty for development is started from a module named "" and the resource files are part of a module named "project.ui.html". The DefaultFilesystemWebResourceRootContributor is assuming that the name of the module with the resources is the name of the module with jetty without "" at the end. If that modules base dir does not contain a "target/dist" folder it is using the working directory as fallback.

Since we combined client and server in one application the default module name "project.ui.html" didn't made any sense and we renamed it to (and Of course, we still had the project.ui.html module with the resources which could not be found by the FileResolvers anymore.

In order to fix this, we @Replaced the DefaultFilesystemWebResourceRootContributor. The new Bean has to be placed as a "marker" in the module with the resources. To find the root folder for the resource we traverse the path of the beans class resource bottom up until we find a folder containing "target/dist". If none is found we return the workingDir like in the default implementation.

If anybody is interested, this is our implementation of the Bean.
public class FilesystemWebResourceRootModuleMarker extends DefaultFilesystemWebResourceRootContributor {
  private static final Logger LOG = LoggerFactory.getLogger(FilesystemWebResourceRootModuleMarker.class);

  public List<Path> getRoots() {
    var workingDir = System.getProperty("user.dir");
    URI classURI;
    try {
      var url = this.getClass().getResource(this.getClass().getSimpleName() + ".class");
      if (url==null) {
        return List.of(new File(workingDir).toPath());
      classURI = url.toURI();
    } catch (NullPointerException | URISyntaxException e) {
      LOG.error("Can't transform path to URI.", e);
      return List.of(new File(workingDir).toPath());

    if (classURI.toString().startsWith("jar:")) {
      LOG.trace("Class is part of a jar, defaulting to workingDir. WebResourceRoot: {}", workingDir);
      return List.of(new File(workingDir).toPath());

    Path pathPart = Path.of(classURI).normalize().toAbsolutePath();
    while (pathPart != null) {
      Path toFind = pathPart.resolve(AbstractWebResourceResolver.OUTPUT_FOLDER_NAME);
      if (Files.exists(toFind)) {
        LOG.trace("WebResourceRoot: {}", toFind);
        return List.of(toFind);
      pathPart = pathPart.getParent();
    LOG.trace("Can't find {} in path, defaulting to workingDir. WebResourceRoot: {}", AbstractWebResourceResolver.OUTPUT_FOLDER_NAME, workingDir);
    return List.of(new File(workingDir).toPath());

Previous Topic:Accordion field, height
Next Topic:Select contents on start edit of input field
Goto Forum:

Current Time: Wed Apr 24 17:03:08 GMT 2024

Powered by FUDForum. Page generated in 0.03399 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top