Spring Boot’s flexible packaging options provide a great deal of choice when it comes to deploying your application. You can deploy Spring Boot applications to a variety of cloud platforms, to container images (such as Docker), or to virtual/real machines.
This section covers some of the more common deployment scenarios.
1.1. Deploying to Containers
If you are running your application from a container, you can use an executable jar, but it is also often an advantage to explode it and run it in a different way. Certain PaaS implementations may also choose to unpack archives before they run. For example, Cloud Foundry operates this way. The simplest way to run an unpacked archive is by starting the appropriate launcher, as follows:
$ jar -xf myapp.jar $ java org.springframework.boot.loader.JarLauncher
This is actually slightly faster on startup (depending on the size of the jar) than running from an unexploded archive. At runtime you shouldn’t expect any differences.
Once you have unpacked the jar file, you can also get an extra boost to startup time by running the app with its "natural" main method instead of the
JarLauncher
. For example:$ jar -xf myapp.jar $ java -cp BOOT-INF/classes:BOOT-INF/lib/* com.example.MyApplication
Using the JarLauncher over the application’s main method has the added benefit of a predictable classpath order. The jar contains a classpath.idx file which is used by the JarLauncher when constructing the classpath. |
More efficient container images can also be created by creating separate layers for your dependencies and application classes and resources (which normally change more frequently).
1.2. Deploying to the Cloud
Spring Boot’s executable jars are ready-made for most popular cloud PaaS (Platform-as-a-Service) providers. These providers tend to require that you “bring your own container”. They manage application processes (not Java applications specifically), so they need an intermediary layer that adapts your application to the cloud’s notion of a running process.
Two popular cloud providers, Heroku and Cloud Foundry, employ a “buildpack” approach. The buildpack wraps your deployed code in whatever is needed to start your application. It might be a JDK and a call to
java
, an embedded web server, or a full-fledged application server. A buildpack is pluggable, but ideally you should be able to get by with as few customizations to it as possible. This reduces the footprint of functionality that is not under your control. It minimizes divergence between development and production environments.
Ideally, your application, like a Spring Boot executable jar, has everything that it needs to run packaged within it.
In this section, we look at what it takes to get the simple application that we developed in the “Getting Started” section up and running in the Cloud.
1.2.1. Amazon Web Services (AWS)
Amazon Web Services offers multiple ways to install Spring Boot-based applications, either as traditional web applications (war) or as executable jar files with an embedded web server. The options include:
- AWS Elastic Beanstalk
- AWS Code Deploy
- AWS OPS Works
- AWS Cloud Formation
- AWS Container Registry
Each has different features and pricing models. In this document, we describe only the simplest option: AWS Elastic Beanstalk.
AWS Elastic Beanstalk
As described in the official Elastic Beanstalk Java guide, there are two main options to deploy a Java application. You can either use the “Tomcat Platform” or the “Java SE platform”.
Using the Tomcat Platform
This option applies to Spring Boot projects that produce a war file. No special configuration is required. You need only follow the official guide.
Using the Java SE Platform
This option applies to Spring Boot projects that produce a jar file and run an embedded web container. Elastic Beanstalk environments run an nginx instance on port 80 to proxy the actual application, running on port 5000. To configure it, add the following line to your
application.properties
file:server.port=5000
Upload binaries instead of sources
By default, Elastic Beanstalk uploads sources and compiles them in AWS. However, it is best to upload the binaries instead. To do so, add lines similar to the following to your
.elasticbeanstalk/config.yml file:
|
Reduce costs by setting the environment type
By default an Elastic Beanstalk environment is load balanced. The load balancer has a significant cost. To avoid that cost, set the environment type to “Single instance”, as described in the Amazon documentation. You can also create single instance environments by using the CLI and the following command:
eb create -s |
Summary
This is one of the easiest ways to get to AWS, but there are more things to cover, such as how to integrate Elastic Beanstalk into any CI / CD tool, use the Elastic Beanstalk Maven plugin instead of the CLI, and others. There is a blog post covering these topics more in detail.
1.2.2. Boxfuse and Amazon Web Services
Boxfuse works by turning your Spring Boot executable jar or war into a minimal VM image that can be deployed unchanged either on VirtualBox or on AWS. Boxfuse comes with deep integration for Spring Boot and uses the information from your Spring Boot configuration file to automatically configure ports and health check URLs. Boxfuse leverages this information both for the images it produces as well as for all the resources it provisions (instances, security groups, elastic load balancers, and so on).
Once you have created a Boxfuse account, connected it to your AWS account, installed the latest version of the Boxfuse Client, and ensured that the application has been built by Maven or Gradle (by using, for example,
mvn clean package
), you can deploy your Spring Boot application to AWS with a command similar to the following:$ boxfuse run myapp-1.0.jar -env=prod
See the
boxfuse run
documentation for more options. If there is a boxfuse.conf
file present in the current directory, it is considered.By default, Boxfuse activates a Spring profile named boxfuse on startup. If your executable jar or war contains an application-boxfuse.properties file, Boxfuse bases its configuration on the properties it contains. |
At this point,
boxfuse
creates an image for your application, uploads it, and configures and starts the necessary resources on AWS, resulting in output similar to the following example:Fusing Image for myapp-1.0.jar ... Image fused in 00:06.838s (53937 K) -> axelfontaine/myapp:1.0 Creating axelfontaine/myapp ... Pushing axelfontaine/myapp:1.0 ... Verifying axelfontaine/myapp:1.0 ... Creating Elastic IP ... Mapping myapp-axelfontaine.boxfuse.io to 52.28.233.167 ... Waiting for AWS to create an AMI for axelfontaine/myapp:1.0 in eu-central-1 (this may take up to 50 seconds) ... AMI created in 00:23.557s -> ami-d23f38cf Creating security group boxfuse-sg_axelfontaine/myapp:1.0 ... Launching t2.micro instance of axelfontaine/myapp:1.0 (ami-d23f38cf) in eu-central-1 ... Instance launched in 00:30.306s -> i-92ef9f53 Waiting for AWS to boot Instance i-92ef9f53 and Payload to start at https://52.28.235.61/ ... Payload started in 00:29.266s -> https://52.28.235.61/ Remapping Elastic IP 52.28.233.167 to i-92ef9f53 ... Waiting 15s for AWS to complete Elastic IP Zero Downtime transition ... Deployment completed successfully. axelfontaine/myapp:1.0 is up and running at https://myapp-axelfontaine.boxfuse.io/
Your application should now be up and running on AWS.
See the blog post on deploying Spring Boot apps on EC2 as well as the documentation for the Boxfuse Spring Boot integration to get started with a Maven build to run the app.
1.2.3. Google Cloud
Google Cloud has several options that can be used to launch Spring Boot applications. The easiest to get started with is probably App Engine, but you could also find ways to run Spring Boot in a container with Container Engine or on a virtual machine with Compute Engine.
To run in App Engine, you can create a project in the UI first, which sets up a unique identifier for you and also sets up HTTP routes. Add a Java app to the project and leave it empty and then use the Google Cloud SDK to push your Spring Boot app into that slot from the command line or CI build.
App Engine Standard requires you to use WAR packaging. Follow these steps to deploy App Engine Standard application to Google Cloud.
Alternatively, App Engine Flex requires you to create an
app.yaml
file to describe the resources your app requires. Normally, you put this file in src/main/appengine
, and it should resemble the following file:service: default
runtime: java
env: flex
runtime_config:
jdk: openjdk8
handlers:
- url: /.*
script: this field is required, but ignored
manual_scaling:
instances: 1
health_check:
enable_health_check: False
env_variables:
ENCRYPT_KEY: your_encryption_key_here
You can deploy the app (for example, with a Maven plugin) by adding the project ID to the build configuration, as shown in the following example:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.0</version>
<configuration>
<project>myproject</project>
</configuration>
</plugin>
Then deploy with
mvn appengine:deploy
(if you need to authenticate first, the build fails).
0 comments :
Post a Comment