GraalVM с компиляцией собственных образов в Travis CI

У меня есть проект Java, который я компилирую с помощью собственного образа GraalVM в исполняемый двоичный файл. Я хотел бы настроить процесс непрерывной интеграции проекта с Travis CI, и мне это интересно - позволяет ли это Travis CI? Как я могу настроить файл.travis.yml для сборки с помощью собственного образа GraalVM?

2 ответа

Решение

Мне удалось настроить компиляцию GraalVM в собственном образе в сборках Travis CI, используя install-jdk.sh из Bach.java - Java Shell Builder. Вот .travis-ci.yml:

sudo: false
language: java

cache:
  directories:
    - $HOME/.m2

before_install:
- wget https://github.com/sormuras/bach/raw/master/install-jdk.sh

matrix:
  include:
  # GraalVM
    - env: JDK='GraalVM 19'
      install: . ./install-jdk.sh --url "https://github.com/oracle/graal/releases/download/vm-19.2.0/graalvm-ce-linux-amd64-19.2.0.tar.gz"

script:
  - mvn package -Pnative -Dnative-image.docker-build=true

Вариант 1: GraalVM с компиляцией образа в машинном коде непосредственно на хосте Travis CI

Первый вариант установки GraalVM (включая собственный образ) на TravisCI: просто используйте SDKMAN. В.travis.yml выглядит так:

language: minimal

install:
  # Install GraalVM with SDKMAN
  - curl -s "https://get.sdkman.io" | bash
  - source "$HOME/.sdkman/bin/sdkman-init.sh"
  - sdk install java 20.0.0.r11-grl

  # Check if GraalVM was installed successfully
  - java -version

  # Install Maven, that uses GraalVM for later builds
  - sdk install maven

  # Show Maven using GraalVM JDK
  - mvn --version

  # Install GraalVM Native Image
  - gu install native-image

  # Check if Native Image was installed properly
  - native-image --version

script:
  # Run GraalVM Native Image compilation
  - native-image \
    --no-server \
    --no-fallback \
    -H:+TraceClassInitialization \
    -H:Name=yourArtifactNameHere \
    -H:+ReportExceptionStackTraces \
    -DremoveUnusedAutoconfig=true \
    -DremoveYamlSupport=true \
    -cp yourClassPathHere yourMainClassHere;

Здесь следует отметить один важный момент: не используйтеlanguage: java или дистрибутивы Linux по умолчанию, такие как dist: bionicв одиночестве!, поскольку они поставляются с предустановленными версиями Maven, которые настроены на использование предустановленного OpenJDK. Но большинству людей понадобится Maven, чтобы использовать наш SDKMAN, установленный GraalVM, для правильной компиляции наших проектов Java позже. Поэтому мы просто используемlanguage: minimal, который представляет собой простой способ получения наших сборок Travis на основе базовой среды сборки Travis без предустановленных JDK или Maven. Чтобы проверить это, мы запускаемmvn --version, который должен выглядеть примерно так внутри нашей сборки Travis:

$ mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /home/travis/.sdkman/candidates/maven/current
Java version: 11.0.6, vendor: Oracle Corporation, runtime: /home/travis/.sdkman/candidates/java/20.0.0.r11-grl
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.15.0-1028-gcp", arch: "amd64", family: "unix"

В native-image команда внутри scriptРаздел здесь просто используется как заполнитель, так как у вас могут быть совершенно разные параметры в зависимости от вашего варианта использования.

В моем случае я хотел скомпилировать приложение Spring Boot, поэтому я также создал 100% понятный пример проекта spring-boot-graalvm, где вы также могли бы взглянуть на сборки TravisCI, которые устанавливают GraalVM и выполняют компиляцию собственного образа.: https://travis-ci.org/jonashackt/spring-boot-graalvm

===========================================

Вариант 2: GraalVM с компиляцией нативного образа в Docker с использованием Docker-сервиса TravisCI

Возможно, вы уже привыкли создавать свои Java-приложения внутри контейнеров Docker - тогда компиляция собственных образов GraalVM не является исключением. Используя службу докеров TravisCI,.travis.yml становится довольно просто:

dist: bionic
language: minimal

services:
  - docker

script:
  - docker build . --tag=spring-boot-graal

Важнейшая часть - это ваша Dockerfileсейчас ( см. этот полный пример с использованием многоэтапных сборок Docker) - и преимущество перед вариантом 1: вы можете протестировать его локально на своем компьютере. Вот примерDockerfile:

FROM oracle/graalvm-ce:20.1.0-java11

MAINTAINER Jonas Hecht

ADD . /build
WORKDIR /build

# For SDKMAN to work we need unzip & zip
RUN yum install -y unzip zip

RUN \
    # Install SDKMAN
    curl -s "https://get.sdkman.io" | bash; \
    source "$HOME/.sdkman/bin/sdkman-init.sh"; \
    sdk install maven; \
    # Install GraalVM Native Image
    gu install native-image;

RUN source "$HOME/.sdkman/bin/sdkman-init.sh" && mvn --version

RUN native-image --version

RUN source "$HOME/.sdkman/bin/sdkman-init.sh" && native-image \
    --no-server -J-Xmx4G \
    --no-fallback \
    -H:+TraceClassInitialization \
    -H:Name=yourArtifactNameHere \
    -H:+ReportExceptionStackTraces \
    -DremoveUnusedAutoconfig=true \
    -DremoveYamlSupport=true \
    -cp yourClassPathHere yourMainClassHere;

Мы используем официальный образ Oracle GraalVM oracle/graalvm-ce:20.1.0-java11из DockerHub по адресу https://hub.docker.com/r/oracle/graalvm-ce/ здесь. Поскольку этого не хватаетnative-image command и Maven, мы используем guutil для установки команды и снова SDKMAN для установки Maven. Теперь вы можете компилировать собственные образы GraalVM как локально, так и в системах CloudCI, таких как TravisCI.

Напоминаем один намек: компиляция изображений в собственном коде требует довольно большого количества памяти. Если вам нужно использовать--no-server вариант, вам следует ограничить использование памяти с помощью -J-Xmx4G параметр для 4GB оперативной памяти для сборок Travis, так как в противном случае ваши сборки могут выйти из строя Error: Image build request failed with exit status 137 или похожие ошибки.

Следующим логическим шагом было бы отправить полученный образ Docker в какой-то реестр Docker и, возможно, запустить контейнер в каком-нибудь Cloud PaaS. Если вам нужна дополнительная информация, взгляните на это полностью понятное руководство здесь. Также есть пример полностью работающей многоступенчатой ​​сборки Docker.Dockerfileв этом примере проекта: https://github.com/jonashackt/spring-boot-graalvm/blob/master/Dockerfile

Другие вопросы по тегам