Hey everyone! im working on WebServer course that ...
# kobweb
e
Hey everyone! im working on WebServer course that stevdza-san did! Right now im trying to deploy it in render... im having an issue when deployed:
Exception in thread "main" com.varabyte.kobweb.common.error.KobwebException: No site folder found. Did you run
kobweb export
?
And this is my Dockerfile (first time with Docker):
Copy code
#-----------------------------------------------------------------------------
# Variables shared across multiple stages (they need to be explicitly opted
# into each stage by being declaring there too, but their values need only be
# specified once).
ARG KOBWEB_APP_ROOT="site"

FROM eclipse-temurin:17 as java

FROM java as export

#-----------------------------------------------------------------------------
# Create an intermediate stage which builds and exports our site. In the
# final stage, we'll only extract what we need from this stage, saving a lot
# of space.

ENV KOBWEB_CLI_VERSION=0.9.13
ARG KOBWEB_APP_ROOT

ENV NODE_MAJOR=20

# Copy the project code to an arbitrary subdir so we can install stuff in the
# Docker container root without worrying about clobbering project files.
COPY . /project

# Update and install required OS packages to continue
# Note: Node install instructions from: <https://github.com/nodesource/distributions#installation-instructions>
# Note: Playwright is a system for running browsers, and here we use it to
# install Chromium.
RUN apt-get update \
    && apt-get install -y ca-certificates curl gnupg unzip wget \
    && mkdir -p /etc/apt/keyrings \
    && curl -fsSL <https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key> | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
    && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] <https://deb.nodesource.com/node_$NODE_MAJOR.x> nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
    && apt-get update \
    && apt-get install -y nodejs \
    && npm init -y \
    && npx playwright install --with-deps chromium

# Fetch the latest version of the Kobweb CLI
RUN wget <https://github.com/varabyte/kobweb-cli/releases/download/v${KOBWEB_CLI_VERSION}/kobweb-${KOBWEB_CLI_VERSION}.zip> \
    && unzip kobweb-${KOBWEB_CLI_VERSION}.zip \
    && rm kobweb-${KOBWEB_CLI_VERSION}.zip

ENV PATH="/kobweb-${KOBWEB_CLI_VERSION}/bin:${PATH}"

WORKDIR /project/${KOBWEB_APP_ROOT}

# Decrease Gradle memory usage to avoid OOM situations in tight environments
# (many free Cloud tiers only give you 512M of RAM). The following amount
# should be more than enough to build and export our site.
RUN mkdir ~/.gradle && \
    echo "org.gradle.jvmargs=-Xmx256m" >> ~/.gradle/gradle.properties

RUN kobweb export --notty

#-----------------------------------------------------------------------------
# Create the final stage, which contains just enough bits to run the Kobweb
# server.
FROM java as run

ARG KOBWEB_APP_ROOT

COPY --from=export /project/${KOBWEB_APP_ROOT}/.kobweb .kobweb

ENTRYPOINT .kobweb/server/start.sh
Any idea which could be the issue? Thanks
j
I ran into something similar, see here. It's most likely that something in the docker build is failing, but the final step succeeds so docker thinks everything is OK. I suggest combing through the render build log for "BUILD FAILED" in the middle somewhere, or docker-building it locally with
--progress=plain
and looking for the failure
thank you color 1
e
thanks @jeff! do you know how can i test it locally?
j
try
docker build --progress plain -t <TAG_NAME> .
(tag name is arbitrary, just pick an identifier)
đŸ«¶ 1
e
Hi again @jeff! news about this: i dont have anymore this issue but i have a new one:
Exception in thread "main" java.lang.NullPointerException: getenv(...) must not be null
May 29 111913 AM at com.exxample.kobweb.data.MongoDB.<init>(MongoDB.kt:36)
May 29 111913 AM at com.exxample.kobweb.data.MongoDBKt.initMongoDB(MongoDB.kt:
j
System.getenv() throws an NPE if the key isn't set. Check line 36 for what key it's requesting, and make sure that environment variable is set
e
i have:
Copy code
MongoClient.create(System.getenv("MONGODB_URI"))
the same one
đŸ€” 1
j
Hmm, that looks like it should be ok. The error you pasted is from the render.com logs?
e
yea!
j
Actually I was wrong, getenv is happy to return null if the key isn't set. But your db init is expecting non-null, hence the NPE.
can you share MongoDB.kt?
e
sure:
Copy code
@InitApi
fun initMongoDB(ctx: InitApiContext) {
    System.setProperty(
        "org.litote.mongo.test.mapping.service",
        "org.litote.kmongo.serialization.SerializationClassMappingTypeService"
    )
    ctx.data.add(MongoDB(ctx))
}

class MongoDB(private val context: InitApiContext) : MongoRepository {

    private val client = MongoClient.create(System.getenv("MONGODB_URI"))
    private val database = client.getDatabase(DATABASE_NAME)
    private val userCollection = database.getCollection<User>("user")
    private val postCollection = database.getCollection<Post>("post")

....
....
j
ah -- is the error you pasted from the deploy, or after the site is running?
e
in the deploy one
i can't deploy
j
Ok, so I think what's happening is this: 1. Render sets your env vars when it runs your container, but not when it builds it (this part is the guess) 2.
kobweb export
has a step where it renders all your pages (for SEO reasons) -- see the thread I linked originally 3. In order to do that rendering, it spins up your server 4. But at this stage, your env var isn't set, hence the crash
The options I see are: 1. delay mongo initialization, so that it doesn't trigger as part of the export 2. set the proper env var in your Dockerfile (not ideal because it's a secret) 3. disable the export (I haven't tried this yet but David said it's possible)
Given that this isn't a prod app (I'm assuming, based on your package name), #3 might be easiest. Try this
e
Cool Jeff! i'll take a look on those steps! yes its only a sample app! thanks for all this
i'll let you know
i don't know exactly how to do this two: 1. delay mongo initialization, so that it doesn't trigger as part of the export 2. set the proper env var in your Dockerfile (not ideal because it's a secret)
Hey @jeff! im still fighting with this! about the 1st point you mentioned:
delay mongo initialization, so that it doesn't trigger as part of the export
how can i do this?
p
Hi @Eduardo Ruesta How did you fix the original issue?
Exception in thread “main” com.varabyte.kobweb.common.error.KobwebException: No site folder found. Did you run
kobweb export
?
I tried to run the docker command locally but couldn’t find any issue
e
Hey @Phuc the issue was related to the Mongo class not to the docker
p
Thanks @Eduardo Ruesta I meant this
“Exception in thread “main” com.varabyte.kobweb.common.error.KobwebException: No site folder found. Did you run
kobweb export
?
In my case, it was out of memory because of a config in Dockerfile
I don’t use Mongo
e
mmm let me think since it was a while ago
p
Copy code
RUN mkdir ~/.gradle && \
    echo "org.gradle.jvmargs=-Xmx300m" >> ~/.gradle/gradle.properties
When I removed this, it worked
e
this is my last dockerfile:
Copy code
#-----------------------------------------------------------------------------
# Variables are shared across multiple stages (they need to be explicitly
# opted into each stage by being declaring there too, but their values need
# only be specified once).
ARG KOBWEB_APP_ROOT="site"
# ^ NOTE: Kobweb apps generally live in a root "site" folder in your project,
# but you can change this in case your project has a custom layout.

FROM eclipse-temurin:17 as java

#-----------------------------------------------------------------------------
# Create an intermediate stage which builds and exports our site. In the
# final stage, we'll only extract what we need from this stage, saving a lot
# of space.
FROM java as export

ENV KOBWEB_CLI_VERSION=0.9.15
ARG KOBWEB_APP_ROOT

ENV NODE_MAJOR=20

# Copy the project code to an arbitrary subdir so we can install stuff in the
# Docker container root without worrying about clobbering project files.
COPY . /project

# Update and install required OS packages to continue
# Note: Node install instructions from: <https://github.com/nodesource/distributions#installation-instructions>
# Note: Playwright is a system for running browsers, and here we use it to
# install Chromium.
RUN apt-get update \
    && apt-get install -y ca-certificates curl gnupg unzip wget \
    && mkdir -p /etc/apt/keyrings \
    && curl -fsSL <https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key> | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
    && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] <https://deb.nodesource.com/node_$NODE_MAJOR.x> nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
    && apt-get update \
    && apt-get install -y nodejs \
    && npm init -y \
    && npx playwright install --with-deps chromium

# Fetch the latest version of the Kobweb CLI
RUN wget <https://github.com/varabyte/kobweb-cli/releases/download/v${KOBWEB_CLI_VERSION}/kobweb-${KOBWEB_CLI_VERSION}.zip> \
    && unzip kobweb-${KOBWEB_CLI_VERSION}.zip \
    && rm kobweb-${KOBWEB_CLI_VERSION}.zip

ENV PATH="/kobweb-${KOBWEB_CLI_VERSION}/bin:${PATH}"

WORKDIR /project/${KOBWEB_APP_ROOT}

# Decrease Gradle memory usage to avoid OOM situations in tight environments
# (many free Cloud tiers only give you 512M of RAM). The following amount
# should be more than enough to build and export our site.
RUN mkdir ~/.gradle && \
    echo "org.gradle.jvmargs=-Xmx4096m" >> ~/.gradle/gradle.properties

RUN kobweb export --notty

#-----------------------------------------------------------------------------
# Create the final stage, which contains just enough bits to run the Kobweb
# server.
FROM java as run

ARG KOBWEB_APP_ROOT

COPY --from=export /project/${KOBWEB_APP_ROOT}/.kobweb .kobweb

ENTRYPOINT .kobweb/server/start.sh
p
You increased the .jvmargs
the original was 300m
so similar to what I fixed
Thanks for your confirmation @Eduardo Ruesta
e
yea, maybe that was the issue in that moment! no problem 😁
🙌 1