gradle 用于运行JLink可执行文件的Alpine Docker映像

e5njpo68  于 2022-12-29  发布在  Docker
关注(0)|答案(1)|浏览(185)

我目前的Docker映像大约是200MB。我的目标是尽可能地减少它,所以我认为alpine映像将是实现这一目标的好方法。然而,我不断遇到障碍。
它是一个多模块libGDX项目,使用Java14及其预览特性,以及JLink(来自JPackage)来生成定制(轻量级)JRE。
我只关心部署server模块,它依赖于common模块(client模块也使用它)。
我将提供所有必要的文件下面,但如果我错过了什么,这里是一个链接到回购:https://github.com/payne911/marvelous-bob/tree/dev

当前问题

我要么得到:

  • 执行./server时:file not found表示我知道存在且可执行的可执行文件,我尝试在Docker映像中运行该文件
  • 执行apk add --no-cache someLibrary时:尝试下载ENTRYPOINT中的库时出现segfault: core dumped,我认为执行该文件需要这些库(libstdc++libc6-compat

目标

可重用的轻量级Docker映像,其中包含运行JLink生成的libGDX可执行文件所需的一切内容。

当前文件处于工作状态,我正在尝试重构

一米十四分一秒

FROM openjdk:14-jdk-alpine
COPY server/build/libs/server-all.jar /app.jar
COPY utils/deploys/bootstrap.sh /bootstrap.sh
RUN chmod +x /bootstrap.sh
EXPOSE 80
ENTRYPOINT ["./bootstrap.sh"]

bootstrap.sh

#!/usr/bin/env sh
echo "========== LAUNCHING SERVER APP ========="
apk add --no-cache libstdc++
java --enable-preview -jar /app.jar

build.gradle个文件

buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
        maven { url "https://plugins.gradle.org/m2/" }
        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
        jcenter()
        google()
    }
    dependencies {
    }
}

// to force download of sources and JavaDoc
plugins {
    id 'java'
    id 'idea'
}
idea {
    module {
        downloadJavadoc = true
        downloadSources = true
    }
}

allprojects {

    version = '1.0'
    ext {
        appName = "marvelous-bob"
        gdxVersion = '1.9.10'
        roboVMVersion = '2.3.7'
        box2DLightsVersion = '1.5'
        ashleyVersion = '1.7.0'
        aiVersion = '1.8.2'

        slf4j = '1.7.26'
        logback = '1.2.3'
        lombok = '1.18.12'
        kryonet = '2.22.6'
        reflectionsVersion = '0.9.12'

        pieMenuVersion = '4.2.0'
        shapeDrawer = '2.3.0'
    }

    repositories {
        mavenLocal()
        mavenCentral()
        jcenter()
        google()
        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
        maven { url "https://oss.sonatype.org/content/repositories/releases/" }
        maven { url 'https://jitpack.io' }
    }
}

project(":desktop") {
    apply plugin: "java-library"

    dependencies {
        api project(":client")
        api "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
        api "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop"
        api "com.badlogicgames.gdx:gdx-tools:$gdxVersion"
    }
}

project(":client") {
    apply plugin: "java-library"

    dependencies {
        api project(":common")
        api "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"

        api "space.earlygrey:shapedrawer:$shapeDrawer"
        api "com.github.payne911:PieMenu:$pieMenuVersion"
    }
}

project(":server") {
    apply plugin: "java-library"

    dependencies {
        api project(":common")
        api "com.badlogicgames.gdx:gdx-backend-headless:$gdxVersion"
        api "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
    }
}

project(":common") {
    apply plugin: "java-library"

    dependencies {
        api "com.badlogicgames.gdx:gdx:$gdxVersion"
        api "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
        api "com.badlogicgames.box2dlights:box2dlights:$box2DLightsVersion"
        api "com.badlogicgames.gdx:gdx-ai:$aiVersion"

        // todo: do we need both logging libraries? p.s. kryonet uses Minlog
        api "org.slf4j:slf4j-api:$slf4j"
        api "ch.qos.logback:logback-classic:$logback"
        api "com.github.crykn:kryonet:$kryonet"
        api "org.reflections:reflections:$reflectionsVersion"
    }
}

常见

plugins {
    id 'java'
    id 'io.freefair.lombok' version '5.1.0'
}

sourceCompatibility = 14
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

tasks.withType(JavaCompile) {
    options.compilerArgs += "--enable-preview"
}
tasks.withType(Test) {
    jvmArgs += "--enable-preview"
}
tasks.withType(JavaExec) {
    jvmArgs += '--enable-preview'
}

sourceSets.main.java.srcDirs = [ "src/" ]

jar {
    from('src') {
        include '**/*.properties'
    }
}

服务器

plugins {
    id 'java'
    id 'io.freefair.lombok' version '5.1.0'
    id 'com.github.johnrengelman.shadow' version '5.2.0'
}

sourceCompatibility = 14
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
tasks.withType(JavaCompile) {
    options.compilerArgs += "--enable-preview"
}
tasks.withType(Test) {
    jvmArgs += "--enable-preview"
}
tasks.withType(JavaExec) {
    jvmArgs += '--enable-preview'
}
sourceSets.main.java.srcDirs = [ "src/" ]

jar {
    project.version="" // to remove version number from the built jar's name
    manifest {
        attributes 'Main-Class': 'com.marvelousbob.server.BobServerLauncher'
    }
}

GitHub操作yml文件

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup with Java 14
        id: java-setup
        uses: actions/setup-java@v1
        with:
          java-version: 14

      - name: Allow GitHub Actions to run Gradlew
        run: chmod u+x gradlew

      - name: Run Gradle build
        id: gradle-build
        uses: eskatos/gradle-command-action@v1
        with:
          arguments: shadowJar

      # more stuff ...

∮我所尝试的∮
好多事情,好多天!这就是我最后一次尝试的状态。

一米十七

FROM alpine:3.7
COPY server/build/jpackage/server /server
FROM openjdk:14-jdk-alpine
COPY server/build/libs/server-all.jar /app.jar
COPY utils/deploys/bootstrap.sh /bootstrap.sh
RUN chmod +x /bootstrap.sh
EXPOSE 80
ENTRYPOINT ["./bootstrap.sh"]

一米十八分一秒

#!/bin/sh
echo "========== LAUNCHING SERVER APP ========="
cd /server/bin
chmod +x server
./server

一米十九

和另一个一样。

常见

和另一个一样。

服务器

plugins {
    id 'java'
    id 'io.freefair.lombok' version '5.1.0'
    id 'org.beryx.runtime' version '1.8.4'
}

sourceCompatibility = 14
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
tasks.withType(JavaCompile) {
    options.compilerArgs += "--enable-preview"
}
tasks.withType(Test) {
    jvmArgs += "--enable-preview"
}
tasks.withType(JavaExec) {
    jvmArgs += '--enable-preview'
}
sourceSets.main.java.srcDirs = [ "src/" ]

mainClassName = "com.marvelousbob.server.BobServerLauncher"

task dist(type: Jar) {
    project.version="1" // adjust the CI/CD if you change this
    manifest {
        attributes 'Main-Class': project.mainClassName
    }
    from {
        configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
    with jar

    destinationDirectory = file("$buildDir/lib")
}

jpackageImage.dependsOn dist
dist.dependsOn classes

// JLink configuration to minimize size of generated jar
runtime {
    options = ['--strip-debug',
               '--compress', '2',
               '--no-header-files',
               '--no-man-pages',
               '--strip-native-commands',
               '--vm', 'server']
    modules = ['java.base' ,
               'java.desktop',
               'jdk.unsupported']
    distDir = file(buildDir)

    jpackage {
        //jpackageHome = '/usr/lib/jvm/open-jdk'
        mainJar = dist.archiveFileName.get()
    }
}

Github操作yml文件

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup with Java 14
        id: java-setup
        uses: actions/setup-java@v1
        with:
          java-version: 14

      - name: Building with Gradlew
        run: |
          chmod u+x gradlew
          ./gradlew server:jpackageImage

      # more stuff ...
polhcujo

polhcujo1#

@deduper似乎已经弄明白了(参见https://chat.stackoverflow.com/rooms/222569/discussion-between-deduper-and-payne),但我没有时间回去确认他的分析是否正确。
从理论上讲,这确实很有意义,所以我还是把它作为一个答案贴出来:
我很确定你在问题中描述的错误的主要原因是因为你在Windows10或Ubuntu上构建了运行时;然后尝试在Alpine上部署和运行运行时。
我不会接受我的答案,因为我还没有确认这一点,但我仍然张贴它的情况下,其他人遇到这个问题,并希望一个可能的线索。

相关问题