CloudCaptain supports Spring Boot 1.x and 2.x apps packaged as either a Spring Boot Executable Jar or a Spring Boot Executable War using OpenJDK 7, 8, 11, 17 or 21.
If you haven't already, start by following Spring Boot & CloudCaptain tutorial that will get you up and running in 5-10 minutes.
Also check out our blog post on how to create a Spring Boot application and deploy it on EC2 using CloudCaptain.
For databases, check out our blog post on how to build a Spring Boot microservice that uses a CloudCaptain-managed PostgreSQL database.
Additionally here are also a number of articles on how to use CloudCaptain with Spring Boot.
By default CloudCaptain uses the latest OpenJDK 17 version (headless JRE).
If you want to switch to OpenJDK 7.x or simply an
older version, you can do so using the -components.openjdk
configuration setting:
> boxfuse run my-app-1.0.jar -components.openjdk=7.80.32
To find out which OpenJDK versions are available from the CloudCaptain Inventory you can simply issue:
> boxfuse inventory openjdk
If you prefer to use a different JRE, including the Oracle JRE, rather than the default OpenJDK one,
you can do so by including the Linux x64 JRE distribution of your choice in a /jre
folder inside the Spring Boot jar file.
If you use Maven or Gradle, this means the /jre
folder should be put into the
src/main/resources
directory:
my-spring-boot-app
src
main
java
resources
jre
bin
java
...
lib
amd64
...
rt.jar
...
COPYRIGHT
LICENSE
...
Tip for Git users
To avoid file corruption due to Git line-ending normalization, add the following line to
.gitattributes
src/main/resources/jre/* binary
By default CloudCaptain looks for an application-boxfuse.properties
file inside the Spring Boot jar
file
and runs your app with the Spring profile boxfuse
activated by default.
If you use Maven or Gradle, this means the application-boxfuse.properties
file should be put into the
src/main/resources
directory.
When the Spring Boot Maven or Gradle plugin packages the executable jar, it will include it in the root of your
class path, where CloudCaptain can see it.
my-spring-boot-app
src
main
java
resources
application-boxfuse.properties
CloudCaptain parses application-boxfuse.properties
and automatically configures the
ports and the healthcheck based on the
information it contains.
If no application-boxfuse.properties
is found in the jar file, CloudCaptain will automatically
look for the following configuration files both at the root of the classpath and in the config
package:
application-boxfuse.yml
application-default.properties
application-default.yml
application.properties
application.yml
The overriding order matches the default Spring Boot one.
Note: Other config files (including the ones for other specific Spring profiles) are not taken into account for auto-configuration and you will have to specify the appropriate port and healthcheck configuration settings yourself.
CloudCaptain will automatically configure your application ports to be either http
or https
based on the value of server.ssl.enabled
. The actual port numbers are
automatically
configured according to the values of the server.port
and management.port
properties.
CloudCaptain will automatically configure the healthcheck port and path based on the discovered Spring Boot configuration. If your application also includes the Spring Boot Actuator, CloudCaptain will automatically configures its healthcheck to match the Spring Boot health endpoint.
By default CloudCaptain activates a Spring Profile called boxfuse
. You can however easily specify a different
profile by setting the SPRING_PROFILES_ACTIVE
environment variable or the spring.profiles.active
JVM system property to the value you need using the
envvars and jvm.args arguments.
To use a different Spring Profile for each CloudCaptain environment,
set the Spring Boot profile to the value of the BOXFUSE_ENV
environment variable which contains the
name of the
current environment (dev, test, prod): -jvm.args=-Dspring.profiles.active=$BOXFUSE_ENV
Tip for Mac OSX and Linux users
The BOXFUSE_ENV
environment variable is only available within the CloudCaptain instance, so
you must prevent variable expansion by using single quotes:
'-jvm.args=-Dspring.profiles.active=$BOXFUSE_ENV'
Note that selecting a Spring Profile via an environment variables or any other means does not affect how CloudCaptain configures ports and healthchecks. CloudCaptain will only read the files described in that section to extract that information, regardless of which Spring profile gets selected at runtime. You can override those auto-configured values by explicitly setting the port numbers and healthcheck paths using CloudCaptain parameters when fusing images or launching instances. At runtime those parameters will then override any other Spring Boot configuration.
If your app includes the PostgreSQL or MySQL JDBC driver, CloudCaptain will automatically provision the necessary PostgreSQL or MySQL database in each environment and auto-configure Spring Boot's DataSource.
CloudCaptain auto-configures Spring Boot's DataSource by setting the SPRING_DATASOURCE_URL
,
SPRING_DATASOURCE_USERNAME
and SPRING_DATASOURCE_PASSWORD
environment variables
to the correct JDBC url, user and password for the current environment.
Tip
If your application experiences long periods of inactivity your database connections may time out and throw errors upon checkout.
Add the following configuration to your application.properties
to fix this:
spring.datasource.testOnBorrow=true spring.datasource.validationQuery=SELECT 1
To disable database auto-provisioning and use an existing database set db.type
to none
when creating your app.
To expose your app via HTTPS make sure you have a custom domain configured
for the environment where you want to run it. Also make sure that you have obtained
a valid TLS (SSL) certificate and that your app has been created
with app.type
set to load-balanced
and tls.type
set to acm
(AWS Certificate Manager).
With that in place your Spring Boot app will be automatically configured to run with HTTPS and a green lock will appear in the browser.
You can also manually force the correct configuration by adding these properties to your Spring Boot config file:
server.port=443 server.ssl.enabled=true server.ssl.key-store=/app-config/boxfuse-selfsigned.jks server.ssl.key-store-password=boxfuse-selfsigned
This will ensure that all network traffic between the ELB and your instances will be encrypted as well.
To use HTTPS with your own certificate, you first have to obtain a valid certificate from a Certificate Authority and add a KeyStore containing your TLS (SSL) certificate to the root of the classpath to ensure it is packaged inside the Spring Boot jar file.
If you use Maven or Gradle, this means your .jks
or .keystore
KeyStore file should be put
into the src/main/resources
directory.
When Maven or Gradle packages the jar, it will include it in the root of your Spring Boot jar file, where CloudCaptain
can see it.
my-spring-boot-app
src
main
java
resources
example.jks
You can then configure the Spring Boot connector to use it. So if for example
you have a KeyStore named example.jks
inside your Spring Boot jar file,
application-boxfuse.properties
should look like this:
server.port=443 server.ssl.enabled=true server.ssl.key-store=classpath:example.jks server.ssl.key-store-password=myS3cr3tPwd
By default, CloudCaptain uses the same root certificate bundle as the latest version of Firefox. Additionally CloudCaptain also includes the root certificates for Amazon RDS, so you can connect securely to RDS databases out of the box.
You can, however, ship your own set of root certificates, by placing them in a KeyStore inside the Jar file as /cacerts
.
If you use Maven or Gradle, this means your cacerts
KeyStore file should be put into the src/main/resources
directory.
CloudCaptain will then automatically configure the JRE to use these instead.
my-spring-boot-app
src
main
java
resources
cacerts
If you choose to secure your cacerts
TrustStore with a password different than the default changeit
,
you have to add the following to your Spring Boot configuration:
server.ssl.trust-store=/cacerts/cacerts server.ssl.trust-store-password=my0th3rPwd
This is already enabled by default (starting with OpenJDK 8.162.12) and no further action is required.
To enable JCE unlimited cryptography (for AES-256, RSA-4096, ...), download the policy zip from the Oracle website for either Java 7 or Java 8.
Extract both local_policy.jar
and US_export_policy.jar
and place them at the root of your
Jar file.
If you use Maven or Gradle, this means both policy jar files should be put into the src/main/resources
directory.
CloudCaptain will then automatically configure the JRE to use these instead.
my-spring-boot-app
src
main
java
resources
local_policy.jar
US_export_policy.jar
If you use a custom JRE it is your responsibility to ensure it is configured for unlimited strength cryptography if you need it.
If you wish to launch the JRE with one or more Java Agents, simply place the Java Agent files inside the Jar file
under
/javaagents/
. In a Maven or Gradle project this means you have to put your agent jar and whatever other
files it requires under src/main/resources/javaagents
:
my-spring-boot-app
src
main
java
resources
javaagents
myjavaagent.jar
myjavaagent.properties
CloudCaptain will then automatically configure the JRE to use these Java Agents
By default CloudCaptain will dynamically configure your JVM heap to use 85% of the available memory in
the instance. All other settings
use the JVM defaults. You can override this by specifying the required JVM arguments like -Xmx
via the
jvm.args
configuration setting.
CloudCaptain configures the JVM to use /tmp
as the directory to store temporary files and provisions 1
GB of space by default.
To increase this (up to a maximum of 16 TB), simply set
the tmp
configuration setting to the number of GB of temp space you need. To prevent CloudCaptain from
provisioning any temp space set tmp
to 0
.
CloudCaptain also automatically configures the Spring Boot Actuator disk space health check to monitor /tmp
.
When you disable
the temp space (by setting tmp
to 0
), CloudCaptain will also automatically disable the Actuator
disk space health check.
Remote debugging (including hot-code replace) with your favorite IDE is fully supported. Details and setup instructions on our debugging page.
Profiling with tools like JVisualVM and Java Flight Recorder is fully supported. Details and setup instructions on our profiling page.
CloudCaptain supports Live Reloading of exploded Spring Boot jar and war files. However in most cases you're probably better off using Spring Boot's own solution, the Spring Boot Dev Tools, as they work great on both VirtualBox and AWS.
Check out our blog post for details.
CloudCaptain supports the Spring Boot Dev Tools, including running as a remote application both on VirtualBox and on AWS.
Simply include the spring-boot-devtools
dependency either in your Maven pom.xml
:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>
Or in your build.gradle
:
compile("org.springframework.boot:spring-boot-devtools")
And ensure the Spring Boot Dev Tools are enabled in the final jar by setting the excludeDevtools
flag of the Spring Boot Maven plugin to false
:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludeDevtools>false</excludeDevtools> </configuration> </plugin>
Or in your build.gradle
:
bootRepackage { excludeDevtools = false }
Then define an application secret in application.properties
:
spring.devtools.remote.secret=mysecret
Now package, fuse and run your application:
> mvn package > boxfuse run ... Payload started in 00:07.682s -> https://127.0.0.1:8080
All that is left is to go to your IDE project for your app and run
org.springframework.boot.devtools.RemoteSpringApplication
with the same classpath as your project
and one argument with the address where your app is running, for example https://127.0.0.1:8080
.
The RemoteSpringApplication now starts:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \ \\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) ) ' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / / =========|_|==============|___/===================================/_/_/_/ :: Spring Boot Remote :: (v1.3.6.RELEASE) 2016-07-07 17:04:40.996 INFO 5280 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication v1.3.6.RELEASE on axel-silencio with PID 5280 (C:\Users\myuser\.m2\repository\org\springframework\boot\spring-boot-devtools\1.3.6.RELEASE\spring-boot-devtools-1.3.6.RELEASE.jar started by myuser in C:\Workspaces\getstarted-springboot) 2016-07-07 17:04:40.998 INFO 5280 --- [ main] o.s.b.devtools.RemoteSpringApplication : No active profile set, falling back to default profiles: default 2016-07-07 17:04:41.021 INFO 5280 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@365c30cc: startup date [Thu Jul 07 17:04:41 CEST 2016]; root of context hierarchy 2016-07-07 17:04:41.378 WARN 5280 --- [ main] o.s.b.d.r.c.RemoteClientConfiguration : The connection to https://localhost:8080 is insecure. You should use a URL starting with 'https://'. 2016-07-07 17:04:41.432 INFO 5280 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2016-07-07 17:04:41.456 INFO 5280 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 0.684 seconds (JVM running for 0.981)
Any change you now make in your IDE (don't forget to save and build) will be reflected within your running CloudCaptain instance, regardless of whether it is on VirtualBox or AWS.
More details and info in our blog post.
By default all CloudCaptain instance use the UTC
time zone.
We don't recommend changing this as this greatly simplifies time zone issues in machine to machine communication and cleanly relegates all time zones related aspects to a pure presentation layer concern.
If however you still do want to change this, you can override the default time zone of the instance using the
TZ
environment variable. For example to change the time zone of your instance to America/Los_Angeles
you would do so like this:
> boxfuse fuse -envvars.TZ=America/Los_Angeles
Some JVM applications also depend on native Linux x64 binaries and libs to do their work. CloudCaptain makes it easy to integrate them into your image.
Simply place your binaries under /native/bin
on the classpath and CloudCaptain
will automatically add them to the PATH
at runtime in your instances.
If those binaries also depend on additional shared libraries beyond the C library, place the .so files of your libraries
under /native/lib
on the classpath and CloudCaptain
will automatically add them to the LD_LIBRARY_PATH
at runtime in your instances.
Tip
To list all the shared libraries your Linux x64 binary requires, you can use the following command on a Linux system:
$ ldd -v my-native-binary
If you use Maven or Gradle, the native
directory should be put into the src/main/resources
directory. CloudCaptain will then automatically configure the PATH
and LD_LIBRARY_PATH
to use it.
my-spring-boot-app
src
main
java
resources
native
bin
my-native-binary
other-linux-x64-binary
lib
my-shared-lib.so
other-shared-lib.so
You can then simply invoke them in your code using
Runtime.getRuntime().exec("my-native-binary arg1 arg2 arg3");
To monitor your app using New Relic simply pass in your New Relic license key when fusing your image and CloudCaptain will automatically install and configure the New Relic Servers Linux x64 and New Relic Java agents for you.
> boxfuse fuse -newrelic.licensekey=0123456789abcdef0123456789abcdef01234567
Alternatively you can also supply a newrelic.yml
configuration file for the Java agent and CloudCaptain will
automatically use that instead. CloudCaptain will then install the agent for you, but won't override any application name
you may have configured.
If you haven't configured a New Relic license key as described above, CloudCaptain will use
the license key contained in your newrelic.yml
configuration file instead.
If you use Maven or Gradle, the newrelic.yml
file should be put into the src/main/resources
directory.
CloudCaptain will then automatically configure the New Relic Java agent to use it.
my-spring-boot-app
src
main
java
resources
newrelic.yml
To tune the arguments passed Linux kernel from the bootloader, simply pass them using the
-linux.args
setting when fusing your image.
If you need to tune the Linux kernel running in your instance, simply place a sysctl.conf
file at the
root inside your jar file.
In a Maven or Gradle project this means you have to put it under src/main/resources
:
my-spring-boot-app
src
main
java
resources
sysctl.conf
You can then for example tune the maximum number of file descriptors by simply including the following in sysctl.conf
:
fs.file-max = 131072
CloudCaptain will then automatically configure the Linux kernel to use these settings.