I would like to run a spring application on cloudfoundry as a one-off task using the java buildpack.
Please note that my app is not a web application but a spring batch application that also uses spring cloud task.
Here is my manifest:
---
buildpack: https://github.com/cloudfoundry/java-buildpack.git
memory: 1024M
env:
APPLICATION_URL: http://bignibou-server.cfapps.io/
APPLICATION_MAIL_NO_REPLY_ADDRESS: balteo@bignibou-server.cfapps.io
SPRING_PROFILES_ACTIVE: cloud
applications:
- name: bignibou-server
path: bignibou-server/build/libs/bignibou-server.jar
env:
APPLICATION_GOOGLE_API_KEY: ******************
- name: bignibou-batch
path: bignibou-batch/build/libs/bignibou-batch.jar
no-hostname: true
no-route: true
command: null
health-check-type: none
env:
JAVA_OPTS: -Dspring.batch.job.names=messagesDigestMailingJob
Whenever I push the app, it is detected as a worker app:
App bignibou-batch is a worker, skipping route creation
which is what I want.
But then it tries to start the batch as a web application (still whilst deploying the app)... See:
2017-03-24T22:33:50.828+01:00 [CELL/0] [OUT] Destroying container
2017-03-24T22:33:50.854+01:00 [API/3] [OUT] Process has crashed with type: "web"
2017-03-24T22:33:50.873+01:00 [API/3] [OUT] App instance exited with guid befc8bf2-d338-45e1-90b9-430ff3b09a3f payload: {"instance"=>"", "index"=>0, "reason"=>"CRASHED", "exit_description"=>"2 error(s) occurred:\n\n* Codependent step exited\n* cancelled", "crash_count"=>1, "crash_timestamp"=>1490391230813627797, "version"=>"8f92e459-a6c7-4558-bc0b-09ac398eb069"}
2017-03-24T22:33:51.473+01:00 [CELL/0] [OUT] Successfully destroyed container
2017-03-24T22:33:51.634+01:00 [CELL/0] [OUT] Creating container
2017-03-24T22:33:52.478+01:00 [CELL/0] [OUT] Successfully created container
2017-03-24T22:33:56.824+01:00 [APP/PROC/WEB/0] [OUT] JVM Memory Configuration: -XX:MaxMetaspaceSize=164239K -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=25984K -Xmx295151K -XX:MaxDirectMemorySize=10M
2017-03-24T22:33:56.827+01:00 [APP/PROC/WEB/0] [ERR] JVM Memory Configuration: -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=25984K -Xmx295151K -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=164239K
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] . ____ _ __ _ _
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] \\/ ___)| |_)| | | | | || (_| | ) ) ) )
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] ' |____| .__|_| |_|_| |_\__, | / / / /
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] =========|_|==============|___/=/_/_/_/
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
2017-03-24T22:33:59.075+01:00 [APP/PROC/WEB/0] [OUT] :: Spring Boot :: (v1.5.2.RELEASE)
2017-03-24T22:33:59.266+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.256 INFO 16 --- [ main] pertySourceApplicationContextInitializer : Adding 'cloud' PropertySource to ApplicationContext
2017-03-24T22:33:59.381+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.359 WARN 16 --- [ main] o.c.r.o.s.cloud.AbstractCloudConnector : No suitable service info creator found for service elasticsearch Did you forget to add a ServiceInfoCreator?
2017-03-24T22:33:59.389+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.388 INFO 16 --- [ main] nfigurationApplicationContextInitializer : Adding cloud service auto-reconfiguration to ApplicationContext
2017-03-24T22:33:59.465+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.451 INFO 16 --- [ main] com.bignibou.batch.Batch : Starting Batch on a1e87528-637d-4dae-62ab-0538e48fb49b with PID 16 (/home/vcap/app/BOOT-INF/classes started by vcap in /home/vcap/app)
which is not what I want...
So my questions are:
- How can I configure my manifest in order for the batch app to be pushed properly without starting automatically - I just want the binaries pushed to cf so that I can run tasks later on...
- How can I start my spring batch as a cf task on cloudfoundry?
In order to run a task, you need an app to be deployed and to be completely staged (so there's a droplet). You can then
cf run-task <app> <task-cmd>
.A couple ideas:
First option, you could use a manifest.yml like this:
This will setup an app with a very small memory limit and a command that essentially does nothing forever (the forever part is key so that the app will completely stage and start). We also set the health check to none and no route, so that no route is bound and no TCP health check is done. You can optionally set your build pack.
Then run
cf push
. The app should stage and start OK. After that you cancf run-task
as many times as you want. You can optionally stop the app.Second option, just push your app without making any special manifest.yml configurations. The app should stage properly, fail to start running then after it's failed you can
cf stop
the app. From there, you should be able tocf run-task
as many times as you want.You might also be able to use the v3 API directly, which would give you some additional flexibility, but all the interaction is manual via
cf curl
at this point.If you want to see a concrete example of how to use
cf run-task
, see Selwyn's answer.push your app like so to pcf
use the special task launcher to start your app as a task. You can also append arguments after the ".JarLauncher arg1" that will show up as string[] args to your main method or CommandLineRunner
Runs the task using the Task runner. This support for tasks is built into the platform.
Note link below also shows you have to schedule it
Source: https://github.com/joshlong/cf-task-demo