I’ve been running with 512 mb no problem on <Fly.i...
# ktor
c
I’ve been running with 512 mb no problem on Fly.io. With 256 mb, I was getting some OOMs. My ktor application was a good bit more complex than the generated example though, including database with Exposed and Postgres.
🧵 1
c
thanks. i might give them a try. any tldr on how to launch a ktor sample?
for example... railway.app had 0 docs so it was kinda hard for me to understand what to do. also. what i dont like about railway is that it has downtime between deployments. about a minute+... 😭
hm. looks like with fly.io you have to use docker?
c
Yes, Docker is required. Once you get over the docker hump, it honestly makes things a lot easier. Then your application can be deployed to Google Cloud Run, Azure app services, etc.
c
i guess i might cave and try to wrap my head around docker.
i was really hoping i could get away without it. lol
c
It can be a little bit confusing. What often works well for these cloud providers is to put your jar file and Dockerfile in a directory, point the cloud CLI to that directory, and then let the cloud provider upload those and actually build the docker image for you. This effectively means you don’t need docker on your computer The alternative is to try to build the docker image on your computer, which I always found to be much more difficult to set up due to different operating systems, cpu architecture, etc.
Copy code
val createDockerfile = register("createDockerfile") {
        val javaVersion = libs.versions.java.target.get()
        val isDockerMinificationEnabled = project.property(“IS_DOCKER_MINIFICATION_ENABLED").toString().toBoolean()
Copy code
inputs.property("javaVersion", javaVersion)
        inputs.property("isDockerMinificationEnabled", isDockerMinificationEnabled)
Copy code
if (isJavaMinificationEnabled) {
            dependsOn(proguardJar)
            inputs.files(proguardJar)
        } else {
            dependsOn(fatJar)
            inputs.files(fatJar)
        }
Copy code
val dockerFile = File(dockerDir, "Dockerfile")
        val jarToDeploy = File(dockerDir, "app.jar")
        outputs.files(dockerFile, jarToDeploy)
Copy code
doLast {
            inputs.files.first { it.name.endsWith(".jar") }.copyTo(jarToDeploy, overwrite = true)
Copy code
val dockerFileContents = buildString {
                appendLine("FROM eclipse-temurin:${javaVersion}-alpine AS build")
                appendLine("COPY ${jarToDeploy.name} /app.jar")
Copy code
if (isDockerMinificationEnabled) {
                    appendLine("RUN jdeps --ignore-missing-deps -q --multi-release $javaVersion --print-module-deps app.jar > jdeps.txt")
                    appendLine("RUN jlink --verbose --compress 2 --strip-java-debug-attributes --no-header-files --no-man-pages --output \"jre_optimized\" --add-modules \$(cat jdeps.txt),<http://jdk.crypto.ec|jdk.crypto.ec>,jdk.crypto.cryptoki,java.instrument")
                    appendLine("FROM alpine:latest")
                    appendLine("COPY --from=build /jre_optimized /opt/java/jre")
                    appendLine("COPY --from=build /app.jar /app.jar")
                }
Copy code
appendLine("EXPOSE 8080:8080")
Copy code
val javaBin = if (isDockerMinificationEnabled) "/opt/java/jre/bin/java" else "java"
                appendLine("ENTRYPOINT [\"$javaBin\", \"-jar\", \"/app.jar\"]")
            }
Copy code
dockerFile.writeText(dockerFileContents)
        }
    }
We’re going to have to live with some bizarro format here in Slack 😂
There is a ktor gradle plug-in for docker, although I had better luck getting an optimized image by writing my own gradle task. ProGuard and jlink are optional but do reduce the final image size significantly (hundreds of megabytes).
😍 1
c
How about you let jib build the image and push it to an image repo? We use jib at my company
j
some notes in https://community.fly.io/t/deployment-of-java-spring-api-using-dockerfile/6708/8 re: running on fly.io and fitting in 256MB limit of their free tier
c
wth is jib. lemme google it
c
@Colton Idle it helps build an optimized docker image for your Java apps.
c
oooh
j
yeah depending on your build process having docker built as part of maven via jib is nice, but separate Dockerfile that does the same thing can be better to integrate into some other processes; running constrained by mem you'll have to do similar things in both cases
c
gotcha. right now im still learning ktor, so i might stick to building the fat jar with gradle, but will def try jib later. thank you