Reputation: 880
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:
Also, when I run the ps command to check the running processes, there's nothing that would consume all my memory.
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?!
Upvotes: 2
Views: 1775
Reputation: 880
I found a solution; which is rather unexpected and counterintuitive. Here's what I did:
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}]'
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.
Upvotes: 2
Reputation: 2488
For Lite accounts, memory is limited to 256 MB across all apps deployed for an account:
https://cloud.ibm.com/docs/account?topic=account-noruntimemem
You will either need to stop any Cloud Foundry applications that are not in use or upgrade your account.
In Cloud Foundry, your manifest.yml in the application code will specify the memory.
Note: If you are using a Toolchain, the deployment will create a new application and switch routes on every redeployment in the pipeline, so temporarily you will have two applications running to avoid downtime. This is another scenario where you could potentially run into this memory problem (i.e. your application specifies 256MB of memory but temporarily there is 512MB of usage while both applications are running). To fix this, either manually stop the CF application that's running before running the pipeline (will incur downtime while stopped) or upgrade your account.
Upvotes: 1