Search code examples
javaspringspring-bootdockeribm-cloud

Server error, status code: 400, error code: 100005, message: You have exceeded your organization's memory limit


I'm trying to deploy a simple Spring + Spring Boot App to IBM Cloud using Cloud Foundry. My Docker file looks as follows:

# IBM Java SDK UBI is not available on public docker yet. Use regular
# base as builder until this is ready. For reference:
# https://github.com/ibmruntimes/ci.docker/tree/master/ibmjava/8/sdk/ubi-min

FROM ibmjava:8-sdk AS builder
LABEL maintainer="IBM Java Engineering at IBM Cloud"

WORKDIR /app
RUN apt-get update && apt-get install -y maven

COPY pom.xml .
RUN mvn -N io.takari:maven:wrapper -Dmaven=3.5.0

COPY . /app
RUN ./mvnw install

ARG bx_dev_user=root
ARG bx_dev_userid=1000
RUN BX_DEV_USER=$bx_dev_user
RUN BX_DEV_USERID=$bx_dev_userid
RUN if [ $bx_dev_user != "root" ]; then useradd -ms /bin/bash -u $bx_dev_userid $bx_dev_user; fi

# Multi-stage build. New build stage that uses the UBI as the base image.

# In the short term, we are using the OpenJDK for UBI. Long term, we will use
# the IBM Java Small Footprint JVM (SFJ) for UBI, but that is not in public
# Docker at the moment.
# (https://github.com/ibmruntimes/ci.docker/tree/master/ibmjava/8/sfj/ubi-min)

FROM adoptopenjdk/openjdk8:ubi-jre

# Copy over app from builder image into the runtime image.
RUN mkdir /opt/app
COPY --from=builder /app/target/javaspringapp-1.0-SNAPSHOT.jar /opt/app/app.jar

ENTRYPOINT [ "sh", "-c", "java -jar -XX:MaxRAM=10m /opt/app/app.jar" ]

As you can see, I've limited my app to use a max of 10MB and my instance has 256MB available. However, everytime I deploy the app, I get the following error: Log 1

Also, when I run the ps command to check the running processes, there's nothing that would consume all my memory.

Log 2

I've ran the same app locally and it only requires 25MB max, so the 256MB of my instance should be enough. Any ideas on how to solve this problem?

NOTE: Unfortunately I am not allowed to increase the capacity of the instance at this moment of time.


[UPDATE] So I decided to start from a scratch and create a new Java Spring App in IBM Cloud. IBM automatically sets it to start with this template, which is cloned to your repo. The app was deployed normally and I could access it.

Now, I removed one line of code in the HTML and tried to deploy again. To my surprise, I got:

FAILED
Error restarting application: Server error, status code: 400, error code: 100005, message: You have exceeded your organization's memory limit: app requested more memory than available

How is this even possible?!


Solution

  • I found a solution; which is rather unexpected and counterintuitive. Here's what I did:

    1. I reduced the memory of the instance of the application to 64MB.

    enter image description here

    1. In the manifest.yml, I set the memory of the application to 192M. My manifest looks as follows:

    applications:
    - instances: 1
      timeout: 180
      name: appname
      buildpack: java_buildpack
      path: ./target/appname-1.0-SNAPSHOT.jar
      disk_quota: 1G
      memory: 192M
      domain: eu-gb.mybluemix.net
      host: appHost
      env:
        JAVA_OPTS: '-XX:ReservedCodeCacheSize=32M -XX:MaxDirectMemorySize=32M'
        JBP_CONFIG_OPEN_JDK_JRE: '[memory_calculator: {stack_threads: 2}]'
    
    1. I pushed the changes in the manifest.yml to the repo, starting a new deployment. This time the application is deployed successfully and runs smoothly.

    NOTE: After deploying, the memory of the instance is overwritten and 192MB are assigned. In order to perform any further changes in the code, I need to set the memory back to 64MB before pushing the changes and deploying the app.