1. Overview
Deploying a Spring Boot application to Cloud Foundry is a simple exercise. In this tutorial, we’ll show you how to do it.
2. Spring Cloud Dependencies
Since this project will require new dependencies for Spring Cloud project, we’ll add the Spring Cloud Dependencies BOM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2023.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
We can find the latest version of the spring-cloud-dependencies library on Maven Central.
Now, we want to maintain a separate build for the Cloud Foundry, so we’ll create a profile named cloudfoundry in the Maven pom.xml.
We’ll also add compiler exclusions and the Spring Boot plugin to configure the name of the package:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/logback.xml</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>${project.name}-cf</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/cloud/config/*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
We also want to exclude the cloud-specific files from the normal build so we add a global profile exclusion to Maven compiler plugin:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/cloud/*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
Then, we need to add the Spring Cloud Starter and the Spring Cloud Connectors libraries, which provide support for Cloud Foundry:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cloud-connectors</artifactId>
</dependency>
3. Cloud Foundry Configuration
To go through this tutorial, we need to register for a trial here or download the pre-configured development environment for Native Linux or Virtual Box.
Furthermore, the Cloud Foundry CLI needs to be installed. Instructions are here.
After registration with a Cloud Foundry provider, the API URL will be made available (you can come back to it by following the Tools option on the left side).
The application container allows us to bind services to applications. Next, let’s log in to the Cloud Foundry environment:
cf login -a <url>
The Cloud Foundry Marketplace is a catalog of services like databases, messaging, email, monitoring, logging and a lot more. Most services provide a free or trial plan.
Let’s search the Marketplace for “MySQL” and create a service for our application:
cf marketplace | grep MySQL
>
cleardb spark, boost*, amp*, shock* Highly available MySQL for your Apps.
The output lists the services with “MySQL” in the description. On PCF the MySQL service is named cleardb and non-free plans are marked with an asterisk.
Next, we list the details of a service using:
cf marketplace -s cleardb
>
service plan description free or paid
spark Great for getting started and developing your apps free
boost Best for light production or staging your applications paid
amp For apps with moderate data requirements paid
shock Designed for apps where you need real MySQL reliability, power and throughput paid
Now we create a free MySQL service instance named spring-bootstrap-db:
cf create-service cleardb spark spring-bootstrap-db
4. Application Configuration
Next, we add a @Configuration annotated class that extends AbstractCloudConfig to create a DataSource in the package named org.baeldung.cloud.config:
@Configuration
@Profile("cloud")
public class CloudDataSourceConfig extends AbstractCloudConfig {
@Bean
public DataSource dataSource() {
return connectionFactory().dataSource();
}
}
Adding @Profile(“cloud”) ensures that the Cloud Connector isn’t active when we do local testing. We also add @ActiveProfiles(profiles = {“local”}) to the Integration tests.
Then build the application with:
mvn clean install spring-boot:repackage -P cloudfoundry
Also, we need to provide a manifest.yml file, to bind the service to the application.
We usually place the manifest.yml file in the project folder but in this case, we’ll create a cloudfoundry folder since we’re going to demonstrate deploying to multiple cloud-native providers:
---
applications:
- name: spring-boot-bootstrap
memory: 768M
random-route: true
path: ../target/spring-boot-bootstrap-cf.jar
env:
SPRING_PROFILES_ACTIVE: cloud,mysql
services:
- spring-bootstrap-db
5. Deployment
Deploying the application is now as easy as:
cd cloudfoundry
cf push
Cloud Foundry will use the Java buildpack to deploy the application and create a random route to the application.
We can view the last few entries in the log file using:
cf logs spring-boot-bootstrap --recent
Or we can tail the log file:
cf logs spring-boot-bootstrap
Finally, we need the route name to test the application:
cf app spring-boot-bootstrap
>
name: spring-boot-bootstrap
requested state: started
routes: spring-boot-bootstrap-delightful-chimpanzee.cfapps.io
last uploaded: Thu 23 Aug 08:57:20 SAST 2018
stack: cflinuxfs2
buildpacks: java-buildpack=v4.15-offline-...
type: web
instances: 1/1
memory usage: 768M
state since cpu memory disk
#0 running 2018-08-23T06:57:57Z 0.5% 290.9M of 768M 164.7M of 1G
Executing the following command will add a new book:
curl -i --request POST \
--header "Content-Type: application/json" \
--data '{"title": "The Player of Games", "author": "Iain M. Banks"}' \
https://<app-route>/api/books
#OR
http POST https://<app-route>/api/books title="The Player of Games" author="Iain M. Banks"
And this command will list all books:
curl -i https://<app-route>/api/books
#OR
http https://<app-route>/api/books
>
HTTP/1.1 200 OK
[
{
"author": "Iain M. Banks",
"id": 1,
"title": "Player of Games"
},
{
"author": "J.R.R. Tolkien",
"id": 2,
"title": "The Hobbit"
}
]
6. Scaling the Application
Lastly, scaling an application on Cloud Foundry is as simple as using the scale command:
cf scale spring-cloud-bootstrap-cloudfoundry <options>
Options:
-i <instances>
-m <memory-allocated> # Like 512M or 1G
-k <disk-space-allocated> # Like 1G or 2G
-f # Force restart without prompt
Remember to delete the application when we don’t need it anymore:
cf delete spring-cloud-bootstrap-cloudfoundry
7. Conclusion
In this article, we covered the Spring Cloud libraries that simplify the development of a cloud-native application using Spring Boot. Deployment with the Cloud Foundry CLI is well documented here.
Extra plugins for the CLI are available in the plugin repository.
The full source code of our examples here is, as always, over on GitHub.