dockerkotlingradlekotlin-js

Kotlin/JS fails to build inside of Docker because of backslashes in package.json


I have a multi-project gradle build that I'm trying to build inside of docker. One of the projects is a Kotlin multiplatform project that builds to JVM and JS. Building the library is fine on my Windows machine, but I get an error when building from Docker.

Here is my Dockerfile (common is the multiplatform project):

FROM amazoncorretto:17-alpine-jdk
COPY . .
RUN apk add --update npm
RUN ./gradlew :common:build --no-daemon

And here is the relevant error snippet:

#10 181.5 > Task :common:jsPackageJson
#10 181.5 Cannot find build/js/packages_imported/Kotlin-DateTime-library-kotlinx-datetime-js-ir\0.4.0, rebuilding
#10 181.5 Cannot find build/js/packages_imported/kotlin\1.7.21, rebuilding
#10 181.5 Cannot find build/js/packages_imported/kotlin-test-js-runner\1.7.21, rebuilding

I can pretty clearly see that the error here is that the environment in docker doesn't recognize the \ as part of the path. I believe it works fine in my machine because Windows is ok with the backslash. I don't have access to a linux or macOS machine, so I can't check if package.json is created with forward or back slashes there. How do I get my project to build in docker?

./gradlew -v:

------------------------------------------------------------
Gradle 7.5.1
------------------------------------------------------------

Build time:   2022-08-05 21:17:56 UTC
Revision:     d1daa0cbf1a0103000b71484e1dbfe096e095918

Kotlin:       1.6.21
Groovy:       3.0.10
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          17.0.5 (Eclipse Adoptium 17.0.5+8)
OS:           Windows 10 10.0 amd64

Full Docker error:

[+] Building 194.7s (11/11) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                   0.0s
 => => transferring dockerfile: 341B                                                                                                                                                   0.0s
 => [internal] load .dockerignore                                                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                                                        0.0s
 => [internal] load metadata for docker.io/library/amazoncorretto:17-alpine-jdk                                                                                                        0.5s
 => [auth] library/amazoncorretto:pull token for registry-1.docker.io                                                                                                                  0.0s
 => [internal] load build context                                                                                                                                                      0.7s
 => => transferring context: 729.48kB                                                                                                                                                  0.7s
 => CACHED [1/6] FROM docker.io/library/amazoncorretto:17-alpine-jdk@sha256:55910135e17f0cbde36944c00fa327dc350cdc3f71bc3b150bb0950a116990c3                                           0.0s
 => [2/6] COPY . .                                                                                                                                                                     1.5s
 => [3/6] RUN apk add --update npm                                                                                                                                                     7.1s
 => [4/6] WORKDIR web                                                                                                                                                                  0.0s
 => [5/6] RUN npm install                                                                                                                                                              1.7s
 => ERROR [6/6] RUN ../gradlew :common:build --no-daemon                                                                                                                             183.1s
------
 > [6/6] RUN ../gradlew :common:build --no-daemon:
#10 0.602 Downloading https://services.gradle.org/distributions/gradle-7.5.1-bin.zip
#10 1.360 ...........10%............20%...........30%............40%...........50%............60%...........70%............80%...........90%............100%
#10 9.081
#10 9.081 Welcome to Gradle 7.5.1!
#10 9.081
#10 9.081 Here are the highlights of this release:
#10 9.082  - Support for Java 18
#10 9.082  - Support for building with Groovy 4
#10 9.082  - Much more responsive continuous builds
#10 9.083  - Improved diagnostics for dependency resolution
#10 9.083
#10 9.083 For more details see https://docs.gradle.org/7.5.1/release-notes.html
#10 9.084
#10 9.280 To honour the JVM settings for this build a single-use Daemon process will be forked. See https://docs.gradle.org/7.5.1/userguide/gradle_daemon.html#sec:disabling_the_daemon.
#10 10.78 Daemon will be stopped at the end of the build
#10 91.19 > Task :buildSrc:generateExternalPluginSpecBuilders
#10 91.19 > Task :buildSrc:extractPrecompiledScriptPluginPlugins
#10 93.58 > Task :buildSrc:compilePluginsBlocks
#10 110.6 > Task :buildSrc:generatePrecompiledScriptPluginAccessors
#10 110.6 > Task :buildSrc:generateScriptPluginAdapters
#10 113.9 > Task :buildSrc:pluginDescriptors
#10 113.9 > Task :buildSrc:processResources
#10 113.9 > Task :buildSrc:processTestResources NO-SOURCE
#10 137.6 > Task :buildSrc:compileKotlin
#10 137.6 > Task :buildSrc:compileJava NO-SOURCE
#10 137.6 > Task :buildSrc:compileGroovy NO-SOURCE
#10 137.6 > Task :buildSrc:classes
#10 137.7 > Task :buildSrc:inspectClassesForKotlinIC
#10 137.8 > Task :buildSrc:jar
#10 137.8 > Task :buildSrc:assemble
#10 137.9 > Task :buildSrc:compileTestKotlin NO-SOURCE
#10 137.9 > Task :buildSrc:pluginUnderTestMetadata
#10 137.9 > Task :buildSrc:compileTestJava NO-SOURCE
#10 137.9 > Task :buildSrc:compileTestGroovy NO-SOURCE
#10 137.9 > Task :buildSrc:testClasses UP-TO-DATE
#10 137.9 > Task :buildSrc:test NO-SOURCE
#10 138.1 > Task :buildSrc:validatePlugins
#10 138.1 > Task :buildSrc:check
#10 138.1 > Task :buildSrc:build
#10 169.0 > Task :common:transformCommonMainDependenciesMetadata
#10 171.5 > Task :common:generateProjectStructureMetadata
#10 181.2 > Task :kotlinNodeJsSetup
#10 181.2 > Task :kotlinNpmCachesSetup
#10 181.2 > Task :kotlinRestoreYarnLock
#10 181.3 > Task :kotlinYarnSetup
#10 181.5
#10 181.5 > Task :common:jsPackageJson
#10 181.5 Cannot find build/js/packages_imported/Kotlin-DateTime-library-kotlinx-datetime-js-ir\0.4.0, rebuilding
#10 181.5 Cannot find build/js/packages_imported/kotlin\1.7.21, rebuilding
#10 181.5 Cannot find build/js/packages_imported/kotlin-test-js-runner\1.7.21, rebuilding
#10 181.6
#10 181.6 > Task :common:jsTestPackageJson
#10 181.6 > Task :packageJsonUmbrella
#10 181.6 > Task :rootPackageJson
#10 181.6 > Task :kotlinNpmInstall FAILED
#10 182.1 > Task :common:compileCommonMainKotlinMetadata
#10 182.1
#10 182.1 FAILURE: Build completed with 2 failures.
#10 182.1
#10 182.1 1: Task failed with an exception.
#10 182.1 -----------
#10 182.1 * What went wrong:
#10 182.1 Execution failed for task ':kotlinNpmInstall'.
#10 182.1 > A problem occurred starting process 'command '/root/.gradle/nodejs/node-v16.13.0-linux-x64/bin/node''
#10 182.1
#10 182.1 * Try:
#10 182.1 > Run with --stacktrace option to get the stack trace.
#10 182.1 > Run with --info or --debug option to get more log output.
#10 182.1 > Run with --scan to get full insights.
#10 182.1 ==============================================================================
#10 182.1
#10 182.1 2: Task failed with an exception.
#10 182.1 -----------
#10 182.1 * What went wrong:
#10 182.1 java.lang.StackOverflowError (no error message)
#10 182.1
#10 182.1 * Try:
#10 182.1 > Run with --stacktrace option to get the stack trace.
#10 182.1 > Run with --info or --debug option to get more log output.
#10 182.1
#10 182.1 Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
#10 182.1
#10 182.1 You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
#10 182.1
#10 182.1 See https://docs.gradle.org/7.5.1/userguide/command_line_interface.html#sec:command_line_warnings> Run with --scan to get full insights.
#10 182.1 ==============================================================================
#10 182.1
#10 182.1 * Get more help at https://help.gradle.org
#10 182.1
#10 182.1
#10 182.1 BUILD FAILED in 3m 1s
#10 182.1 23 actionable tasks: 23 executed
------
executor failed running [/bin/sh -c ../gradlew :common:build --no-daemon]: exit code: 1

Here is build/js/package.json (auto generated by the Kotlin/JS compiler):

{
  "name": "my-app",
  "version": "0.0.1",
  "private": true,
  "workspaces": [
    "packages\\my-app-common",
    "packages\\my-app-common-test",
    "packages_imported\\Kotlin-DateTime-library-kotlinx-datetime-js-ir\\0.4.0",
    "packages_imported\\kotlin\\1.7.21",
    "packages_imported\\kotlin-test-js-runner\\1.7.21"
  ],
  "resolutions": {},
  "devDependencies": {},
  "dependencies": {},
  "peerDependencies": {},
  "optionalDependencies": {},
  "bundledDependencies": []
}

Solution

  • The build/ folders were being copied over, so the backslashes in the package.json files built on my local machine were not being overwritten. Just adding **/build/ to my .dockerignore fixed it.

    This gave me another problem:

    > A problem occurred starting process 'command '/root/.gradle/nodejs/node-v16.13.0-linux-x64/bin/node''
    

    After some troubleshooting turns out I wasn't installing nodejs properly. Here is my final fixed Dockerfile where I install gradle nodejs and corretto properly and use them to build:

    FROM node:lts as nodejs
    
    FROM gradle:7.6-jdk17
    COPY --from=nodejs . .
    COPY . .
    RUN gradle clean build
    
    ENTRYPOINT ["gradle", ":server:run"]