Introduction
CloudFoundry v2 uses Heroku buildpacks to package droplet on which an application will run. But before, CF checks among the locally available buildpacks which one can be used to prepare the application runtime. The buildpack contract is composed of the following scripts (that can be written in shell, python, ruby, etc):
- Detect: checks if this buildpack is suitable for the submitted application,
- Compile: prepares the runtime environment of the application,
- Release: finally launches the application
Applications with single file
Java applications whether a standalone or web are managed by the java-buildpack. In case a manifest.yml is used to submit the application, then for Web applications or executable jar it may looks like:---
applications:
- name: APP_NAME
memory: 4G
disk_quota: 2G
timeout: 180
instances: 1
host: APP_NAME-${random-word}
path: /path/to/war/file.war or /path/to/executable/file.jar
The java-buildpack will check if the file is a .war to launch Tomcat container, or an executable jar to look for the mainClass in META-INF/MANIFEST.MF.
Applications with many files
In case the application is composed of multiple files (jars, assets, configs, etc.) the java-buildpack won't be able to automatically detect what appropriate container to use. We need:
1. For the Detect phase to choose which container is appropriate (here the java-main): Clone the java-buildpack and set the java_main_class property in config/java_main.yml.
2. In the manifest: indicate the path to the folder containing all artifacts that should be download to the droplet at the Compile phase.
3. In the manifest: set the command that will be used at the Release phase to launch the application.
An example of java_main.yml file:
---java_main_class: package.name.ClassName
An example of a manifest.yml file:
---applications:
- name: APP_NAME
memory: 2G
timeout: 180
instances: 1
host: APP_NAME-${random-word}
path: ./
buildpack: http://url/to/custom/java-buildpack
command: $PWD/.java-buildpack/open_jdk_jre/bin/java -cp $PWD/*:. -Djava.io.tmpdir=$TMPDIR package.name.ClassName
Application submission
$ cf push to submit an application$ cf logs APP_NAME to access the application logs
$ cf events APP_NAME to access CF events related to this application
$ cf files APP_NAME to access the VCAP user home where the application files are stored
Troubleshooting
If the application fails to start for some reason (you may see no logs), you can check what command was used to launch the application as follows:$ CF_TRACE=true cf app app_name | grep "detected_start_command"
Note
- Uploaded jar files are extracted under /home/vcap/app/APP_NAME in the droplet.
- for executable jar, we need to accept traffic on the port given by CF which is in the VCAP_APP_PORT environment variable. Otherwise CF will think that the application has failed to start and thus shut it down.
- to check if a java program is running on CloudFoundry:
import org.cloudfoundry.runtime.env.CloudEnvironment; ... CloudEnvironment cloudEnvironment = new CloudEnvironment(); if (cloudEnvironment.isCloudFoundry()) { // activate cloud profile System.out.println("On A cloudfoundry environment"); }else { System.out.println("Not on A cloudfoundry environment"); }
Resources:
- Standalone (non-web) applications on Cloud Foundry - link